Skip to main content
Every failed request returns a non-2xx status and a JSON body. Use the code field to decide what to do. Treat message as English fallback text that can change.

Error response format

Most Partner API endpoints return this body:
code is omitted when a response has no stable code, for example most 422 validation errors. Codes are a public contract. Bitwage can add new codes, so handle unknown codes with your generic error path.

Legacy error body

Some older endpoints return a simpler body without request_id or code:
These endpoints return it with HTTP 400:
  • POST /api/user/create
  • POST /api/user/update
  • POST /api/user/payer/create, /update and /delete
  • POST /api/user/kyc-initiate
A few also return a plain string or a raw {field: [messages]} object. Read the body defensively: look for message, then error, then the raw body.

HTTP status codes

For 500 and 502, the body contains a generic message that includes the request_id. It does not include a code you can branch on beyond unexpected-error.

Validation errors (422)

A 422 response puts every failing field under schema. message is the first error in that tree.
Nested fields are nested in the tree. For example, a bad worker.email on POST /api/company/{company_id}/recipients/create is reported under schema.worker.email.

Authentication and permission errors

All return 403.
With API key authentication, a company_id or user_id in the query string or JSON body that you do not own produces invalid-api-key, not a 404. If a known-good key suddenly fails on one request, check the IDs. IDs in the URL path return partner-company-not-found instead.

Idempotency errors

See the Idempotency guide. Only successful responses are stored against a key. If a request fails, retry it with the same key and it runs again.

Errors by lifecycle step

Company onboarding

Recipients (contractors, employees, vendors)

Distributions

Payroll

POST /api/company/payroll/create validates the whole request and returns 422 with the failing field under schema. These are the messages you can expect. They don’t have a code; match on the field and handle unknown messages generically.

Payroll status

Retrying safely

  1. Check data.retryable. false means the same request will fail the same way. true means a provider failed and a retry can succeed.
  2. Reuse the Idempotency-Key on every retry of a write request. If the first attempt did succeed but you never got the response, you get the stored response back and no second side effect.
  3. Back off on 500 and 502. Wait and retry a few times, then contact support with the request_id.
  4. Don’t retry 4xx responses other than a 400 with data.retryable: true. Fix the request instead.