Skip to content

Errors

The inSigner API uses RFC 9457 Problem Details for all error responses. This provides a consistent, machine-readable format across every endpoint.

All errors return a JSON body with Content-Type: application/problem+json:

{
"type": "https://docs.insigner.com/errors/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "The request body contains invalid fields",
"errors": [
{ "field": "email", "message": "Invalid email" },
{ "field": "name", "message": "Required" }
]
}
FieldTypeDescription
typestringA URI identifying the error type. Use this for programmatic handling.
titlestringShort human-readable summary (e.g. “Not Found”).
statusnumberHTTP status code.
detailstringDetailed explanation for this specific error.
errorsarray(Optional) Field-level validation errors with field and message.

Every error response also includes an X-Request-Id header for support and debugging.

StatusMeaningWhen it happens
400Bad RequestMalformed JSON or invalid request format
401UnauthorizedMissing, invalid, revoked, or expired API key
403ForbiddenAPI key lacks the required scope
404Not FoundResource doesn’t exist or doesn’t belong to your organization
409ConflictAction not allowed in current state (e.g. deleting a pending document)
422Validation ErrorRequest body failed schema validation
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error
502Bad GatewayUpstream service failure (e.g. email delivery)
Type URIStatusDescription
https://docs.insigner.com/errors/unauthorized401Invalid or missing API key
https://docs.insigner.com/errors/forbidden403Insufficient permissions for this resource
https://docs.insigner.com/errors/not-found404Resource not found
https://docs.insigner.com/errors/conflict409Action conflicts with current resource state
https://docs.insigner.com/errors/validation-error422Request body validation failed
https://docs.insigner.com/errors/rate-limited429Rate limit exceeded
https://docs.insigner.com/errors/email-failed502Email delivery failed
https://docs.insigner.com/errors/internal500Unexpected internal error
{
"type": "https://docs.insigner.com/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid API key"
}
{
"type": "https://docs.insigner.com/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Document not found"
}
{
"type": "https://docs.insigner.com/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "Cannot delete a document that is pending signing. Cancel it first."
}
{
"type": "https://docs.insigner.com/errors/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "The request body contains invalid fields",
"errors": [
{ "field": "name", "message": "String must contain at least 1 character(s)" },
{ "field": "expiresAt", "message": "Expiration date must be in the future" }
]
}

Includes a Retry-After header with seconds until the limit resets.

{
"type": "https://docs.insigner.com/errors/rate-limited",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Please retry after the reset period."
}
const res = await fetch('https://app.insigner.co/api/v1/documents', {
headers: { 'Authorization': 'Bearer isk_YOUR_API_KEY' }
});
if (!res.ok) {
const error = await res.json();
switch (error.type) {
case 'https://docs.insigner.com/errors/rate-limited':
const retryAfter = res.headers.get('Retry-After');
await sleep(retryAfter * 1000);
// Retry the request...
break;
case 'https://docs.insigner.com/errors/unauthorized':
console.error('Check your API key');
break;
default:
console.error(`${error.title}: ${error.detail}`);
}
}