AWS WAF image grid
Summary
| Property | Value |
|---|---|
| v1 type | image.grid.aws beta |
| Compatibility names | none: native API (v1) only |
| Proxy | not used |
| Deadline | 60 seconds (starting value). A task not solved by then fails with timeout and is not charged. |
Parameters
The params object of POST /v1/tasks. Unknown fields are rejected with 422 invalid_params.
| Field | Type | Description |
|---|---|---|
imagerequired | string | Base64 of the whole 3x3 grid image. min length 1 · max length 1,000,000 |
questionoptional | string | The full question as shown on the page, e.g. Select all hats. min length 1 · max length 1,024 |
Solution
The solution object of a solved task.
| Field | Type | Description |
|---|---|---|
objectsrequired | array of integer | Zero-based indexes of the images or tiles to select, left to right, top to bottom. max items 64 · unique items |
confidencesoptional | array of number | max items 64 |
Example: native API (v1)
Runs as is with a test key (nop_test_…) in the sandbox; use a live key for real tasks.
{ "type": "image.grid.aws", "params": { "image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "question": "Select all hats" }}export NOPTCHA_KEY=nop_test_... # your test or live key
# waits up to 60 s; 200 = finished (solved or failed), 202 = still processingIDEMPOTENCY_KEY=$(uuidgen) # one key per task you want; a retry of the same request reuses itcurl -s -X POST "https://api.noptcha.com/v1/tasks" \ -H "Authorization: Bearer $NOPTCHA_KEY" \ -H 'Prefer: wait=60' \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" \ -H 'Content-Type: application/json' \ -d @- <<EOF{ "type": "image.grid.aws", "params": { "image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "question": "Select all hats" }}EOF
# on 202: long-poll with the "id" from the responseTASK_ID=...curl -s "https://api.noptcha.com/v1/tasks/$TASK_ID?wait=60" \ -H "Authorization: Bearer $NOPTCHA_KEY"import osimport timeimport uuid
import requests
API = "https://api.noptcha.com"HEADERS = {"Authorization": f"Bearer {os.environ['NOPTCHA_KEY']}"} # a nop_test_ key runs in the sandbox
# One Idempotency-Key per task you want. If you retry this request after a network error, send the same key and# the same body bytes: you get the same task back, not a second one (see Idempotency on the Tasks page).idempotency_key = str(uuid.uuid4())r = requests.post( f"{API}/v1/tasks", headers={**HEADERS, "Prefer": "wait=60", "Idempotency-Key": idempotency_key}, json={ "type": "image.grid.aws", "params": { "image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "question": "Select all hats", }, }, timeout=100,)task = r.json()if r.status_code >= 400: raise RuntimeError(f"{task['code']}: {task.get('detail', '')}")while task["status"] == "processing": # 202: not finished within the wait time.sleep(1) # a long poll can return early (for example when wait slots are full) r = requests.get(f"{API}/v1/tasks/{task['id']}", params={"wait": 60}, headers=HEADERS, timeout=100) task = r.json() if r.status_code >= 400: raise RuntimeError(f"{task['code']}: {task.get('detail', '')}")
if task["status"] == "solved": print(task["solution"])else: print("failed:", task["error"]["code"], task["error"]["message"])import { randomUUID } from 'node:crypto';
const API = 'https://api.noptcha.com';const HEADERS = { Authorization: `Bearer ${process.env.NOPTCHA_KEY}` }; // a nop_test_ key runs in the sandbox
async function v1(path, init = {}) { const res = await fetch(`${API}${path}`, { ...init, headers: { ...HEADERS, ...init.headers } }); const data = await res.json(); if (!res.ok) throw new Error(`${data.code}: ${data.detail ?? ''}`); return data;}
// One Idempotency-Key per task you want. If you retry this request after a network error, send the same key and// the same body bytes: you get the same task back, not a second one (see Idempotency on the Tasks page).const idempotencyKey = randomUUID();let task = await v1('/v1/tasks', { method: 'POST', headers: { 'Content-Type': 'application/json', Prefer: 'wait=60', 'Idempotency-Key': idempotencyKey }, body: JSON.stringify({ type: "image.grid.aws", params: { image: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", question: "Select all hats", }, }),});while (task.status === 'processing') { await new Promise((r) => setTimeout(r, 1000)); // a long poll can return early (for example when wait slots are full) task = await v1(`/v1/tasks/${task.id}?wait=60`); // long poll}if (task.status === 'solved') console.log(task.solution);else console.log('failed:', task.error.code, task.error.message);In the sandbox the task is solved at once and solution is:
{ "objects": [ 0 ]}