Starship Rewards API

Error Codes

Complete reference for error envelope shape, HTTP status codes, and API-specific error codes returned by the Starship Rewards API

Error Codes

Every Starship API error is returned in a consistent envelope so your integration can route, log, and retry programmatically — without string-matching on messages.

Error Envelope

All non-2xx responses follow this shape:

{
  "error": {
    "name": "ValidationException",
    "code": "E_VALIDATION_FAILURE",
    "message": "Input validation failed.",
    "messages": {
      "amount": [
        {
          "rule": "required",
          "field": "amount",
          "message": "The amount field is required."
        }
      ]
    }
  }
}
FieldTypeDescription
error.namestringStable machine identifier for the error class (e.g., ValidationException, NotFoundError). Safe to branch on.
error.codestringShort, UPPER_SNAKE_CASE code. The recommended primary field to branch on — see code table below.
error.messagestringHuman-readable summary. Suitable for logs; not guaranteed to be stable. Do not branch on this.
error.messagesobject (optional)Present only on validation failures. Maps field name → array of { rule, field, message }.

Never match on error.message. Messages are subject to wording changes. Always branch on error.code (or error.name). The API guarantees codes are stable; messages are not.

Code Table

Error codes grouped by HTTP status. Your integration should handle every code in a status class consistently (e.g., all 4xx are non-retriable; all 5xx may be retried with backoff).

400 Bad Request

CodeNameWhen it occurs
E_VALIDATION_FAILUREValidationExceptionRequest body failed schema validation. error.messages contains per-field details.
VALIDATION_FAILUREValidationExceptionSingle-field validation failure (legacy code; prefer E_VALIDATION_FAILURE).
INVALID_INPUTInvalidInputErrorInput is syntactically valid but semantically rejected (e.g., unsupported currency).
INVALID_STATUSInvalidStatusErrorThe resource cannot transition to the requested status.
INVALID_FEATUREInvalidFeatureErrorThe feature is not enabled for your client account. Contact support.
NOT_FOUNDProductNotFoundException / DenominationNotFoundExceptionReferenced product or denomination doesn't exist. (Yes, 400 on these is historical — see note below.)
BAD_REQUESTBadRequestErrorGeneric malformed request.
SYNTAX_ERRORSyntaxErrorRequest body is not valid JSON.
IDEMPOTENCY_KEY_REQUIRED(see note)Idempotency-Key header missing on a write endpoint that requires it.
IDEMPOTENCY_KEY_TOO_SHORT(see note)Idempotency-Key shorter than 8 characters.
IDEMPOTENCY_KEY_TOO_LONG(see note)Idempotency-Key longer than 256 characters.

Idempotency errors use a slightly different envelope. The three IDEMPOTENCY_KEY_* errors currently return { error: { code, message, details } } (no name, no messages). Branch on error.code — it is stable across both envelope shapes. A future release will unify these on the standard envelope.

401 Unauthorized

CodeNameWhen it occurs
E_UNAUTHORIZED_ACCESSAuthenticationExceptionCredentials are missing, malformed, or revoked. Check X-API-Key / X-API-Secret or JWT.
UNAUTHORIZEDUnauthorizedErrorGeneric authentication failure.
INVALID_CREDENTIALSInvalidCredentialsErrorCredentials were supplied but were wrong.

402 Payment Required

CodeNameWhen it occurs
PAYMENT_REQUIREDPaymentRequiredErrorWallet balance is insufficient to complete the order.

403 Forbidden

CodeNameWhen it occurs
FORBIDDEN_ACTIONForbiddenActionErrorAuthenticated, but your API key does not have permission for this operation.
FORBIDDENForbiddenErrorGeneric authorization failure.

404 Not Found

CodeNameWhen it occurs
NOT_FOUNDNotFoundErrorGeneric resource not found.
WALLET_NOT_FOUNDWalletNotFoundExceptionThe wallet referenced does not exist for this client.
USER_NOT_FOUNDUserNotFoundErrorThe client user referenced does not exist.
RESOURCE_NOT_AVAILABLEResourceNotAvailableErrorResource exists but is unavailable for the requested operation.

405 / 408 / 409 / 410

CodeHTTPNameWhen it occurs
METHOD_NOT_ALLOWED405MethodNotAllowedErrorHTTP verb is not supported for this endpoint.
OPERATION_TIMEOUT408OperationTimeoutErrorOperation exceeded its internal timeout budget. Retriable with backoff.
RESOURCE_CONFLICT409ResourceConflictErrorState conflict (e.g., duplicate Idempotency-Key with different body).
CONFLICT409ConflictErrorGeneric state conflict.
GONE410GoneErrorResource existed but has been permanently removed. Do not retry.

429 Too Many Requests

CodeNameWhen it occurs
E_REQUEST_THROTTLEDThrottlingExceptionPer-client rate limit hit. Honor the Retry-After response header.
TOO_MANY_REQUESTSTooManyRequestsErrorBurst limit on a specific endpoint. Back off and retry.

500 / 503

CodeHTTPNameWhen it occurs
INTERNAL_SERVER_ERROR500InternalServerErrorUnhandled server error. Safe to retry idempotent reads; use an Idempotency-Key for writes.
INTERNAL_DATABASE_ERROR500InternalDatabaseErrorDatabase layer failure. Retriable.
SERVICE_UNAVAILABLE503ServiceUnavailableErrorA downstream dependency is unavailable (typically a vendor API during fulfillment). Retriable.

Retry Guidance

StatusRetry?Strategy
4xx (except 408/429)NoFix the request before retrying.
408 Operation TimeoutYesExponential backoff, start at 2 s, max 5 attempts.
429 Too Many RequestsYesHonor Retry-After header; if absent, exponential backoff from 1 s.
500 / 503YesExponential backoff starting at 1 s, max 3 attempts. Writes must carry the same Idempotency-Key.
Network timeout / connection resetYesSame as 5xx. Treat as "request possibly succeeded" for writes — use idempotency.

Idempotency is your friend. For any POST/PUT/PATCH retry, reuse the original Idempotency-Key. The server will return the cached response instead of processing the request twice. See the Idempotency guide.

Validation Error Details

For E_VALIDATION_FAILURE, the error.messages object gives you per-field reasons. Each entry is an array (a field can fail multiple rules):

{
  "error": {
    "name": "ValidationException",
    "code": "E_VALIDATION_FAILURE",
    "message": "Input validation failed.",
    "messages": {
      "email": [
        { "rule": "required", "field": "email", "message": "The email field is required." }
      ],
      "amount": [
        { "rule": "gt", "field": "amount", "message": "The amount field must be greater than 0." },
        { "rule": "numeric", "field": "amount", "message": "The amount field must contain only numeric values." }
      ]
    }
  }
}

Common validation rules you'll see in rule:

RuleMeaning
requiredField is missing or empty.
min / maxString length out of bounds.
lenString length not exactly N.
gt / gte / lt / lteNumeric comparison failure.
numericValue is not numeric.
emailValue is not a valid email.

Security & Information-Disclosure

Starship sanitizes error messages before returning them to clients — SQL errors, stack traces, credential fragments, and internal connection details are never leaked. If you ever see one, report it to hello@rocketincentive.com immediately.

Next Steps