Errors and rate limits

The error format, the error code catalog and the rate limit headers.

Error format

All errors follow RFC 9457 Problem Details, returned as application/problem+json:

{
  "type": "https://api.lingohub.com/errors/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "The request contains invalid fields.",
  "instance": "/v2/projects",
  "code": "validation_failed",
  "request_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "errors": [
    {
      "pointer": "#/name",
      "parameter": null,
      "code": "minLength",
      "detail": "must be at least 2 characters long"
    }
  ]
}
FieldMeaning
codeMachine-readable error code. Use it, not title or detail, in your error handling.
typeLink to a page that explains the error.
titleShort, constant summary of the error.
statusHTTP status code.
detailHuman-readable explanation of this occurrence.
instancePath of the request that failed.
request_idCorrelation ID, also in the X-Request-ID header. Quote it when you contact support.
errorsRejected fields or parameters, when the problem concerns specific input. pointer locates a body field (JSON Pointer), parameter a query, path or header parameter or a multipart field.
required_permissionOn 403, the permission the API key is missing.

A resource your key isn't allowed to see can return 404 resource_not_found, the same as one that doesn't exist.

Error codes

CodeHTTP statusMeaning
invalid_json400Invalid JSON
invalid_parameter400Invalid parameter
unexpected_request_body400Unexpected request body
missing_parameter400Missing parameter
unknown_parameter400Unknown parameter
invalid_filter400Invalid filter
invalid_cursor400Invalid cursor
bad_request400Bad request
missing_api_key401Missing API key
invalid_api_key401Invalid API key
expired_api_key401Expired API key
revoked_api_key401Revoked API key
disabled_api_key401Disabled API key
insufficient_permissions403Insufficient permissions
resource_not_found404Resource not found
route_not_found404Route not found
method_not_allowed405Method not allowed
not_acceptable406Not acceptable
precondition_failed412Precondition failed
content_too_large413Content too large
unsupported_media_type415Unsupported media type
already_exists409Already exists
idempotency_outcome_unknown409Idempotency outcome unknown
idempotency_key_in_use409Idempotency key in use
stack_not_empty409Stack not empty
branch_not_ready409Branch not ready
backup_not_ready409Backup not ready
backup_in_use409Backup in use
distribution_release_not_ready409Distribution release not ready
distribution_release_counts_unavailable409Distribution release counts unavailable
distribution_release_empty409Distribution release empty
import_not_cancellable409Import not cancellable
task_not_open409Task not open
task_not_closable409Task not closable
task_not_skippable409Task not skippable
default_branch_protected409Default branch protected
owner_membership_protected409Owner membership protected
source_language_protected409Source language protected
branch_limit_reached409Branch limit reached
context_image_limit_reached409Context image limit reached
translation_order_pending409Translation order pending
git_integration_not_configured409Git integration not configured
git_integration_unauthorized409Git integration unauthorized
conflict409Conflict
validation_failed422Validation failed
idempotency_key_mismatch422Idempotency key mismatch
rate_limit_exceeded429Rate limit exceeded
internal_error500Internal error
upstream_error502Upstream error
service_unavailable503Service unavailable
upstream_timeout504Upstream timeout

Rate limits

Requests are limited per API key and per workspace, where the workspace limit counts all of its keys together. When you exceed either limit, the API answers 429 rate_limit_exceeded with a Retry-After header that gives the seconds to wait.

Responses to authenticated requests also carry the RateLimit and RateLimit-Policy headers (IETF draft):

  • RateLimit-Policy lists the policies that apply, each with its request quota q per window of w seconds.
  • RateLimit reports the policy closest to rejection: the requests remaining right now (r) and the seconds until the full quota is available again (t). For example: "api-key";r=42;t=7.

Use these headers to pace your requests instead of waiting for a 429. They are advisory: they're missing when a request fails authentication or the limiter state is briefly unknown.

A 429 never makes it safe to repeat a write whose outcome you don't know. See Safe retries and conditional updates.


Did this page help you?