Error handling
Handle API errors correctly with retry strategies, error codes reference, and best practices for robust integrations.
Robust integrations handle errors gracefully. The DALP API returns structured errors with machine-readable codes, enabling your application to respond appropriately—whether that means fixing the request, retrying with backoff, or surfacing a clear message to users.
This guide covers all API error codes, when to retry, and implementation patterns for resilient error handling.
Error response format
All API errors follow a consistent JSON structure:
{
"code": "USER_NOT_AUTHORIZED",
"status": 403,
"message": "User does not have the required role to execute this action.",
"data": {
"requiredRoles": ["SUPPLY_MANAGEMENT_ROLE"]
}
}| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error identifier (SCREAMING_SNAKE_CASE) |
status | number | HTTP status code |
message | string | Human-readable error description |
data | object? | Optional additional context (varies by error type) |
The data field provides error-specific details. For example, USER_NOT_AUTHORIZED includes requiredRoles, while INPUT_VALIDATION_FAILED includes an errors array.
Quick reference
| Code | Status | Retry? | Action |
|---|---|---|---|
BAD_REQUEST | 400 | No | Fix request payload |
UNAUTHORIZED | 401 | No | Reauthenticate |
FORBIDDEN | 403 | No | Check role permissions |
NOT_ONBOARDED | 403 | No | Complete user onboarding |
SYSTEM_NOT_CREATED | 403 | No | Initialize platform first |
USER_NOT_AUTHORIZED | 403 | No | Request required role |
NOT_FOUND | 404 | No | Verify resource exists |
CONFLICT | 409 | No | Resolve state conflict |
RESOURCE_ALREADY_EXISTS | 409 | No | Use existing resource |
INPUT_VALIDATION_FAILED | 422 | No | Fix validation errors |
TOKEN_INTERFACE_NOT_SUPPORTED | 422 | No | Use compatible token contract |
INTERNAL_SERVER_ERROR | 500 | Yes | Retry with exponential backoff; contact support if persistent |
CONFIRMATION_TIMEOUT | 504 | No | Check transaction status before retrying |
Retry decision flowchart
Use this flowchart to determine whether to retry a failed request:
Key principles:
- 4xx errors: Never retry. The request itself is invalid—fix the underlying issue first.
- 5xx errors: Retry with exponential backoff, unless it's a blockchain revert.
- Blockchain reverts: Check the revert reason—retrying won't help if the underlying issue persists.
Client errors (4xx)
Client errors indicate problems with the request itself. Retrying the same request will produce the same error. Fix the underlying issue before retrying.
Authentication errors (401)
UNAUTHORIZED
Authentication is missing or invalid. The API key may be expired, revoked, or malformed.
- Verify the API key includes the
sm_dalp_prefix - Check the key hasn't been deleted in the API Keys page
- Confirm the
X-Api-Keyheader is set correctly
Authorization errors (403)
FORBIDDEN
The authenticated user lacks permission for this operation.
- Review the user's assigned roles
- Check if the operation requires admin or system-level permissions
- See Platform setup for role management
NOT_ONBOARDED
The user hasn't completed the onboarding process.
- Direct the user to complete onboarding in the platform UI
- Onboarding includes profile setup and wallet configuration
- See User onboarding for the complete flow
SYSTEM_NOT_CREATED
The DALP platform hasn't been initialized. This occurs when accessing a fresh deployment before the first admin completes setup.
- Follow the First admin setup guide
USER_NOT_AUTHORIZED
The user lacks the specific role required for this token operation.
The data.requiredRoles field lists what's needed (e.g., SUPPLY_MANAGEMENT_ROLE, USER_MANAGEMENT_ROLE).
- Check Asset admin roles for role assignment
Resource errors (404, 409)
NOT_FOUND
The requested resource doesn't exist.
- Verify the resource ID or address is correct
- Check if the resource was deleted
- Confirm the API path is correct (include
/apisuffix in base URL)
CONFLICT
The operation conflicts with the current system state.
- Check if another operation is in progress
- Verify the resource state hasn't changed since your last read
RESOURCE_ALREADY_EXISTS
Attempted to create a resource that already exists.
- Query for the existing resource instead of creating
- Use a unique identifier if creating a new resource
Validation errors (422)
INPUT_VALIDATION_FAILED
Request data failed schema validation. The data.errors array lists specific issues.
{
"code": "INPUT_VALIDATION_FAILED",
"status": 422,
"message": "Input validation failed",
"data": {
"errors": ["amount: Expected positive number, received -100", "recipient: Invalid Ethereum address"]
}
}Review each error and fix the corresponding field in your request.
TOKEN_INTERFACE_NOT_SUPPORTED
The token contract at the specified address doesn't implement the required interface.
The data.requiredInterfaces field lists the missing interfaces (e.g., ERC20, IYieldSchedule).
- Verify you're using the correct token address
- Check if the token type supports the requested operation
Server errors (5xx)
Server errors indicate temporary problems. Most can be resolved by retrying with exponential backoff.
General server errors (500)
INTERNAL_SERVER_ERROR
An unexpected error occurred on the server.
- Retry with exponential backoff (1s, 2s, 4s delays)
- Maximum 3 retry attempts
- If errors persist, contact support with the request details
Timeout errors (504)
CONFIRMATION_TIMEOUT
A blockchain transaction was submitted but confirmation timed out. The transaction may still succeed—do not retry the original API call.
Do not retry the original request—this may create duplicate transactions. Check the transaction status first to determine whether to retry.
- The
data.transactionHashfield in the error contains the transaction hash - Query
GET /api/transaction/{transactionHash}to check if the transaction succeeded, reverted, or was never submitted - See Transaction tracking for the full timeout recovery flow
Blockchain transaction errors
When a blockchain transaction reverts, the API returns the revert information in the error details. Revert reasons come directly from smart contract custom errors.
Important: Blockchain reverts should not be retried without fixing the underlying issue. The same transaction will revert again.
Common revert reasons
These errors occur frequently during normal operations and typically require user action or data correction.
Balance and supply errors
| Error | Description | Resolution |
|---|---|---|
InsufficientTokenBalance | Account lacks sufficient token balance | Query balance before retrying; ensure user has enough tokens |
ExceededCap | Minting would exceed the token's supply cap | Reduce mint amount or increase cap (if authorized) |
InsufficientCollateral | Insufficient collateral backing for mint operation | Add more collateral before minting |
Permission and authorization errors
| Error | Description | Resolution |
|---|---|---|
AccessControlUnauthorizedAccount | Account lacks the required role for this operation | Grant the required role to the account |
TransferNotCompliant | Transfer failed compliance checks | Verify both parties meet compliance requirements |
MintNotCompliant | Mint operation failed compliance checks | Verify recipient meets compliance requirements |
RecipientNotVerified | Recipient doesn't meet identity verification requirements | Complete identity verification for recipient |
ApprovalRequired | Transfer requires pre-approval from authorized party | Request transfer approval before executing |
Token state errors
| Error | Description | Resolution |
|---|---|---|
TokenPaused | Token operations are paused by admin | Wait for admin to unpause the token |
SenderAddressFrozen | Sender's address is frozen | Contact admin to unfreeze the address |
RecipientAddressFrozen | Recipient's address is frozen | Contact admin to unfreeze the address |
Identity and compliance errors
| Error | Description | Resolution |
|---|---|---|
IdentityNotRegistered | User's identity is not registered in the system | Register identity through onboarding flow |
IdentityAlreadyRegistered | Identity already exists for this user | Use existing identity instead of creating new |
ComplianceCheckFailed | Generic compliance check failure | Review compliance requirements for the operation |
Validation errors
| Error | Description | Resolution |
|---|---|---|
ZeroAddressNotAllowed | Zero address provided where non-zero required | Provide a valid non-zero address |
LengthMismatch | Array lengths don't match in batch operations | Ensure all arrays have equal length |
InvalidDecimals | Token decimals value is invalid (typically >18) | Use valid decimals value (0-18) |
Retry strategies
Exponential backoff
For 5xx errors (except blockchain reverts), use exponential backoff:
| Attempt | Wait time |
|---|---|
| 1 | 1 second |
| 2 | 2 seconds |
| 3 | 4 seconds |
| 4+ | Fail |
Add jitter (random 0-500ms) to prevent thundering herd problems when multiple clients retry simultaneously.
Transaction confirmation
For operations that submit blockchain transactions:
- The API polls for confirmation automatically
- If
CONFIRMATION_TIMEOUToccurs, do not retry the original request - Query
GET /api/transaction/{transactionHash}to check if the transaction was processed - The transaction hash (available in
X-Transaction-Hashresponse header or error response) can be used to verify on-chain status - Only submit a new request after confirming the original transaction failed
Multi-transaction operations: Some API calls trigger multiple blockchain transactions (e.g., system creation with compliance modules). The X-Transaction-Hash header contains all transaction hashes as a comma-separated list, ordered by execution sequence. If a timeout occurs, it applies to the last hash—all preceding transactions completed successfully.
See Transaction tracking for detailed polling patterns and response interpretation.
Best practices
Log errors with context
Include the error code, request path, and relevant IDs in your logs. This enables faster debugging when issues occur in production.
Set reasonable timeouts
Configure client timeouts appropriate for the operation type:
- Read operations: 10-30 seconds
- Write operations: 60-90 seconds (blockchain transactions take time)
Fail fast on client errors
Don't retry 4xx errors. Surface them to users or fix them programmatically. Retrying wastes resources and delays the actual fix.
Circuit breaker for repeated failures
If a specific endpoint fails repeatedly (5+ times in a minute), pause requests to that endpoint temporarily. This prevents cascading failures and allows the service to recover.
Idempotency for critical operations
For financial operations, ensure your integration can handle duplicate responses safely. Network issues may cause a successful request to appear failed, leading to retry attempts on already-completed operations.
Next steps
- Getting started – Set up API authentication
- Token lifecycle – Understand operation flows
- API reference – Complete endpoint documentation