Error Handling
Understand error responses and handle them gracefully
All API errors follow a consistent JSON format with an error code, message, and optional field-level details.
Error Response Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
},
"meta": {
"request_id": "req_abc123def456ghi789jkl012"
}
}| Field | Type | Description |
|---|---|---|
error.code | string | Machine-readable error code |
error.message | string | Human-readable description |
error.details | array | Field-level errors (for validation failures) |
meta.request_id | string | Unique request ID for debugging |
Always include meta.request_id when contacting support — it helps us trace the exact request.
Error Codes
| Status | Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Request body or query parameter validation failed |
401 | MISSING_AUTH | No Authorization header provided |
401 | INVALID_API_KEY | API key is invalid, revoked, or expired |
403 | INSUFFICIENT_SCOPE | API key lacks the required scope |
404 | NOT_FOUND | Resource does not exist |
409 | CONFLICT | Duplicate resource (e.g., email or domain already exists) |
422 | UNPROCESSABLE_ENTITY | Referenced resource doesn't exist (e.g., invalid company_id) |
429 | RATE_LIMITED | Rate limit exceeded |
500 | INTERNAL_ERROR | Unexpected server error |
Validation Errors
Validation errors include a details array with field-level messages:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
},
{
"field": "tags",
"message": "Array must contain at most 20 element(s)"
}
]
},
"meta": {
"request_id": "req_abc123def456ghi789jkl012"
}
}Conflict Errors
Conflict errors occur when you try to create a resource that violates a uniqueness constraint:
{
"error": {
"code": "CONFLICT",
"message": "A contact with this email already exists in this workspace"
},
"meta": {
"request_id": "req_abc123def456ghi789jkl012"
}
}Common conflicts:
- Duplicate contact email within a workspace
- Duplicate company domain within a workspace
- Duplicate custom field slug per entity type
SDK Error Handling
The TypeScript SDK maps API errors to specific error classes:
import {
NodeStash,
ApiError,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
} from '@nodestash/sdk'
const client = new NodeStash({ apiKey: 'nds_live_...' })
try {
await client.contacts.create({ email: 'invalid' })
} catch (error) {
if (error instanceof ValidationError) {
console.log(error.message)
for (const detail of error.details) {
console.log(` ${detail.field}: ${detail.message}`)
}
} else if (error instanceof AuthenticationError) {
console.log('Check your API key')
} else if (error instanceof NotFoundError) {
console.log('Resource not found')
} else if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`)
} else if (error instanceof ApiError) {
console.log(`${error.code}: ${error.message}`)
console.log(`Status: ${error.statusCode}`)
console.log(`Request ID: ${error.requestId}`)
}
}Error Class Hierarchy
Error
└── NodeStashError — Base SDK error
└── ApiError — API returned an error response
├── AuthenticationError — 401 (invalid/missing key)
├── NotFoundError — 404 (resource not found)
├── ValidationError — 400/422 (validation failed)
└── RateLimitError — 429 (rate limited)Error Properties
| Class | Properties |
|---|---|
ApiError | code, statusCode, requestId, details, message |
AuthenticationError | requestId, message |
NotFoundError | requestId, message |
ValidationError | details[], requestId, message |
RateLimitError | retryAfter, requestId, message |
Best Practices
- Handle specific errors first — catch
ValidationError,NotFoundErroretc. beforeApiError - Log the request ID — include
meta.request_idorerror.requestIdin your logs - Don't retry 4xx errors — only retry on
429(rate limit) and5xx(server errors) - Display validation details — show users which fields have errors using
error.details