Error Handling
All Tanqory API errors follow a consistent JSON format.
Error Response Format
{
"statusCode": 422,
"message": "Product title is required",
"error": "Unprocessable Entity",
"code": "VALIDATION_ERROR"
}
| Field | Description |
|---|---|
statusCode | HTTP status code |
message | Human-readable error description |
error | HTTP status text |
code | Machine-readable error code |
HTTP Status Codes
| Code | Meaning | When |
|---|---|---|
400 | Bad Request | Malformed request body or parameters |
401 | Unauthorized | Missing or expired token |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource does not exist |
409 | Conflict | Duplicate entry (e.g., duplicate SKU) |
422 | Unprocessable Entity | Validation failed |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server-side failure |
Error Codes
| Code | Description |
|---|---|
VALIDATION_ERROR | Request body failed Zod validation |
RESOURCE_NOT_FOUND | Referenced ID does not exist |
DUPLICATE_ENTRY | Unique constraint violated |
INSUFFICIENT_STOCK | Not enough inventory for operation |
PAYMENT_FAILED | Payment processor rejected the charge |
RATE_LIMIT_EXCEEDED | Too many requests |
SUBSCRIPTION_REQUIRED | Feature requires a higher plan |
SDK Error Classes
import { TanqoryAPIError, TanqoryRateLimitError, TanqoryNetworkError } from '@tanqory/sdk'
try {
await tanqory.products.create(storeId, data)
} catch (error) {
if (error instanceof TanqoryRateLimitError) {
console.log(`Retry after ${error.retryAfter}s`)
} else if (error instanceof TanqoryNetworkError) {
console.log('Network issue — check connectivity')
} else if (error instanceof TanqoryAPIError) {
console.log(error.statusCode) // 400, 404, 422, etc.
console.log(error.code) // 'VALIDATION_ERROR'
console.log(error.message) // 'Product title is required'
}
}
Retry Logic
The SDK auto-retries on 429 and 5xx errors (up to maxRetries, default 3):
const tanqory = createClient({
apiKey: 'pk_live_...',
maxRetries: 3, // Retries 429 and 5xx with exponential backoff
})
For manual retry with raw HTTP:
# Check the Retry-After header on 429 responses
HTTP/1.1 429 Too Many Requests
Retry-After: 2
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712678400
Validation Errors
Validation errors may include field-level details:
{
"statusCode": 422,
"message": "Validation failed",
"error": "Unprocessable Entity",
"code": "VALIDATION_ERROR",
"details": [
{ "field": "title", "message": "Product title is required" },
{ "field": "price", "message": "Price must be a positive number" }
]
}