Errors

    Built and tested, not yet deployed. Early access.

    On this page

    The envelope

    message is safe to log and show. field appears only for a request error that can name the part of the body at fault. code appears on the errors a program should tell apart: sensitive_data, invalid_idempotency_key, idempotency_in_progress and idempotency_key_reuse.

    Error

    400 Bad Request

    {
      "error": {
        "message": "input must be an object",
        "field": "input"
      }
    }

    That error is the answer to {"decision":"spend_type","input":[]}: a named decision whose input isn’t an object.

    400 Bad Request

    400 errors
    MessageCauseWhat to do
    The body must be JSON.The body didn’t parse.Send a JSON object.
    The body must be a JSON objectAn array, string or null at the top level. No field.Wrap it in an object.
    Send either "decision" (a named decision) or "question" (your own question)Neither key is there. No field.Add one.
    decision must be one of: restricted_merchant, spend_type, receipt_match, refund_pairing, return_window, support_route, signal_baseline, member_route, document_completeAn unknown decision id. field: "decision".Check the id.
    input must be an objectA named decision with other input. field: "input".Send an object.
    input must be an object or textYour own question with other input, or text over 20,000 characters.Send an object, or shorter text.
    abstainBelow must be a number from 0.5 to 0.99field: "abstainBelow".Send a number in range, or leave it out.
    question must be an objectfield: "question".
    question.instructions must be text of 1 to 4000 charactersMissing, blank or too long.
    question.options must list 2 to 50 optionsToo few or too many, or a blank name.
    question.options descriptions must be textA map whose descriptions aren’t all strings.
    question.levels must list 2 to 11 ordered levels
    question.type must be "predicate", "choice" or "score"
    <field> must be text of 1 to <n> charactersDecision input text: 200 characters, transaction ids 100.
    <field> must be a four-digit merchant category codeSend the code as a string.
    <field> must be an amount in US dollarsNot a number, or over a billion.
    <field> must be an ISO 8601 date
    <field> must be a transaction object
    <field>.id can't be "none"none is reserved for “no match”.
    input.transactions must be a list of up to 500 transactionsTrim the list.
    input.transactions ids must be unique
    input.mcc is requiredSpend type without a code.
    input.receipt must be an objectReceipt to charge.
    input.purchase.amount must be positiveRefund to purchase.
    This looks like a full card number. Send the merchant, amount and date instead; never send card numbers.A string anywhere in the body holds 13 to 19 digits that pass the card checksum, or a whole number of 15 to 19 digits does. code: "sensitive_data"; field is the path, such as input.transactions[2].merchant. The value is never repeated.Remove the number and send the request again.
    This looks like a Social Security number. Remove it; the API never needs one.A number written AAA-GG-SSSS (or with spaces), or nine digits under a key such as ssn. code: "sensitive_data".Remove it.
    This looks like a bank account number with its routing number. Remove them; send the merchant, amount and date instead.A routing number beside an account number, in one string or in one object (by key name, such as routing and account, or by the routing checksum). code: "sensitive_data".Remove both.
    Idempotency-Key must be 1 to 255 printable characters.The Idempotency-Key header is empty, too long, or has spaces or other characters outside printable ASCII. code: "invalid_idempotency_key".Send a key such as a UUID.

    401 Unauthorized

    401 errors
    MessageCauseWhat to do
    Send your API key or access token as a Bearer token. Get a key at <console address>.No credential: neither an Authorization nor an x-api-key header, or an Authorization value with a space in it that isn’t Bearer <key>.Add the header.
    That API key isn't valid or was revoked.A key we don’t recognise, or one that was revoked.Check the key; make a new one if it was revoked.
    That access token isn't valid, has expired or was revoked.An access token (uat_…) we don’t recognise, one past its hour, or one whose app connection was revoked.Refresh the token, or connect the app again.
    That access token was issued for a different MCP URL.A token issued for another of our addresses.Use a token issued for this address.

    402 Payment Required

    402 errors
    MessageCauseWhat to do
    This account is out of credit. Email api@theunderstanding.company to add more.The key’s account has no credit left. Checked before the call, so the call isn’t made.Add credit. Don’t retry.

    409 Conflict

    409 errors
    MessageCauseWhat to do
    A request with this Idempotency-Key is still running. Retry in a moment.The first request with this key hasn’t finished. Comes with Retry-After: 1. code: "idempotency_in_progress".Wait a second, then retry with the same key.

    413 Payload Too Large

    413 errors
    MessageCauseWhat to do
    The body is over 256 KB.Split the call; trim transactions.

    422 Unprocessable Entity

    422 errors
    MessageCauseWhat to do
    This Idempotency-Key was already used with a different request.The key was used in the past 24 hours with another body. code: "idempotency_key_reuse".Use a new key for a new request. Don’t retry.

    429 Too Many Requests

    429 errors
    MessageCauseWhat to do
    Rate limit: 60 requests per minute per key.The key made 60 calls in the past minute. Comes with Retry-After: 10.Wait 10 seconds, then retry.

    500 Internal Server Error

    500 errors
    MessageCauseWhat to do
    Something went wrong on our side. Try again.An error we didn’t expect, at any step. Every response, this one included, carries x-request-id.Retry with backoff, with the same Idempotency-Key. If it keeps happening, send us the request id.

    502 Bad Gateway

    502 errors
    MessageCauseWhat to do
    The decision model didn't answer. Try again.Any error inside the decision other than a bad request: usually the model call failing. A model that declines is not this: that is a 200 with model_declined.Retry with backoff.

    503 Service Unavailable

    503 errors
    MessageCauseWhat to do
    The API is starting up. Try again in a moment.We couldn’t check the key, the credit or the rate just then.Retry with backoff.

    Order of checks

    1. The key or access token: 401, or 503 if it can’t be checked just then.
    2. The size on Content-Length: 413.
    3. JSON, and the size once read: 400 or 413.
    4. The Idempotency-Key, if sent: 400 if it’s malformed, 422 if it was used with another body, 409 while its first request runs. A repeat of a finished success is answered here, from the stored response.
    5. For an API key or a connected app’s token, the account’s credit, then the rate: 402, then 429.
    6. The sensitive-data screen: 400 with code: "sensitive_data", before any model sees the input.
    7. The fields: 400.
    8. The decision: 200, or 502.

    The first check that fails answers; nothing after it runs. An error we didn’t expect, at any step, is a 500.