Skip to main content

Errors

Every error from /v1 is one shape, application/problem+json (RFC 9457):

{
"type": "https://docs.hopforms.com/api/errors#insufficient_scope",
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"detail": "This API key does not hold the flows:read scope.",
"request_id": "req_example_0001"
}

Branch on code. It is stable for the life of /v1; detail is a sentence for a person and its wording may change. type links to the code's section on this page. Validation failures add errors, a list of {field, code, detail} naming what was wrong. Quote request_id when asking for help.

Codes are only ever added. The list below is complete for the current build. Codes for endpoints not yet published are listed ahead of their release, so a client can branch on them from day one.

malformed_request​

400. The request body could not be read as JSON. Check the body is valid JSON and the Content-Type is application/json.

unknown_parameter​

400. A query parameter is not one the endpoint accepts. Where an endpoint declares parameters, errors names the offending one and suggests the closest known one.

invalid_parameter​

400. A query parameter you named correctly carries a value the endpoint will not accept — a limit above the maximum, a timestamp that is not RFC 3339, or a cursor that did not come from this endpoint's own next_cursor. errors names the parameter. Note that limit above the maximum is an error rather than a silent clamp, so a page size you did not ask for can never be mistaken for the end of the data.

unauthorized​

401. No usable key: missing, malformed, unknown, revoked, or expired. The body is identical in every case. Mint a new key on your organisation's API page and send it as Authorization: Bearer hop_sk_....

insufficient_scope​

403. The key is valid but does not hold the permission this endpoint needs. The WWW-Authenticate header names the scope; edit the key's permissions or mint one that has it.

not_found​

404. Nothing at that path for this key: the resource does not exist, or belongs to another organisation. The two cases are deliberately indistinguishable.

in_flight​

409. A request with the same Idempotency-Key is still being processed. Wait for it to finish, then read the result rather than sending again.

not_in_draft_state​

409. Publish refused: the version is not a draft.

draft_not_yet_uploaded​

409. Publish refused: WhatsApp has not finished receiving the draft. Poll the version until publishable is true, then publish.

not_published​

409. Unpublish refused: the flow is not currently published.

must_unpublish_first​

409. Delete refused: the flow is published. Unpublish it, then delete.

register_in_use​

409. The record action cannot be removed while an option list still reads the register it provisioned; the detail says which flow, or that it is this flow's own version. Remove that binding in the flow editor, then retry.

code_conflict​

409. Making the flow public would claim a keyword another organisation already holds. Change the keyword in the app, then retry.

plan_cap_reached​

409. Publish refused: the organisation's plan has reached its published-flow cap. detail names the cap. Email billing@hopforms.com to raise the cap.

request_too_large​

413. The body is over this endpoint's limit. On endpoints that accept a body, detail states the bytes sent and the bytes allowed.

unsupported_media_type​

415. The Content-Type is not one this endpoint accepts. Endpoints take JSON unless their reference page says multipart.

validation_failed​

422. The request has the right shape but a wrong value, or a body key the endpoint does not know. errors lists each field with its own code and detail. On the record-action write, errors[].code is one of unknown, not_register_bound, not_applicable, no_processed_version and not_a_flow_register; the operation's description says when each applies.

Elsewhere errors[].code is invalid for a value the field refuses, unknown for a name the endpoint or the flow does not have, invalid_format for a malformed idempotency key, conversion_failed for a spreadsheet that would not convert, and, on a body that fails the schema, the validator's own reason (invalid_type, missing_field, unexpected_field, min_length). That last set is the validator's and grows with it; match on field first and code second.

unknown_answer_field​

422. A submission names an answer field that is not in the flow's published Flow JSON. errors suggests the closest known field and lists the known ones.

conversion_failed​

422. The XLSForm could not be converted. errors is per cell; warnings may also be present and does not fail the request.

idempotency_key_missing​

422. This write requires an Idempotency-Key header. Send a unique value per intended operation and reuse it only when retrying that same operation.

idempotency_key_reuse​

422. The Idempotency-Key was already used with a different payload. Use a fresh key for a new operation.

no_published_version​

422. The flow has no published version, so there is no schema to validate against or submit to. Publish a version first.

no_number_configured​

422. The organisation has no WhatsApp number to attach the flow to. Configure one in the app, or pass number_id.

record_not_resolved​

422. A submission in update mode could not be matched to an existing record. Nothing was written; retrying with the same Idempotency-Key is safe once the record exists.

rate_limited​

429. Over a bucket. Obey Retry-After (seconds); detail names the bucket. RateLimit-* headers on every response the API answers show how much room is left.

internal_error​

500. Something failed on Hop's side. The body carries the standard fields and a request_id, and nothing about the failure; quote the id when reporting the problem.

converter_unavailable​

502. The XLSForm converter could not run. Nothing was created; retry, and quote request_id if it persists.

storage_unavailable​

502. The source form could not be stored. Nothing was created; retry with the same Idempotency-Key.

converter_timeout​

504. The XLSForm converter did not finish inside its budget. Nothing was created; try a smaller form or retry.