Error Codes
Complete reference of all Holdify API error codes.
All Holdify API errors follow a consistent format. Errors include a machine-readable code, human-readable message, and a link to documentation.
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests, please retry after 60 seconds",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"docs_url": "https://holdify.io/docs/errors#rate-limiting"
}Quick reference
| Code | HTTP | Description |
|---|---|---|
| INVALID_API_KEY | 401 | Invalid API Key |
| API_KEY_EXPIRED | 401 | API Key Expired |
| RATE_LIMIT_EXCEEDED | 429 | Rate Limit Exceeded |
| BUDGET_EXCEEDED | 429 | Budget Exceeded |
| IDEMPOTENCY_KEY_CONFLICT | 409 | Idempotency Key Conflict |
| IDEMPOTENCY_KEY_REQUIRED | 400 | Idempotency Key Required |
| INVALID_REQUEST_BODY | 400 | Invalid Request Body |
| RESOURCE_NOT_FOUND | 404 | Resource Not Found |
| ACCESS_DISABLED | 403 | Access Disabled |
| WEBHOOK_SIGNATURE_INVALID | 401 | Invalid Webhook Signature |
| INTERNAL_SERVER_ERROR | 500 | Internal Server Error |
| SERVICE_UNAVAILABLE | 503 | Service Unavailable |
Authentication Errors
INVALID_API_KEY
Invalid API Key
Description
The provided API key is invalid, malformed, or has been revoked.
Remediation
Verify your API key is correct and active. Generate a new key via POST /v1/api-keys if needed.
API_KEY_EXPIRED
API Key Expired
Description
The API key has expired and is no longer valid for authentication.
Remediation
Rotate your API key using POST /v1/api-keys/{id}/rotate to generate a new one.
Rate Limiting
RATE_LIMIT_EXCEEDED
Rate Limit Exceeded
Description
Too many requests have been made in a short period. The rate limit window will reset shortly.
Remediation
Wait for the time specified in the Retry-After header before retrying. Consider implementing exponential backoff.
BUDGET_EXCEEDED
Budget Exceeded
Description
The dollar-based budget for this API key has been exhausted. No further requests will be processed until the budget resets or is increased.
Remediation
Wait for the budget period to reset, upgrade your plan, or contact the account owner to increase the budget limit.
Details fields
| Field | Description |
|---|---|
| budget_limit | The total budget limit in USD |
| budget_spent | The amount already spent in USD |
| reset_at | Unix timestamp when the budget resets |
Idempotency
IDEMPOTENCY_KEY_CONFLICT
Idempotency Key Conflict
Description
A request with the same Idempotency-Key was already processed with a different request body (different request_hash).
Remediation
Use a unique Idempotency-Key for each distinct request. The key should only be reused for retries of the exact same request.
IDEMPOTENCY_KEY_REQUIRED
Idempotency Key Required
Description
The Idempotency-Key header is required for this endpoint but was not provided.
Remediation
Include an Idempotency-Key header with a unique value (UUID recommended) for each request.
Request Validation
INVALID_REQUEST_BODY
Invalid Request Body
Description
The request body failed validation. Check the 'details' field for specific validation errors.
Remediation
Review the API documentation for the expected request format and fix the validation errors listed in 'details'.
Resource Errors
RESOURCE_NOT_FOUND
Resource Not Found
Description
The requested resource does not exist. The 'details' field contains the resource type and ID.
Remediation
Verify the resource ID is correct. The resource may have been deleted or never existed.
Details fields
| Field | Description |
|---|---|
| resource | The type of resource that was not found (e.g., 'api_key', 'entitlement') |
| id | The ID that was requested |
Access Errors
ACCESS_DISABLED
Access Disabled
Description
Access to this resource or feature has been disabled. This may be due to an inactive entitlement, suspended account, or revoked access.
Remediation
Check your entitlement status. Contact support if you believe this is an error.
Webhook Errors
WEBHOOK_SIGNATURE_INVALID
Invalid Webhook Signature
Description
The webhook signature verification failed. The request may have been tampered with or the wrong secret was used.
Remediation
Ensure you are using the correct webhook secret. Verify the signature is computed correctly using HMAC-SHA256.
Server Errors
INTERNAL_SERVER_ERROR
Internal Server Error
Description
An unexpected error occurred on the server. This has been logged and will be investigated.
Remediation
Retry the request with exponential backoff. If the issue persists, contact support with the request_id.
Budget headers
When using dollar-based budgets, Holdify returns additional headers on every response:
X-Budget-Limit: 500.00
X-Budget-Spent: 124.50
X-Budget-Remaining: 375.50
X-Budget-Currency: USD
X-Budget-Reset: 2025-02-01T00:00:00ZUse these headers to display budget information to your customers or trigger alerts before budgets are exhausted.
When a budget is exceeded, you'll receive a 429 BUDGET_EXCEEDED error.
Handling errors in code
Use the SDK's HoldifyError class
to handle errors gracefully. Here's a complete example:
import { Holdify, HoldifyError } from '@holdify/sdk';
const holdify = new Holdify({
apiKey: process.env.HOLDIFY_PROJECT_KEY,
});
async function verifyRequest(apiKey: string) {
try {
const result = await holdify.verify(apiKey);
if (!result.valid) {
return { error: 'Invalid API key', status: 401 };
}
if (result.remaining <= 0) {
return {
error: 'Rate limit exceeded',
status: 429,
retryAfter: result.reset
};
}
// Check budget remaining (if using dollar-based budgets)
if (result.budget && result.budget.remaining <= 0) {
return {
error: 'Budget exceeded',
status: 429,
headers: {
'X-Budget-Remaining': '0',
'X-Budget-Reset': result.budget.reset_at
}
};
}
return { success: true, plan: result.plan };
} catch (error) {
if (error instanceof HoldifyError) {
switch (error.code) {
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
await new Promise(r => setTimeout(r, error.retryAfter * 1000));
return verifyRequest(apiKey);
case 'BUDGET_EXCEEDED':
// Cannot retry - budget is exhausted
return { error: 'Budget exceeded', status: 429, budgetExceeded: true };
case 'SERVICE_UNAVAILABLE':
// Fail open or closed based on your needs
console.warn('Holdify unavailable, failing open');
return { success: true, fallback: true };
default:
console.error(`Holdify error: ${error.code}`, error.message);
return { error: 'Verification failed', status: 500 };
}
}
throw error;
}
}