Errors
How the Signkoi API reports errors: HTTP status codes, error types, stable error codes and request ids.
Successful requests return 2xx. Anything else returns the same JSON error object, so you can always branch on error.type and error.code.
The error object
422 · application/json
{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "The recipients.0.email field must be a valid email address.",
"param": "recipients.0.email",
"errors": {
"recipients.0.email": ["The recipients.0.email field must be a valid email address."]
},
"request_id": "0f6c8f5e-2b1d-4c3a-9e7f-5a8b1c2d3e4f"
}
}HTTP status codes
Error types
Error codes
Authentication and access
Requests
Files (creating envelopes)
For file errors param is file, files, files.N or files.N.content_base64, so you know which file failed.
Envelope state
Sending
Plans, limits and our side
Handling errors
- 4xx errors mean the request needs to change — don’t retry them unchanged. The one exception is
429. - 429 and 5xx are safe to retry with exponential backoff. Send POST requests with an Idempotency-Key so a retry never creates a second envelope.
- Log the request_id of every failed request.
Branching on error.type
const res = await fetch(url, options);
if (!res.ok) {
const { error } = await res.json();
switch (error.type) {
case 'rate_limit_error':
// Wait for Retry-After seconds, then retry.
break;
case 'api_error':
// Our side: retry with backoff, reusing the same Idempotency-Key.
break;
case 'billing_error':
// plan_limit: ask the account owner to upgrade.
break;
default:
// invalid_request_error, conflict_error, permission_error, authentication_error:
// fix the request; don't retry it unchanged.
console.error(error.code, error.param, error.message, error.request_id);
}
}404 instead of 403
To avoid revealing what exists, the API answers 404 resource_missing for resources that belong to someone else.