Make a decision

    POST /v1/understand answers one decision: a named one we maintain, or your own question.

    Built and tested, not yet deployed. Early access.

    On this page
    curl "$UNDERSTANDING_API_URL/v1/understand" \
      -H "Authorization: Bearer $UNDERSTANDING_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "decision": "restricted_merchant",
        "input": {
          "merchant": "DRAFTKINGS",
          "mcc": "7995"
        }
      }'
    const base = process.env.UNDERSTANDING_API_URL;
    const key = process.env.UNDERSTANDING_API_KEY;
    
    const body = {
      decision: "restricted_merchant",
      input: {
        merchant: "DRAFTKINGS",
        mcc: "7995",
      },
    };
    
    const res = await fetch(`${base}/v1/understand`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${key}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });
    const result = await res.json();
    import os
    import requests
    
    base = os.environ["UNDERSTANDING_API_URL"]
    key = os.environ["UNDERSTANDING_API_KEY"]
    
    body = {
        "decision": "restricted_merchant",
        "input": {
            "merchant": "DRAFTKINGS",
            "mcc": "7995",
        },
    }
    
    res = requests.post(
        f"{base}/v1/understand",
        headers={"Authorization": f"Bearer {key}"},
        json=body,
        timeout=10,
    )
    result = res.json()

    Stand-in probability1

    {
      "decision": "restricted_merchant",
      "type": "predicate",
      "answer": true,
      "probability": 0.97,
      "reasons": [
        "mcc_7995",
        "rule_gambling_category",
        "kind_sportsbook"
      ],
      "abstain": false
    }
    {
      "error": {
        "message": "input must be an object",
        "field": "input"
      }
    }

    Headers

    • Authorizationstringrequired

      Bearer <your key>, or Bearer <access token> from a connected app. The key alone also works. Keys and authentication

    • x-api-keystringoptional

      Your key, for a client that can’t set Authorization. Read only when there’s no Authorization header.

    • Content-Typestringrecommended

      application/json. The body is read as JSON either way.

    • Idempotency-Keystringoptional

      1 to 255 printable characters. The same key within 24 hours returns the first successful response, with no second model call and no second charge. With a different body: 422. While the first is still running: 409.

    • x-request-idstringoptional

      Your own id for the call: 1 to 128 letters, digits and . _ : -. We send it back; without one, we make one.

    Body: a named decision

    • decisionstringrequired

      One of restricted_merchant, spend_type, receipt_match, refund_pairing, return_window, support_route, signal_baseline, member_route, document_complete.

    • inputobjectrequired

      The decision’s input. Each decision’s page lists its fields.

      Show 4 fields
    • abstainBelownumberoptional

      The probability under which abstain is true, from 0.5 to 0.99. Defaults to 0.8.

    Body: your own question

    • questionobjectrequired

      Your question.

      Show 4 fields
      • typestringrequired

        predicate, choice or score.

      • instructionsstringrequired

        1 to 4,000 characters.

      • optionsarray or objectchoice

        2 to 50 names, or a map of name to description.

      • levelsarrayscore

        2 to 11 ordered levels.

    • inputobject or stringrequired

      An object, or text up to 20,000 characters.

    • abstainBelownumberoptional

      From 0.5 to 0.99. Defaults to 0.8.

    If a body has both decision and question, decision wins.

    Response 200

    • decisionstring or null

      The named decision, or null for your own question.

    • typestring

      predicate, choice or score.

    • answerboolean, string, number or null

      Predicate: true or false. Choice: one option name, a transaction id for receipts and refunds, or "none" when nothing matches. Score: an integer from 0 to 100. null when the model declined.

    • probabilitynumber or null

      The probability of the answer given. For a predicate answered false it is one minus the probability of true; for a score it is the most likely level’s probability. 1 when a rule settled the answer. null when the model declined or gave no probability.

    • reasonsarray of strings

      Codes for what the answer rests on: rule checks that fired and the model’s sub-answers. Empty for your own question, unless the model declined: then ["model_declined"], as for a named decision.

    • abstainboolean

      True when the probability is under your line, when the model gave no probability for its answer (answer is still set) or when the model declined. Send these cases to a person.

    Response headers

    • cache-controlstringalways

      no-store, on every response, errors included.

    • x-request-idstringalways

      Yours, if you sent a valid one; otherwise ours, starting req_. Quote it when you ask us about a call.

    • x-understanding-input-tokensstringmetered calls

      The input tokens the call counted, as a whole number. On a 200 to an API key or a connected app’s token.

    • x-understanding-cost-usdstringmetered calls

      What the call cost, in US dollars, as a number with six decimal places and no dollar sign. On a 200 to an API key or a connected app’s token. A call that fails costs nothing.

    • idempotent-replayedstringreplays only

      true when the response is the stored one for a repeated Idempotency-Key.

    • retry-afterstring409 and 429

      Seconds to wait before the next call: 1 on a 409, 10 on a 429.

    • www-authenticatestring401 only

      Bearer realm="understanding-api".

    Errors

    Errors
    StatusWhen
    400The body isn’t JSON, a field is wrong, the input holds a card, Social Security or account number, or the Idempotency-Key is malformed. error.field names the part at fault when one can be named.
    401No credential, or a key or access token that isn’t valid, has expired or was revoked.
    402The account is out of credit.
    409A request with this Idempotency-Key is still running.
    413The body is over 256 KB.
    422This Idempotency-Key was used with a different body.
    429Over 60 requests in a minute on one key.
    500Something went wrong on our side. Try again.
    502The decision model didn’t answer. Try again.
    503We couldn’t check the key or the account just then. Try again.

    Every error message

    Checked against the code

    The fields on this page are checked against the contract in our code each time the site is built (last on 2026-11-02).