Skip to content

Errors

Every Swft error response uses the same envelope — RFC 9457 Problem Details compatible AND Stripe-shape, so any SDK that already groks Stripe-style envelopes can consume it unchanged.

{
"error": {
"type": "https://docs.swft.co.uk/errors/idempotency_key_reused",
"code": "idempotency_key_reused",
"message": "Idempotency-Key was reused with a different request body.",
"doc_url": "https://docs.swft.co.uk/errors/idempotency_key_reused",
"request_id": "req_01HZ9X...",
"param": "Idempotency-Key"
}
}

request_id always echoes the value of the response swft-request-id header — paste it into support tickets.

HTTPCodeMeaning
400bad_requestMalformed input.
400missing_parameterA required parameter is missing. param names it.
400invalid_parameterA parameter failed validation. param names it.
400missing_idempotency_keyEndpoint requires Idempotency-Key.
400missing_swft_merchant_headerEndpoint requires X-Swft-Merchant.
400unsupported_api_versionSwft-Version is not recognised. meta.supported lists valid versions.
401missing_authorizationNo Authorization: Bearer header.
401invalid_api_keyKey not found or revoked.
403forbiddenAuthenticated but not authorised.
403insufficient_scopeKey lacks a required scope. meta.required / meta.missing list them.
403merchant_not_in_workspaceX-Swft-Merchant does not belong to the key’s workspace.
404merchant_not_foundMerchant id unknown.
404workspace_not_foundWorkspace id unknown.
404resource_not_foundGeneric not-found.
404webhook_delivery_not_foundDelivery id not in this workspace.
409merchant_already_existsstore_url already registered.
409idempotency_key_reusedKey reused with different body, or request still in-flight.
409pre_confirmation_rejectedPartner pre-confirmation hook returned available:false. meta.reason repeats the partner-supplied reason.
409custom_domain_already_setMerchant already has a custom domain assigned.
429rate_limitedSlow down. meta.retry_after is seconds.
503pre_confirmation_unavailablePartner endpoint timed out / 5xx’d and fail_mode=‘closed’.

The type URL is stable. Add it to your SDK’s switch statement without parsing the human-readable message. Each URL also serves as the documentation deeplink — link to it from your own error UI.