Errors
The inSigner API uses RFC 9457 Problem Details for all error responses. This provides a consistent, machine-readable format across every endpoint.
Error response format
Section titled “Error response format”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" } ]}| Field | Type | Description |
|---|---|---|
type | string | A URI identifying the error type. Use this for programmatic handling. |
title | string | Short human-readable summary (e.g. “Not Found”). |
status | number | HTTP status code. |
detail | string | Detailed explanation for this specific error. |
errors | array | (Optional) Field-level validation errors with field and message. |
Every error response also includes an X-Request-Id header for support and debugging.
HTTP status codes
Section titled “HTTP status codes”| Status | Meaning | When it happens |
|---|---|---|
400 | Bad Request | Malformed JSON or invalid request format |
401 | Unauthorized | Missing, invalid, revoked, or expired API key |
403 | Forbidden | API key lacks the required scope |
404 | Not Found | Resource doesn’t exist or doesn’t belong to your organization |
409 | Conflict | Action not allowed in current state (e.g. deleting a pending document) |
422 | Validation Error | Request body failed schema validation |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected server error |
502 | Bad Gateway | Upstream service failure (e.g. email delivery) |
Error type reference
Section titled “Error type reference”| Type URI | Status | Description |
|---|---|---|
https://docs.insigner.com/errors/unauthorized | 401 | Invalid or missing API key |
https://docs.insigner.com/errors/forbidden | 403 | Insufficient permissions for this resource |
https://docs.insigner.com/errors/not-found | 404 | Resource not found |
https://docs.insigner.com/errors/conflict | 409 | Action conflicts with current resource state |
https://docs.insigner.com/errors/validation-error | 422 | Request body validation failed |
https://docs.insigner.com/errors/rate-limited | 429 | Rate limit exceeded |
https://docs.insigner.com/errors/email-failed | 502 | Email delivery failed |
https://docs.insigner.com/errors/internal | 500 | Unexpected internal error |
Example error responses
Section titled “Example error responses”401 Unauthorized
Section titled “401 Unauthorized”{ "type": "https://docs.insigner.com/errors/unauthorized", "title": "Unauthorized", "status": 401, "detail": "Invalid API key"}404 Not Found
Section titled “404 Not Found”{ "type": "https://docs.insigner.com/errors/not-found", "title": "Not Found", "status": 404, "detail": "Document not found"}409 Conflict
Section titled “409 Conflict”{ "type": "https://docs.insigner.com/errors/conflict", "title": "Conflict", "status": 409, "detail": "Cannot delete a document that is pending signing. Cancel it first."}422 Validation Error
Section titled “422 Validation Error”{ "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" } ]}429 Rate Limited
Section titled “429 Rate Limited”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."}Handling errors
Section titled “Handling errors”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}`); }}