LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Configuration
  • API Reference
ErrorsVersioning & DeprecationRate limitsIdempotency
Conventions

Errors

The LedgerBee API uses conventional HTTP status codes and returns every error as a JSON envelope. The status code tells you whether retrying can help; the machine-readable code tells you exactly what went wrong.

The error envelope

Every error body carries at least statusCode, timestamp, path, and message. Most errors also include code and details:

Code
{ "statusCode": 400, "timestamp": "2026-06-10T12:34:56.789Z", "path": "/v1/customers", "message": "Bad Request Exception", "code": "SHARED_VALIDATION_FAILED", "details": { "validationErrors": [ { "property": "email", "constraints": { "isEmail": "email must be an email" } } ] } }
FieldAlways presentDescription
statusCodeYesThe HTTP status, repeated in the body.
timestampYesISO 8601 time the error was produced.
pathYesThe request path, relative to the /api mount (e.g. /v1/customers).
messageYesHuman-readable summary. For logging only — its wording may change.
codeNoStable machine-readable identifier (e.g. UNAUTHORIZED, LICENSE.REQUIRED). Branch on this, never on message.
detailsNoContext for the specific code — failing fields, required scopes, the missing license key.

Validation errors (400)

Request bodies are validated strictly: unknown fields are rejected, not ignored. A failed validation returns code: "SHARED_VALIDATION_FAILED" with one details.validationErrors entry per failing field:

  • property — dot-separated path to the field, including array indices (e.g. lines.0.quantity)
  • constraints — map of failed rule name to a human-readable explanation

Status codes

StatusWhen
400 Bad RequestValidation failed (above), or the request violates a business rule — the code says which.
401 UnauthorizedMissing, invalid, expired, or IP-restricted API key / OAuth token. The body has code: "UNAUTHORIZED" and message: "Invalid API key". See Authentication.
403 ForbiddenThe credential is valid but lacks a required scope (code: "INSUFFICIENT_PERMISSIONS", with details.requiredScopes), or your company lacks a required license (code: "LICENSE.REQUIRED", with details.licenseKey). See Authentication for scopes and Licenses for modules.
404 Not FoundNo such route, or the referenced resource doesn't exist in your company.
413 Payload Too LargeThe request body exceeds the size limit — message states the received size and the limit.
429 Too Many RequestsYou hit a rate limit. Back off and retry — see Rate limits.
500 Internal Server ErrorSomething failed on our side. message is a generic Internal Server Error — retry with backoff and contact support if it persists.

Requests authenticated with an OAuth bearer token also receive a standard WWW-Authenticate challenge header on 401/403 (error="invalid_token" vs error="insufficient_scope"), so OAuth and MCP clients know whether to refresh the token or re-consent.

Request IDs

Every response, success or error, carries an X-Request-ID header with a UUID unique to that request. The same ID is stamped on our server-side traces. Include it in support requests so we can locate the exact request in our logs.

TerminalCode
curl -i https://api.ledgerbee.com/api/v1/company \ -H "x-api-key: YOUR_API_KEY" # HTTP/1.1 200 OK # X-Request-ID: 7f9c2ba4-1c3d-4e5f-8a9b-0c1d2e3f4a5b

Error codes are stable

code values such as SHARED_VALIDATION_FAILED, UNAUTHORIZED, and LICENSE.REQUIRED are stable identifiers, safe to branch on. They are never renamed or repurposed; message text may be reworded at any time. New codes may be added over time, so treat any unrecognized code as a generic failure for its status code.

Last modified on July 30, 2026
Versioning & Deprecation
On this page
  • The error envelope
  • Validation errors (400)
  • Status codes
  • Request IDs
  • Error codes are stable
JSON