Auto.dev

Error Codes

Complete catalog of API error responses, status codes, and error types

This document catalogs all possible error types that clients may encounter when using the Auto.dev API Gateway.

Error Response Structure

All API errors follow a consistent JSON structure:

interface ApiError {
  status: number            // HTTP status code (400, 401, 404, 500, etc.)
  error: string             // Human-readable error description
  code: string              // Programmatic error identifier
  path: string              // API endpoint path that generated the error
  requestId: string         // Unique identifier for debugging and support
  suggestion?: string       // Helpful guidance for resolution (optional)
  message?: string          // Alternative error description (legacy/some endpoints)
  errorType?: string        // Legacy error type classification

  // Plan-gating fields (402 responses)
  currentPlan?: string      // The plan the caller is on
  requiredPlan?: string     // The plan needed for this feature
  upgradeUrl?: string       // Preferred upgrade link (tier-targeted)
  upgradeLink?: string      // Alias of upgradeUrl (kept for backward compat)
  docsUrl?: string          // Link to the plans documentation
  plans?: Record<string, { price: string; rateLimit: string; features: string }>
}

Field Usage Across APIs:

  • status - HTTP status code (universal)
  • error - Primary error message (universal)
  • code - Error code identifier (universal)
  • path - Request path (universal)
  • requestId - Debug identifier (universal)
  • suggestion - Resolution guidance (taxes API)
  • message - Alternative / extended error description
  • errorType - Legacy VIN validation errors
  • currentPlan, requiredPlan, upgradeUrl, upgradeLink, docsUrl, plans - Plan-gating context (402 responses)

HTTP Status Codes

400 - Bad Request

Invalid Location

Code: INVALID_LOCATION

{
  "status": 400,
  "error": "Invalid ZIP code format. ZIP code must be 5 digits (e.g., 90210) or 5+4 format (e.g., 90210-1234)",
  "code": "INVALID_LOCATION",
  "path": "/taxes/invalidzip",
  "requestId": "a1b2c3d4e5f6g7h8",
  "suggestion": "Please provide a valid 5-digit ZIP code or ZIP+4 format"
}

Invalid VIN Format

Code: INVALID_VIN_FORMAT

{
  "status": 400,
  "error": "VIN must be exactly 17 characters containing only letters and numbers (excluding I, O, Q)",
  "code": "INVALID_VIN_FORMAT",
  "path": "/vin/123Invalid",
  "requestId": "a1b2c3d4e5f6g7h8"
}

Invalid License Plate Format

Code: INVALID_PLATE_FORMAT

{
  "status": 400,
  "error": "License plate must be 2-8 alphanumeric characters",
  "code": "INVALID_PLATE_FORMAT",
  "path": "/plate/A?state=CA",
  "requestId": "b2c3d4e5f6g7h8i9"
}

Invalid State Code

Code: INVALID_STATE_CODE

{
  "status": 400,
  "error": "State must be a valid 2-letter US state code (e.g., CA, NY, TX)",
  "code": "INVALID_STATE_CODE",
  "path": "/plate/ABC123?state=XX",
  "requestId": "c3d4e5f6g7h8i9j0"
}

Invalid Parameter

Code: INVALID_PARAMETER

{
  "status": 400,
  "error": "Invalid parameter provided: make. This parameter does not exist in this endpoint.",
  "code": "INVALID_PARAMETER",
  "path": "/listings",
  "requestId": "966e8386bb38f095"
}

Invalid Request

Code: INVALID_REQUEST

{
  "status": 400,
  "error": "Invalid request format or missing required parameters",
  "code": "INVALID_REQUEST",
  "path": "/api/endpoint",
  "requestId": "d4e5f6g7h8i9j0k1"
}

401 - Unauthorized

Authentication Required

Code: UNAUTHORIZED

{
  "status": 401,
  "message": "Authentication required. Get your API key at https://auto.dev/dashboard/api-keys",
  "code": "UNAUTHORIZED",
  "path": "/vin/1HGCM82633A123456",
  "requestId": "e5f6g7h8i9j0k1l2"
}

402 - Payment Required

Returned when the caller's plan does not include the requested endpoint. The response body carries plan-gating context (currentPlan, requiredPlan, upgradeUrl, docsUrl, and a plans summary) so clients can render an actionable upgrade CTA without a second API call. Two response headers make the same context available without parsing the body:

  • X-Required-Plan — plan needed for this feature
  • X-Current-Plan — plan the caller is currently on

Feature Not Available

Code: FEATURE_NOT_AVAILABLE

{
  "status": 402,
  "error": "Payment Required",
  "code": "FEATURE_NOT_AVAILABLE",
  "message": "This feature requires the Scale plan. You are currently on the Starter plan.",
  "currentPlan": "Starter",
  "requiredPlan": "Scale",
  "upgradeUrl": "https://auto.dev/pricing?tier=Scale",
  "upgradeLink": "https://auto.dev/pricing?tier=Scale",
  "docsUrl": "https://docs.auto.dev/plans",
  "plans": {
    "Growth": { "price": "$299/mo", "rateLimit": "10 req/s", "features": "build, specs, marketvalue, recalls, tco, payments" },
    "Scale":  { "price": "$599/mo", "rateLimit": "50 req/s", "features": "All Growth + openrecalls, plate lookup, taxes" }
  },
  "path": "/openrecalls/1HGCM82633A123456",
  "requestId": "f6g7h8i9j0k1l2m3"
}

Payment Required (legacy)

Code: PAYMENT_REQUIRED

The original 402 shape is still returned by some legacy endpoints without plan context. New integrations should rely on FEATURE_NOT_AVAILABLE shape above.

{
  "status": 402,
  "error": "Payment Required",
  "code": "PAYMENT_REQUIRED",
  "path": "/advanced-endpoint",
  "requestId": "f6g7h8i9j0k1l2m3",
  "upgradeLink": "https://auto.dev/pricing"
}

403 - Forbidden

Forbidden Access

Code: FORBIDDEN

{
  "status": 403,
  "error": "Forbidden",
  "code": "FORBIDDEN",
  "path": "/restricted-endpoint",
  "requestId": "g7h8i9j0k1l2m3n4"
}

404 - Not Found

VIN Not Found

Code: VIN_NOT_FOUND

{
  "status": 404,
  "error": "No vehicle data found for the provided VIN",
  "code": "VIN_NOT_FOUND",
  "path": "/vin/1FTFW3LDXRFB40317",
  "requestId": "b2c3d4e5f6g7h8i9"
}

License Plate Not Found

Code: PLATE_NOT_FOUND

{
  "status": 404,
  "error": "No vehicle found for the provided license plate",
  "code": "PLATE_NOT_FOUND",
  "path": "/plate/NOTFOUND?state=CA",
  "requestId": "h8i9j0k1l2m3n4o5"
}

No Data Found

Code: NO_DATA_FOUND

{
  "status": 404,
  "error": "License plate found but no vehicle data available",
  "code": "NO_DATA_FOUND",
  "path": "/plate/ABC123?state=CA",
  "requestId": "i9j0k1l2m3n4o5p6"
}

Resource Not Found

Code: RESOURCE_NOT_FOUND

{
  "status": 404,
  "error": "Resource \"1FTFW3LDXRFB40317\" not found",
  "code": "RESOURCE_NOT_FOUND",
  "path": "/listings/1FTFW3LDXRFB40317",
  "requestId": "966716ac29ed8147"
}

422 - Unprocessable Entity

VIN Decode Failed

Code: VIN_DECODE_FAILED

{
  "status": 422,
  "error": "Unable to decode VIN: 1HGBH41JXMN109186",
  "code": "VIN_DECODE_FAILED",
  "path": "/vin/1HGBH41JXMN109186",
  "requestId": "j0k1l2m3n4o5p6q7"
}

Payment Calculation Error

Code: PAYMENT_CALCULATION_ERROR

{
  "status": 422,
  "error": "Cannot calculate payments with provided data",
  "code": "PAYMENT_CALCULATION_ERROR",
  "path": "/payments/1GYKPDRSXSZ102995",
  "requestId": "k1l2m3n4o5p6q7r8"
}

VIN Not Covered

Code: VIN_NOT_COVERED

Returned by /openrecalls when the VIN decodes successfully but falls outside the coverage of our recall data (typically grey-market imports, motorcycles, or non-standard formats). Distinct from a transient upstream failure — retrying will not change the outcome.

{
  "status": 422,
  "error": "VIN is not in our recall coverage. Only vehicles registered in the United States, Canada, or Mexico are supported at this time.",
  "code": "VIN_NOT_COVERED",
  "path": "/openrecalls/SC6GM1CAMX1234567",
  "requestId": "a7b8c9d0e1f2g3h4"
}

429 - Too Many Requests

Rate-limited responses carry the standard RFC 6585 + draft-ietf rate-limit headers so clients can back off deterministically:

  • Retry-After — seconds until the caller may retry
  • X-RateLimit-Limit — request budget for the window
  • X-RateLimit-Remaining — always 0 on a 429
  • X-RateLimit-Reset — Unix timestamp (seconds) when the window resets

Callers on Free/Starter that are approaching the monthly usage quota also see X-Usage-Remaining, X-Usage-Used, and X-Usage-Limit on all responses (not just 429s).

The body carries the same plan-gating context as 402 responses — upgradeLink + plans — so clients can present an upgrade CTA directly.

Rate Limit Exceeded

Code: RATE_LIMIT_EXCEEDED

{
  "status": 429,
  "error": "Rate limit exceeded for your Starter plan. Upgrade to Growth ($299/mo, 10 req/s) at https://auto.dev/pricing for higher limits.",
  "code": "RATE_LIMIT_EXCEEDED",
  "path": "/vin/1HGCM82633A123456",
  "requestId": "l2m3n4o5p6q7r8s9",
  "upgradeLink": "https://auto.dev/pricing",
  "plans": {
    "Growth": { "price": "$299/mo", "rateLimit": "10 req/s", "features": "build, specs, marketvalue, recalls, tco, payments" },
    "Scale":  { "price": "$599/mo", "rateLimit": "50 req/s", "features": "All Growth + openrecalls, plate lookup, taxes" }
  }
}

500 - Internal Server Error

Internal Server Error

Code: INTERNAL_SERVER_ERROR

{
  "status": 500,
  "error": "500 - Internal Server Error",
  "code": "INTERNAL_SERVER_ERROR",
  "path": "/api/endpoint",
  "requestId": "m3n4o5p6q7r8s9t0",
  "message": "An unexpected error occurred, please try again later."
}

503 - Service Unavailable

Source Error

Code: SOURCE_ERROR

{
  "status": 503,
  "error": "External service temporarily unavailable",
  "code": "SOURCE_ERROR",
  "path": "/payments/1GYKPDRSXSZ102995",
  "requestId": "c3d4e5f6g7h8i9j0"
}

Legacy Error Formats

VIN Validation (Legacy Format)

Some endpoints may still return legacy error formats:

{
  "status": 400,
  "error": "VIN validation failed",
  "code": "VIN_VALIDATION_ERROR",
  "path": "/legacy/vin/invalid",
  "requestId": "n4o5p6q7r8s9t0u1",
  "errorType": "VALIDATION_ERROR"
}

Error Handling Best Practices

Client Implementation

  1. Always check the status code first
  2. Use the code field for programmatic error handling
  3. Display the error message to users (human-readable)
  4. Log the requestId for debugging and support
  5. Implement retry logic for 5xx errors with exponential backoff

Getting Help

When contacting support, please include:

  1. Request ID from the error response
  2. Full error response JSON
  3. Request details (endpoint, parameters, headers)
  4. Expected behavior vs. actual behavior