Every API error follows a consistent Stripe-style structure. This page documents every error code, what causes it, and how to fix it.
Error Shape
{
"success": false,
"error": {
"type": "invalid_request_error",
"code": "parameter_missing",
"message": "The 'title' field is required.",
"param": "title",
"doc_url": "https://cstar.help/developers/api/errors#parameter_missing",
"request_id": "req_a1B2c3D4e5F6"
},
"meta": {
"requestId": "req_a1B2c3D4e5F6",
"timestamp": "2026-03-30T10:30:00Z"
}
}
Key fields:
- type -- The broad error category (see below)
- code -- Machine-readable error code (use this for programmatic handling)
- message -- Human-readable explanation
- param -- Which parameter caused the error (when applicable)
- doc_url -- Direct link to documentation for this error
- request_id -- Include this when contacting support
Error Types
| Type | Meaning |
|---|---|
authentication_error |
API key issue (missing, invalid, wrong type, insufficient permissions) |
invalid_request_error |
Bad request (missing fields, invalid values, conflicts) |
not_found_error |
Resource doesn't exist |
rate_limit_error |
Too many requests |
api_error |
Something went wrong on our end |
Authentication Errors (401/403)
| Code | Status | Description |
|---|---|---|
authentication_required |
401 | Missing or malformed Authorization header |
invalid_api_key |
401 | Key is invalid or revoked |
invalid_key_format |
401 | Key doesn't start with sk_live_, pk_live_, sk_test_, or pk_test_ |
key_expired |
401 | Key has expired |
insufficient_permissions |
403 | Key lacks the required permission |
publishable_key_write |
403 | Tried to write with a publishable key |
team_access_denied |
403 | Key doesn't belong to the requested team |
Common fix: Check that you're using the right key type. Publishable keys (pk_*) are read-only. Use a secret key (sk_*) for create/update/delete operations.
Invalid Request Errors (400/409)
| Code | Status | Description |
|---|---|---|
parameter_missing |
400 | A required parameter is missing |
parameter_invalid |
400 | A parameter has an invalid value |
invalid_json |
400 | Request body isn't valid JSON |
invalid_id_format |
400 | ID isn't a valid UUID or prefixed ID (e.g., tkt_abc123) |
resource_conflict |
409 | Duplicate resource (e.g., customer email already exists) |
The param field tells you exactly which parameter failed. Examples:
{"code": "parameter_missing", "param": "title", "message": "The 'title' field is required"}
{"code": "parameter_invalid", "param": "priority", "message": "The 'priority' field must be one of: low, normal, high, urgent"}
{"code": "resource_conflict", "param": "email", "message": "A customer with this email already exists"}
Not Found Errors (404)
| Code | Status | Description |
|---|---|---|
resource_not_found |
404 | The requested resource doesn't exist |
Double-check the ID. Both UUIDs and prefixed IDs (tkt_, cus_, art_) are accepted.
Rate Limit Errors (429)
| Code | Status | Description |
|---|---|---|
rate_limit_exceeded |
429 | Too many requests in the current window |
The response includes a Retry-After header with seconds to wait. See API Rate Limits for backoff strategies.
Server Errors (500)
| Code | Status | Description |
|---|---|---|
internal_error |
500 | Unexpected server error |
database_error |
500 | Database operation failed |
These are our fault, not yours. If persistent, contact support with the request_id.
HTTP Status Code Summary
| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Resource created |
| 204 | Success (no body, used for CORS preflight) |
| 400 | Invalid request |
| 401 | Authentication failed |
| 403 | Permission denied |
| 404 | Resource not found |
| 409 | Conflict (duplicate resource) |
| 429 | Rate limit exceeded |
| 500 | Server error |
Debugging Tips
- Read the
paramfield -- it points directly to the problem parameter - Follow the
doc_url-- each error links to its own documentation - Save the
request_id-- support can trace the exact request with it - Validate your JSON before sending -- malformed bodies return
invalid_json