Getting Started

Errors

Every failed request returns the same JSON body.

{
  "trace_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
  "error_code": "devapi_not_found_error",
  "message": "Not Found",
  "details": "The customer does not belong to this partner"
}
FieldWhat it is
trace_idIdentifier of this request. Keep it: support asks for it first
error_codeMachine-readable code, stable across releases. Branch on it
messageShort explanation for a human. The wording changes without notice, do not match on it
detailsExtra context: a string, a list of field errors, or no key at all when there is nothing to add

Status codes

StatusMeaningWhat to do
400The request is well-formed, but these values cannot be usedRead message and fix the request
401The API key is missing or unknownSend a valid X-Api-Key
403The key is valid, the action is not allowed for itDo not retry; the action needs a different account
404The object does not exist or belongs to another partnerCheck the UUID against your own customers
405The method is not allowed on this pathFix the request
409The object is in a state that does not allow the actionRead the object, act on its current state
422The body or a header failed validationRead details; the list names every invalid field
500A failure on our sideRetry with backoff; if it repeats, send support the trace_id
503The service is temporarily unavailableRetry with backoff

Codes

error_codeHTTPWhen
devapi_internal_error500Unexpected failure inside Stablegate
devapi_request_validation_error422The body or a header failed validation
devapi_iban_parse_error400The IBAN cannot be parsed
devapi_bank_code_required_error400The IBAN does not carry a BIC; pass bank_code explicitly
devapi_bad_request_error400The values contradict each other, for example both client_account and client_account_uuid
devapi_email_occupied_error400The email or username belongs to an existing customer
devapi_not_found_error404The object does not exist or is not yours
devapi_unauthorized_error401The API key is missing or unknown
devapi_forbidden_error403The action is not allowed for this key
devapi_method_not_allowed_error405The method is not allowed on this path
devapi_customer_close_error409A customer can be closed only in the new state with no verification submitted
devapi_download_aol_error409The account opening letter is not available in the current state
devapi_kyc_application_link_error400, 409Verification by link is not configured, or the application is in a state that does not allow the action
devapi_instant_verification_error400, 409Instant verification is not configured, not available for this customer type, or the application is in a state that does not allow the action
devapi_idempotency_invalid_key422Idempotency-Key has non-printable characters or is longer than 255
devapi_idempotency_key_misuse422The key was already used with a different body or path
devapi_idempotency_request_in_progress409A request with this key is still running; retry when it finishes
devapi_service_unavailable_error503A service Stablegate depends on is down

Validation errors

A 422 lists every invalid field in details:

{
  "trace_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
  "error_code": "devapi_request_validation_error",
  "message": "Unprocessable Entity",
  "details": [
    {
      "loc": ["body", "source", "amount"],
      "msg": "Input should be a valid decimal",
      "type": "decimal_parsing"
    },
    {
      "loc": ["body", "destination", "client_account_uuid"],
      "msg": "Field required",
      "type": "missing"
    }
  ]
}

loc is the path to the field: the first item is where the value came from (body, query, header), the rest is the path inside it.

Codes raised by other services

Requests that touch orders, limits, accounts, customers or verification go through internal services, and their codes reach you through the Partner API: oa_ for operations, ca_ for customers. An example is oa_limit_exceeded_error, which check-limits and order creation return when a rule is broken, with the reason in details.

Treat these codes as opaque. Log the code and the trace_id, show the customer message, and send both to support when the problem needs us.

Retries

  • Retry 500, 503 and timeouts with exponential backoff. Three attempts is enough for an interactive flow; a background job can keep going longer.
  • Send the same Idempotency-Key on every retry of the same request: a repeated create returns the first result instead of a second order. A retry with a different body answers 422 with devapi_idempotency_key_misuse.
  • Do not retry 400, 401, 403, 404 and 422 unchanged: the same request fails the same way.
  • 409 may go away when the object changes state, so re-read the object before you decide.
  • There is no rate limit today. If one appears, it will answer 429 with Retry-After.

The request id header

Every response carries X-Request-Id. Send your own value in the request header and Stablegate returns it unchanged; without it the platform generates one. The trace_id of an error body is the same value, so the header alone identifies the call even when the body never reaches you — for example a gateway timeout.

curl https://api.stablegate.com/v1/customers/ \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "X-Request-Id: order-c1d2e3f4-42"

Before you contact support

Send the trace_id, the method and path of the request, and the time with the time zone. The trace_id finds the request in our logs, everything else narrows the search.

Ready to integrate?

Tell us about your use case and we will enable Partner API access for your account.
Copyright © 2026