Error Reference
Complete guide to DUAL API error codes, common causes, and fixes.
Error Response Format
All DUAL API errors follow a consistent JSON format for easy client-side handling:
{
"error": {
"code": 4001,
"message": "Invalid template schema",
"details": {
"field": "private.price",
"reason": "Field type must be number, got string"
}
}
}
Always check the code field to determine error type. The message is human-readable but should not be parsed. The details object provides context-specific information.
HTTP Status Codes
DUAL uses standard HTTP status codes to indicate request outcomes:
| Status Code | Error Type | Example |
|---|---|---|
| 400 | Validation Error | Missing required field, invalid data type |
| 401 | Authentication Error | Invalid credentials, expired token, missing API key |
| 403 | Permission Error | User lacks required role, org access denied |
| 404 | Not Found | Resource does not exist, template not found |
| 409 | Conflict | Template name already exists, object locked |
| 422 | Unprocessable Entity | Semantic error in business logic, invalid state transition |
| 429 | Rate Limited | Too many requests, quota exceeded |
| 500 | Server Error | Internal error, database failure |
Authentication Errors
Common authentication issues and their causes:
- Invalid credentials (401) — Email/password combination does not match. Double-check the credentials used during wallet registration.
- Expired token (401) — JWT token lifetime exceeded. Tokens expire after 24 hours; call
POST /wallets/loginagain to refresh. - Missing API key (401) — Request lacks
x-api-keyheader. Include the header in all API requests. - Invalid API key (401) — The key is malformed or revoked. Generate a new key in the dashboard.
- Missing authorization header (401) — Use either Bearer token or API key; one is required.
Template Errors
Issues when creating or modifying templates:
- Duplicate name (409) — A template with that name already exists in your organization. Template names must be unique. Use a version suffix (v2, v3) if you need a new variant.
- Invalid schema (400) — The schema JSON is malformed or contains unsupported types. Check that all field types are strings, numbers, booleans, or arrays.
- Template in use (409) — Cannot delete a template with live objects. Create a new template version and migrate objects instead.
- Invalid property type (400) — Field type not supported. Supported types: string, number, boolean, array, object (for nested data).
Object Errors
Errors when creating, updating, or querying objects:
- Template not found (404) — The template_id you provided does not exist. Verify the ID matches a template in your org.
- Invalid properties (400) — Object properties do not match the template schema. Check field names and types.
- Ownership conflict (422) — Cannot transfer object to non-existent wallet. Verify recipient wallet ID is valid.
- Object locked (422) — Object is in the middle of a state transition. Wait a moment and retry.
- Object not found (404) — Object ID does not exist. Verify the ID and check if the object was deleted.
Action Errors
Issues when executing actions on objects:
- Invalid action type (400) — The action type is not registered for this template. Create the action type with
POST /ebus/action-types. - Object locked (422) — Object has an in-flight action. Wait for it to complete before executing another.
- Insufficient permissions (403) — Current user lacks permission to execute this action. Check role permissions.
- Invalid parameters (400) — Action parameters do not match the expected schema. Verify all required parameters are provided.
- State violation (422) — Action cannot be executed in current object state. For example, cannot transfer a locked object.
Webhook Errors
Common issues with webhook delivery and configuration:
- Invalid URL (400) — Webhook URL is not a valid HTTPS endpoint. All webhooks must use HTTPS.
- Signature mismatch (401) — Webhook signature verification failed. Check that you're using the correct secret and hashing method.
- Timeout (504) — Webhook endpoint did not respond within 30 seconds. Optimize your handler to respond quickly.
- Delivery failed (500) — Server error when calling your webhook. Check your webhook logs and endpoint status.
Debugging Tips
Strategies for solving errors quickly:
- Check the X-Request-Id header — Every response includes
X-Request-Id. Save this when reporting issues to support; it helps track the request through our logs. - Enable debug mode in SDK — Set
debug: truewhen initializing the client to log all requests and responses to stderr. - Common gotchas:
- Forgetting
Content-Type: application/jsonheader on POST requests - Using expired JWT tokens without refreshing
- Wrong org context (using sandbox API key with prod URL)
- Object IDs and template IDs are case-sensitive
- Properties object must match template schema exactly
- Forgetting
- Test in sandbox first — Errors in sandbox have the same root causes as production. Debug locally before deploying.