Error Reference
Understanding API errors and how to handle them.
| Error Code | Description | How to Fix |
|---|---|---|
| unauthorized | You are not authenticated or don't have permission | Ensure you're using a valid API key and are signed in |
| notAuthorized | Your identity does not have admin access for this operation | This action requires admin privileges. Only the canister admin can perform this operation. |
| userDisabled | Your account has been permanently disabled | Contact hey@vanishd.io to appeal |
| userFrozen | Your account is temporarily frozen for investigation | You can view data but not create new items. Contact hey@vanishd.io |
| invalidApiKey | The API key provided is invalid or has been revoked | Check the key is correct. Create a new key if needed |
| invalidCredentialHash | The credential hash is not valid (must be 32-byte SHA-256) | Ensure you're hashing with SHA-256 and sending 32 bytes |
| invalidMetadataSize | Metadata exceeds the 16KB limit | Reduce your metadata size to under 16KB |
| invalidInput | A parameter is invalid (message includes details) | Check the error message for specifics |
| usageLimitExceeded | You've exceeded your monthly receipt quota | Upgrade your plan or wait for next billing period |
| rateLimited | Too many requests in a short period | Wait a moment and retry. Implement exponential backoff |
| tierChangeCooldown | 24-hour cooldown between tier changes not elapsed | Wait until cooldown expires or contact support |
| receiptNotFound | The requested receipt ID doesn't exist | Verify the receipt ID is correct |
| batchNotFound | The Merkle batch doesn't exist | The batch may not be anchored yet. Try again later |
| idempotencyConflict | A receipt with this idempotency key already exists | This is expected for duplicate requests. Use the existing receipt |
| internalError | An unexpected error occurred | Retry the request. If persistent, contact support |
Handling Errors in Code
// Example error handling
const result = await actor.certify(apiKey, request);
if ('err' in result) {
const error = result.err;
if ('usageLimitExceeded' in error) {
// Prompt user to upgrade or wait
showUpgradeModal();
} else if ('rateLimited' in error) {
// Implement retry with backoff
await sleep(2000);
return retry(request);
} else if ('userFrozen' in error) {
// Show account status message
showFrozenNotice();
} else if ('invalidApiKey' in error) {
// API key issue - prompt to create new one
redirectToApiKeys();
} else {
// Handle other errors
console.error('Unexpected error:', error);
}
}
if ('ok' in result) {
// Success - save the receipt
saveReceipt(result.ok);
}Best Practices
- Always check for errors: The API returns
Result<T, Error>- handle both cases - Implement retry logic: For
rateLimitedand transient errors, use exponential backoff - Monitor usage: Track your receipt count to avoid hitting limits unexpectedly
- Use idempotency keys: Prevent duplicate receipts when retrying failed requests
- Log errors: Keep logs for debugging and support requests
Need Help?
If you're encountering errors you can't resolve, reach out for assistance.