AlmondTill/G3N API

On this page

Errors and retries

A refusal is never a bare status code. It is a structured object on the answer's errors list, with a class, a code inside the class, a retry verdict and words you can show. This guide is the grammar and the one retry rule.

The shape

{
  "errors": [
    {
      "major": "NOT_FOUND",
      "minor": "CONSTRUCT",
      "retryable": false,
      "message": "That record could not be found."
    }
  ],
  "extensions": {
    "at": {
      "callId": "01EXAMPLE-CALL-ID",
      "version": {
        "requested": null,
        "serviced": {
          "name": "genesis",
          "number": 0
        }
      }
    }
  }
}

major names the class, minor the code inside it, retryable says whether the identical call may succeed if you simply try again, and message is the refusal in plain words; detail appears when the refusal has more to say. The answer still carries extensions.at with its callId — quote it when a refusal needs a look.

The 12 classes

VALIDATION · AUTHN · AUTHZ · NOT_FOUND · CONFLICT · RATE_LIMIT · PAYMENT · FULFILLMENT · TAX · FISCAL · INTEGRATION · INTERNAL — 109 codes in all, every one on the errors pages with what happened, why, what to do, and whether to retry.

Four codes every call can answer

Beyond the four: an operation that takes an id can answer NOT_FOUND; a change can answer CONFLICT — the record's state, or an edit made in the meantime, does not allow it — and VALIDATION/VERSION_REQUIRED when the envelope named no version. Each operation page lists exactly the codes it can answer.

The one retry rule

When retryable is true, the same call, unchanged, may succeed a moment later — wait, then send it again; a RATE_LIMIT/THROTTLED refusal names how long in detail.retryAfterSeconds. When it is false, change something first: the values, the record's state, or who is calling. Retrying a false refusal unchanged only repeats it.

Sign-in refusals say one thing

A failed key exchange answers AUTHN/LOGIN_FAILED whatever the cause: an unknown, expired or retired key, and an organization the key does not reach, all read the same. Nothing leaks about which keys exist, so do not branch on the cause — check the secret and the organization, and mint a new key if in doubt.