Skip to content

Errors

Every error response from Ele has the same shape:

{
"error": {
"type": "not_found",
"message": "Resource not found.",
"request_id": "…"
}
}
Field Meaning
type A short code for what went wrong. Your code branches on this.
message A sentence you can show to a person as it is. Never branch on it: the wording can change.
request_id The ID of this request. Quote it when you contact Ele support.
details More detail, when there is some. On a validation error it lists each field that failed and why.
step_up The step-up challenge, when type is step_up_required. See Step-up and approvals.

type, message and request_id are always there. details and step_up are there only when they apply, and may be null.

Decide what to do from error.type. Do not decide from the HTTP status alone, because many types share a status: a 403 can mean the person lacks a role, or that the call needs step-up.

Treat type as an open list. Ele adds new types over time, and any failure without a specific type comes back as unprocessable_entity. Handle the types you care about and send everything else to one default branch that shows the message and logs the request_id.

In Go, with the helper from the example code:

var apiErr *ele.APIError
if errors.As(err, &apiErr) {
switch apiErr.Type {
case "step_up_required":
// Ask the person to complete step-up, then retry.
case "not_authenticated":
// The session has ended. Sign the person in again.
case "rate_limited":
// Wait, then retry.
default:
log.Printf("ele: %s (request %s)", apiErr.Type, apiErr.RequestID)
// Show apiErr.Message to the person.
}
}

Every response, success or failure, carries an x-request-id header. On an error it is the same as error.request_id, except on a replayed response, whose body keeps the ID of the original request. Log it with every failed call. When you ask Ele support about a request, the ID lets them find it.

These are the types you will meet most often. Each operation’s reference page lists the statuses it can return.

Status type Meaning What to do
400 invalid_request A path or query parameter is missing or invalid. details names it. Fix the request. Do not retry it unchanged.
400 idempotency_key_required This write needs an Idempotency-Key header. Add one. See Idempotency.
401 not_authenticated The bearer token is missing, invalid or expired. Sign the person in again. See Authentication.
401 invalid_credentials Sign-in: the email or password is wrong. Ask the person to try again.
401 invalid_api_key The API key is malformed, unknown, revoked, for the other environment, or its secret does not match. Check the key. See API keys.
403 forbidden The person’s role in this organization does not allow this. Show the message. See Organizations and roles.
403 step_up_required The call needs the person to confirm they are present. Complete step-up, then retry. See Step-up and approvals.
403 step_up_enrollment_required The call needs step-up, and the person has no method strong enough. Ask the person to set up an authenticator app. A passkey or the Ele mobile app also counts, but your server can only pass on authenticator codes.
403 api_key_not_permitted This operation does not accept an API key. Call it with a person’s session token.
403 api_scope_missing The API key lacks the scope this operation needs. Give the key that scope, or use another key.
403 organization_unavailable The API key’s organization is paused, banned or deleted. Contact Ele support.
404 not_found The resource does not exist, or this person cannot see it. Check the ID and the organization.
409 conflict The request conflicts with the resource’s current state. Fetch the resource again and decide.
409 idempotency_conflict A request with this Idempotency-Key is still running, or stopped partway. Wait, then retry with the same key. See Idempotency.
413 content_too_large The request body or upload is too large. Send less.
415 unsupported_media_type The body is not JSON. Send Content-Type: application/json.
422 invalid_request The request body failed validation. details lists each field that failed. Fix the body. Do not retry it unchanged.
422 validation_error Ele rejected a value in the body. details says which. Fix the value.
422 idempotency_params_mismatch This Idempotency-Key was already used with a different body. Use a new key for a new request.
422 insufficient_funds The organization’s balance does not cover a payment, a payment batch or a swap. Show the message. Add money, or send less.
422 insufficient_balance The balance does not cover a purchase from Ele, such as a plan or a card order, or there are not enough reward points. Show the message.
422 kyc_required The person or organization must finish identity checks first. Send the person to onboarding.
422 unprocessable_entity Any other refusal without a more specific type. When details is present, it lists the fields that failed. Show the message.
429 rate_limited Too many attempts. Wait, then retry. On a write with an Idempotency-Key, retry with a new key. See Rate limits.
500 internal_error Something failed inside Ele. Check whether the work happened before you retry. See Retrying.
502 provider_unavailable A partner that Ele relies on did not answer. Check whether the work happened before you retry. See Retrying.
502 xero_unavailable Xero did not answer. Retry with the same key. See Retrying.

Many operations add their own types, such as already_rejected when you approve a rejected request. The reference page and the guide for each area name them.

Reads are always safe to retry. Writes need care.

If you sent a write with an Idempotency-Key, Ele keeps most answers under that key, errors included. A retry with the same key returns the same error for 24 hours. That includes 429, 500 internal_error and 502 provider_unavailable. To try again after a kept error, you need a new key, and a new key can do the work a second time if the first attempt did take effect:

  • After a kept 4xx refusal, Ele did not do the work. Fix the cause, or wait, and retry with a new key.
  • After 500 internal_error or 502 provider_unavailable, check whether the work happened before you retry with a new key. If you cannot tell, do not retry: a duplicate payment is worse than none.

Some answers are not kept. For these, keep the same key:

  • 409 idempotency_conflict: the first request is still running, or stopped partway. Wait, then retry with the same key. Never switch to a new key here: the work may already be done.
  • 502 xero_unavailable: retry with the same key.
  • Validation failures (invalid_request, or unprocessable_entity with field details) and step_up_required: fix the cause, then retry with the same key.

Idempotency lists which answers are kept and which are not.

A few failures do not come back in the envelope above. An unexpected failure inside Ele can return 500 with a different JSON body, and a proxy between you and Ele can return an HTML page. Your client must still handle these. Treat any status of 500 or above without an error.type as a failure whose outcome is unknown: for a write, check whether the work happened before you retry. See After a failure.

The Go helper does this for you. When the body is not an Ele error, it returns an APIError with an empty Type, and Message holds the status and the start of the body.