Skip to content

Error Codes

All API errors follow a consistent response format. This page documents every error code and its meaning.

Error Response Format

json
{
  "success": false,
  "data": null,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description",
    "details": [
      { "field": "email", "issue": "Invalid email" }
    ],
    "requestId": "req_abc123"
  },
  "meta": {
    "timestamp": "2026-03-07T12:00:00.000Z"
  }
}

The details array is present only for VALIDATION_ERROR responses, listing each field that failed validation. The requestId is included when the request ID middleware has run.

Error Code Reference

CodeHTTP StatusDescription
UNAUTHORIZED401Missing, invalid, or expired authentication token. Returned when no Authorization header is present or the token cannot be verified.
AUTH_FAILED401Authentication credentials are invalid. Returned on wrong password, expired magic link, or failed OAuth exchange.
VALIDATION_ERROR400Request body failed Zod schema validation. The details array lists each failing field and constraint. Also returned for duplicate resources (email already exists, slug already taken).
NOT_FOUND404The requested resource does not exist. Returned for missing projects, API keys, workspaces, or users.
FORBIDDEN403The authenticated user lacks permission for the requested operation. Returned when workspace role is insufficient (e.g., member attempting admin action) or API key scopes are insufficient.
RATE_LIMITED429Request rate exceeded the configured limit. Check X-RateLimit-Reset header for when the window resets.
INVALID_SOURCE400An invalid source value was specified in a query request. Must be "d1" or "kv".
INTERNAL_ERROR500Unhandled error in the service layer. No internal details are exposed to the client. Check Worker logs for diagnostics.

HTTP Status Code Summary

StatusMeaningWhen Returned
200OKSuccessful read, update, or delete
201CreatedSuccessful resource creation (register, create project, create key)
202AcceptedLog entry queued for processing
400Bad RequestValidation error, invalid source, bad slug format
401UnauthorizedMissing or invalid auth, wrong credentials
403ForbiddenInsufficient role or scope
404Not FoundResource does not exist
409ConflictDuplicate resource (email already registered, slug already taken)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnhandled server error

Context-Specific Error Codes

Authentication Errors

ScenarioCodeStatusMessage
No Authorization headerUNAUTHORIZED401Authentication required
Invalid JWT signatureUNAUTHORIZED401Invalid token
Expired JWTUNAUTHORIZED401Token expired
Invalid API keyUNAUTHORIZED401Invalid or revoked API key
Wrong passwordAUTH_FAILED401Invalid email or password
Expired magic linkAUTH_FAILED401Invalid or expired magic link
Email not verifiedFORBIDDEN403Email verification required

Authorization Errors

ScenarioCodeStatusMessage
Member attempts admin actionFORBIDDEN403Insufficient role
API key missing required scopeFORBIDDEN403Insufficient scope
Non-owner attempts ownership transferFORBIDDEN403Only owner can transfer
Unlinking last auth methodFORBIDDEN403Cannot remove last auth method

Validation Errors

ScenarioCodeStatusMessage
Missing required fieldVALIDATION_ERROR400Invalid input
Invalid email formatVALIDATION_ERROR400Invalid input
Password too short (<8 chars)VALIDATION_ERROR400Invalid input
Duplicate email on registerVALIDATION_ERROR409User with this email already exists
Duplicate workspace slugVALIDATION_ERROR409Slug already taken
Unsupported OAuth providerVALIDATION_ERROR400Unsupported OAuth provider

Security Properties

  • Error messages are generic to prevent information leakage
  • Stack traces are never exposed in production responses
  • forgot-password and magic-link always return 200 to prevent user enumeration
  • requestId in errors enables correlation with Worker logs for debugging

See Also

LogVista — Edge-native structured logging API