Read the response envelope
JSON responses share one format. success indicates success; code is the status; code_message summarizes it; errors[] holds issues; header has metadata; data_count counts items; and data is always a list, even with one result.
{"success":true,"code":200,"code_message":"Request processed successfully.","errors":[],"header":null,"data_count":1,"data":[{"result":"..."}]}
Do not assume data[0] exists. A search with no results may return 200 with data: []. Check success, data_count, and the route contract first.

Request call metadata
Send summary=true in the query when you need execution details in header, including log_id, price, charge status, and execution mode. Store the log_id for support and reconciliation under Calls. The X-Api4devs-Log-Id HTTP header also provides it.
Handle errors consistently
Use errors[].code to decide what your system does. It is stable; messages can change or be translated. Show an appropriate message to users, but base retries and alerts on the code and HTTP status.
| Status | Suggested action |
|---|---|
| 400/422 | Fix the fields in errors[].field before retrying. |
| 401/403 | Check key, environment, project, scope, and allowed IP. |
| 402 | Balance or limit is insufficient. Top up or adjust the limit. |
| 429 | Respect the indicated delay and lower your request rate. |
| 5xx | Record log_id and retry with backoff when the operation permits. |
Avoid duplicate execution
For an operation that must not repeat, send a unique Idempotency-Key for each logical attempt. Reusing it with identical content returns the earlier response without executing or charging again. A repeat while the first request is in progress returns 409. Reusing the key with changed content returns 422.
curl 'https://staging.apifordevs.com/api/v1/oracle/document/read?dev_mode=true' \
-u "afd_test_pk_...:$APIFORDEVS_TEST_SECRET" \
-H 'Idempotency-Key: order-1842' \
-F 'file=@document.pdf' -F 'document_type=CNH'
Receive a binary response
Some routes, such as face crop, return a file instead of JSON. Read Content-Type to store it correctly. Call metadata arrives in X-Api4devs-* headers; do not parse file bytes as a JSON envelope.
Test the same file flow in Playground. Before automating, open the route reference for input types, file size limits, and output format.
Quick answers
No. In the JSON envelope, `data` is always a list. It can be empty even with status 200.
Use `errors[].code` and the HTTP status. The message is for humans and can change.
With identical content, the earlier response is returned without a new execution or charge.