LegitGrailsLegitGrails
Status unavailable
  • Developers
  • API Reference
LegitGrails API
    OverviewQuickstartIntegration setupAuthenticationCatalogOrdersPhotosWebhooksRate limitsErrorsChangelog
API Reference
LegitGrails API

Errors

Failed requests under /v1/integrations use a common JSON envelope. Branch on HTTP status and stable code, not the human-readable message, and retain the request ID for logs and support.

See the API Reference for endpoint-specific error schemas.

Error envelope

Code
HTTP/1.1 400 Bad Request Content-Type: application/json X-Request-Id: <request-id>
Code
{ "statusCode": 400, "message": "Request validation failed", "timestamp": "<timestamp>", "path": "/v1/integrations/orders", "code": "validation-error", "details": { "errors": ["A required field is missing"] }, "request_id": "<request-id>" }
FieldUse
statusCodeNumeric HTTP status.
messageDiagnostic text; do not branch on it.
timestampError timestamp.
pathRequested path.
codeStable, case-sensitive error category.
detailsError-specific context.
request_idIdentifier matching X-Request-Id.

For an unexpected failure, provide the request ID, method, path, time, and relevant order identifier to support. Never include an API key or sensitive photo URL.

HTTP status handling

StatusMeaningClient action
400 Bad RequestInvalid body, query, identifier, catalog choice, photo selection, or webhook URL.Correct the request; do not retry unchanged.
401 UnauthorizedCredentials could not authenticate the request.Check the Authorization header and API key.
402 Payment RequiredThe account lacks credits for order creation.Add credits, then reconcile before creating again.
403 ForbiddenThe request is not authorized for this operation.Check the required scope.
404 Not FoundThe resource or route is unavailable in the authenticated context.Verify the identifier and request path.
409 ConflictThe operation conflicts with current order state.Fetch current order detail before acting.
413 Payload Too LargeAn uploaded file is too large.Resize or recompress it.
429 Too Many RequestsAn endpoint rate limit was exceeded.Honor Retry-After; retry with backoff and jitter.
5xxThe service encountered a transient failure.Retry only safe operations; reconcile ambiguous writes first.

See Authentication for scope rules.

Common and order codes

StatusCodeMeaning or useful details
400validation-errorRequest validation failed; inspect details.errors.
400bad-requestThe request is malformed or violates general request rules.
400answer-time-unavailableInspect available_answer_times and next_available_at.
400mock-outcome-requiredTest keys must send one of the values in allowed_mock_outcomes; Live keys must omit mock_outcome.
400photo-index-not-foundThe index is invalid for the selected catalog context.
400missing-required-photo-indexesInspect missing_index_codes.
400photo-limit-exceededInspect index_code, max_photos, and received_photos.
400unsupported-photo-urlUse only a managed URL returned by POST /photos.
402not-enough-creditsThe account cannot fund the order.
404not-foundA catalog entity was not found.
404order-not-foundThe order is unavailable in the authenticated context.

Refresh Catalog data before correcting catalog codes.

Photo errors

StatusCodeMeaning or useful details
400photo-upload-limit-exceededThe request contains more than 10 files.
400empty-photo-fileOne of the supplied files is empty.
400INVALID_FILE_TYPEThe uploaded image format is unsupported.
400RESOLUTION_TOO_LARGEAn image exceeds 8,000 pixels on one side or 50 megapixels.
400RESOLUTION_MISSINGImage dimensions could not be read.
413FILE_TOO_LARGEThe file exceeds the active per-file limit.
409order-not-awaiting-update-photosThe order is not accepting updated photos; details.expected_status is update-photos.
400invalid-update-photoA resolution violates the documented photo-update rules.
400photo-index-not-requestedInspect requested_index_codes.
400missing-requested-photo-indexesInspect missing_index_codes.
400photo-limit-exceededToo many photos were submitted for an index.
400unsupported-photo-urlUpload the replacement through POST /photos first.

Updated-photo submissions have no idempotency key. After a timeout, conflict, or stale response, retrieve the order before submitting again.

Webhook errors

StatusCodeMeaning
400validation-errorInvalid URL or event fields.
400unsafe-webhook-urlThe destination failed the checks documented in Webhooks.
400bad-requestThe endpoint identifier is invalid.
409webhook-already-existsThe same destination URL is already registered for this API key.
409webhook-limit-reachedThe API key already has the maximum 10 endpoints.
404not-foundThe endpoint is unavailable in the authenticated context.

Audit errors

GET /audit/events returns 400 with invalid-audit-date-range when from is later than to. Invalid timestamps, filters, or pagination values return the normal validation-error response.

Rate limits and retries

Authenticated LegitGrails API responses expose X-RateLimit-Limit and X-RateLimit-Remaining. The API-key category limiter uses code rate-limit-exceeded and includes Retry-After in seconds; the same value is available as details.retry_after_seconds. Additional abuse protection can also return 429, so always branch on the HTTP status and honor Retry-After. Do not use X-RateLimit-Reset to calculate the API-key category window; it is not produced by that limiter.

Treat the response headers as authoritative, wait at least the requested interval, and add capped exponential backoff with random jitter. The exact per-category limits and endpoint mapping are documented in Rate limits.

Use these rules for timeouts and transient failures:

OperationSafe recovery
Any GETRetry with capped backoff; honor Retry-After.
POST /ordersReconcile an ambiguous result before retrying; do not retry automatically.
POST /photosThis operation is not idempotent; reuse a known successful response and avoid automatic retries.
POST /orders/{id}/update_photosFetch authoritative order detail and its latest request before another submission.
DELETE /webhooks/{id}A repeat can return 404; treat an already absent endpoint as reconciled.

Do not retry 400, 401, 402, 403, 404, 409, or 413 unchanged. For 5xx and transport failures, retry only idempotent or reconciled operations, with a cap and jitter. If failures persist, retain the most recent request_id.

Last modified on September 4, 2026
Rate limitsChangelog
On this page
  • Error envelope
  • HTTP status handling
  • Common and order codes
  • Photo errors
  • Webhook errors
  • Audit errors
  • Rate limits and retries
JSON