Skip to main content
When a request fails, the API returns an HTTP status code from 400 to 599 and a JSON body with the same shape on every endpoint:
This page describes API version 2026-10. In 2026-09, an error body has a message, which is the Swedish text when one exists, and most errors add an internal code and an errorId. Several errors also have a different status. For the differences, see Upgrading to 2026-10.

Handle an error

We recommend handling an error in the following order:
  1. Branch on code. The list of codes is closed, so you can handle each code you care about and treat the rest as a failure.
  2. Show userMessage to your users, if you show them anything. Don’t show message, which is written for developers.
  3. Log requestId with every failed request.
The following TypeScript sample turns an error response into an exception that carries the code:

Validation errors

A request that fails validation returns 400 VALIDATION_FAILED and lists every problem in issues, so you can fix them all at once:
Each issue has the following fields:
  • path: the dotted path to the invalid value in the body, the query string, or the path parameters, such as parties.0.email. For a header, it’s the header name, such as Idempotency-Key. It’s empty for a problem with the whole request, such as an unknown query parameter.
  • code: one of INVALID_TYPE, INVALID_FORMAT, INVALID_VALUE, TOO_SMALL, TOO_BIG, or UNRECOGNIZED_KEY.
  • message: a description of the problem, in English, for developers.
An unknown query parameter is an UNRECOGNIZED_KEY issue, so a misspelled filter fails instead of returning every result. For the rules that query strings follow, see Query parameters.

Authentication and permission errors

The status tells you whether the credential or the operation is the problem:
  • 401 UNAUTHORIZED means only that the token is missing, invalid, expired, or revoked. Check the API key, or refresh the OAuth access token. For more information, see Refresh the access token.
  • 403 means that the token is valid, but the operation isn’t allowed. The code tells you why:
    • PERMISSION_DENIED: the user’s workspace role lacks a permission the operation requires, or the endpoint isn’t available to OAuth apps.
    • INSUFFICIENT_SCOPE: the OAuth token wasn’t granted a scope the operation requires. The body lists requiredScopes and grantedScopes. For more information, see Scopes.
    • PLAN_REQUIRED: the organization’s plan doesn’t include API access or the feature.
    • ACCOUNT_INACTIVE: the organization, the user, or the user’s workspace membership is deactivated or suspended.
    • ACCOUNT_SETUP_REQUIRED: the organization must finish its setup first.
    • LIMIT_EXCEEDED: a plan limit was reached, such as the monthly number of sent documents.
A retry doesn’t fix a 401 or a 403 error. Change the credential, the role, the scopes, or the plan first.

Not found errors

A 404 status has one of two codes:
  • NOT_FOUND: the endpoint exists, but the resource doesn’t, or the token can’t access it. resource names the type of the missing resource, so you can tell a missing document from a missing party on the same path.
  • ROUTE_NOT_FOUND: no endpoint matches the method and path in the API version you requested. Check the method and the path. An endpoint that a later version removed also returns ROUTE_NOT_FOUND on that version. For more information, see API versioning.

Conflict errors

A 409 status means that the request conflicts with the current state of a resource:
  • INVALID_STATE: the resource’s state doesn’t allow the operation, such as editing a document that was already sent, or downloading a file that isn’t produced yet. Change the state, or wait for it to change, and then retry.
  • ALREADY_EXISTS: a resource with the same unique value, such as externalId, already exists.
  • APPROVAL_REQUIRED: the operation needs an approval first, such as sending a document that the workspace requires an approval for. To ask for one, see Request approval of a document.
  • IDEMPOTENCY_KEY_IN_USE: a request with the same Idempotency-Key is still running. For more information, see Idempotency.

Request IDs

Every response, successful or not, carries a Sajn-Request-Id header, such as Sajn-Request-Id: req_V1StGXR8Z5jdHi6BmyT2. An error body repeats it as requestId. Log it with every failed request, and quote it when you contact support at [email protected]. When a request with an Idempotency-Key replays a stored error, the requestId in the body identifies the original request, and the Sajn-Request-Id header identifies the retry.

Retry a failed request

Only some errors can succeed when you retry the same request:
  • RATE_LIMITED and IDEMPOTENCY_KEY_IN_USE: wait the number of seconds in the Retry-After response header, and then retry. For a sample, see Retry with backoff.
  • DAILY_QUOTA_EXCEEDED: Retry-After can be several hours, so stop sending requests and resume after it. For more information, see Rate limits and quotas.
  • UPSTREAM_UNAVAILABLE, INTERNAL_ERROR, and network errors: retry with exponential backoff. To make a retried write request safe, send the same Idempotency-Key header on every attempt. For more information, see Idempotency.
  • Every other code: the request fails the same way until you change it, or the state it depends on changes, so don’t retry it unchanged.

Error codes

The API returns only the following codes: The version codes are described in API versioning, the 429 codes in Rate limits and quotas, and the IDEMPOTENCY_KEY_* codes in Idempotency. The OAuth endpoints under /api/oauth, such as the token endpoint, don’t use this shape. They return the standard OAuth 2.0 error and error_description fields. For more information, see Token endpoint errors.