API Reference¶
Language Notice
This page is only available in English.
Introduction¶
The VoidSign API lets you create signature requests, track their status, and download signed documents and audit trails programmatically. It follows REST conventions: resource-oriented URLs, standard HTTP methods, and JSON-encoded request and response bodies. Use it to integrate e-signature workflows directly into your application.
Authentication
Every request must include a valid API key in the X-VoidSign-Key header. You can create and manage your API keys from your VoidSign Dashboard.
Content-Type
All request and response bodies are encoded as JSON (application/json) unless explicitly stated otherwise.
Data Types¶
The API uses standard JSON types. Some string fields carry a format qualifier shown in parentheses in the schema tables:
| Format | Description | Example |
|---|---|---|
date-time |
ISO 8601 timestamp in UTC. Always includes a UTC offset. | 2025-01-15T14:30:00+00:00 |
email |
RFC 5322 email address. | jean.dupont@example.com |
Errors¶
All errors follow a unified format with a top-level error object containing code and message fields. Some errors also include a details array. See the Errors Table for the full list of error codes and examples.
Rate Limits¶
The API enforces a token-bucket rate limit of 60 requests per minute per API key. Every response includes standard RateLimit-* headers. When the limit is exceeded, the API returns a 429 error with a Retry-After header. For full details, see the Rate Limit Headers & Policy.
Update Policy¶
The API evolves in non-breaking ways for existing integrations. For details on what this means and how to stay informed about improvements, see the API Evolution Policy.
Getting Started¶
For a step-by-step walkthrough of creating your first signature request, see the Getting Started tutorial.
Create request¶
POST /api/v1/requests
Upload a PDF document with positioned fields and send signature invitations to the specified signers. Each signer receives an email with a link to sign the document.
curl
curl -X POST \
"https://api.voidsign.com/api/v1/requests" \
-H "X-VoidSign-Key: vs_live_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_method": "mail",
"description": "Service agreement Q1 2025",
"documents": [
{
"base64": "JVBERi0xLjQg...",
"fields": [
{
"box_coordinate_system": "CS-ULP-GD",
"box_height_ratio": 0.1,
"box_width_ratio": 0.3,
"box_x_ratio": 0.15,
"box_y_ratio": 0.7,
"page_number": 0,
"signer_ref": 1,
"type": "signature"
}
]
}
],
"invitation_mode": "voidsign_mail",
"locales": [
"fr-FR"
],
"signers": [
{
"email": "jean.dupont@example.com",
"first_name": "Jean",
"last_name": "Dupont",
"ref": 1,
"reminder_days": [
3,
7
]
}
]
}'
Request body¶
Schema: CreateRequestBody
| Field | Type | Required | Description |
|---|---|---|---|
documents |
array[ApiDocument] | Required | List of documents. Currently limited to exactly one document. |
signers |
array[ApiSigner] | Required | List of signers (1–24). Each signer receives an email invitation. |
description |
string | null |
Optional description for the signature request. | |
auth_method |
"mail" |
Required | Authentication method for signers. Currently only "mail" is supported (email-based verification). |
invitation_mode |
"voidsign_mail" |
Required | How participants receive their signing invitation. Currently only "voidsign_mail" is supported (VoidSign sends invitation emails). |
locales |
array["fr-FR"] |
Required | Languages available in the signing interface. Currently only ["fr-FR"] (French) is supported. |
locale_default |
"fr-FR" | null |
Default language for the signing interface. Required when locales contains more than one entry. Must be a value present in locales. |
Request Body Example
{
"auth_method": "mail",
"description": "Service agreement Q1 2025",
"documents": [
{
"base64": "JVBERi0xLjQg...",
"fields": [
{
"box_coordinate_system": "CS-ULP-GD",
"box_height_ratio": 0.1,
"box_width_ratio": 0.3,
"box_x_ratio": 0.15,
"box_y_ratio": 0.7,
"page_number": 0,
"signer_ref": 1,
"type": "signature"
}
]
}
],
"invitation_mode": "voidsign_mail",
"locales": [
"fr-FR"
],
"signers": [
{
"email": "jean.dupont@example.com",
"first_name": "Jean",
"last_name": "Dupont",
"ref": 1,
"reminder_days": [
3,
7
]
}
]
}
Explicit over implicit
Some parameters like auth_method, invitation_mode, and locales currently accept only one value.
They are mandatory by design: when new options become available (e.g., SMS authentication,
self-managed invitations, additional locales), existing integrations will continue working without
breaking changes. We prefer requiring these parameters early to ensure explicit behavior rather
than implicit behavior.
Responses¶
| Status | Description | Schema |
|---|---|---|
201 |
Successful Response | CreateRequestResponse |
401 |
Missing or invalid API key. | |
403 |
API key does not have permission for this operation. | |
422 |
Validation error (invalid base64, invalid PDF, duplicate signer refs, unknown signer_ref in field, PDF too large, page number out of bounds, date fields in multi-signer requests, conflicting signer info, telephone not yet supported). | |
429 |
Rate limit exceeded. | |
500 |
Internal server error (company not found, email sending failure). |
201 Response example
Get request status¶
GET /api/v1/requests/{request_id}
Retrieve the current status of a signature request, including per-signer details and timestamps.
curl
Parameters¶
| Name | In | Type | Required | Description |
|---|---|---|---|---|
request_id |
path | string |
Required | Unique identifier of the signature request. |
Responses¶
| Status | Description | Schema |
|---|---|---|
200 |
Successful Response | GetRequestResponse |
401 |
Missing or invalid API key. | |
403 |
Signature request belongs to a different company. | |
404 |
Signature request not found. | |
429 |
Rate limit exceeded. | |
422 |
Validation Error |
200 Response example
{
"created_at": "2025-01-15T10:00:00Z",
"description": "Service agreement Q1 2025",
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"signed_at": null,
"signers": [
{
"email": "jean.dupont@example.com",
"first_name": "Jean",
"last_name": "Dupont",
"signed_at": "2025-01-15T14:30:00Z",
"status": "signed"
}
],
"status": "created"
}
Download signed PDF¶
GET /api/v1/requests/{request_id}/downloads/signed
Download the final signed PDF document. The request must be fully signed (all signers have completed).
curl
Parameters¶
| Name | In | Type | Required | Description |
|---|---|---|---|---|
request_id |
path | string |
Required | Unique identifier of the signature request. |
Responses¶
| Status | Description | Schema |
|---|---|---|
200 |
Successful Response | |
400 |
Signature request is not fully signed yet. | |
401 |
Missing or invalid API key. | |
403 |
Signature request belongs to a different company. | |
404 |
Signature request or signed file not found. | |
429 |
Rate limit exceeded. | |
422 |
Validation Error |
200 Response
The response body contains the raw signed PDF file (application/pdf). Use the Content-Disposition header for the suggested filename.
400 Response example
Download audit trail¶
GET /api/v1/requests/{request_id}/downloads/audit-trail/{format}
Download the audit trail for a fully signed request. Available in JSON or PDF format.
curl
Parameters¶
| Name | In | Type | Required | Description |
|---|---|---|---|---|
request_id |
path | string |
Required | Unique identifier of the signature request. |
format |
path | string |
Required | Output format: json or pdf. |
Responses¶
| Status | Description | Schema |
|---|---|---|
200 |
Successful Response | |
400 |
Signature request is not fully signed yet. | |
401 |
Missing or invalid API key. | |
403 |
Signature request belongs to a different company. | |
404 |
Signature request not found. | |
429 |
Rate limit exceeded. | |
422 |
Validation Error |
200 Response
The response body contains the audit trail file. Format depends on the format path parameter: application/json for JSON, application/pdf for PDF.
400 Response example
Annex¶
Schemas¶
CreateRequestBody¶
| Field | Type | Required | Description |
|---|---|---|---|
documents |
array[ApiDocument] | Required | List of documents. Currently limited to exactly one document. |
signers |
array[ApiSigner] | Required | List of signers (1–24). Each signer receives an email invitation. |
description |
string | null |
Optional description for the signature request. | |
auth_method |
"mail" |
Required | Authentication method for signers. Currently only "mail" is supported (email-based verification). |
invitation_mode |
"voidsign_mail" |
Required | How participants receive their signing invitation. Currently only "voidsign_mail" is supported (VoidSign sends invitation emails). |
locales |
array["fr-FR"] |
Required | Languages available in the signing interface. Currently only ["fr-FR"] (French) is supported. |
locale_default |
"fr-FR" | null |
Default language for the signing interface. Required when locales contains more than one entry. Must be a value present in locales. |
Used by: create-request
ApiDocument¶
| Field | Type | Required | Description |
|---|---|---|---|
base64 |
string |
Required | Base64-encoded PDF content. Maximum decoded size: 3 MB. |
fields |
array[ApiSfieldSignature | ApiSfieldText | ApiSfieldParaph | ApiSfieldDate] | Required | List of fields (signature, paraph, text, date) to place on the document. |
Used by: create-request
ApiSfieldSignature¶
Signature field positioned using the CS-ULP-GD coordinate system (upper-left point + given dimensions).
| Field | Type | Required | Description |
|---|---|---|---|
type |
"signature" |
Required | Field type. Must be signature. |
box_coordinate_system |
"CS-ULP-GD" |
Required | Coordinate system. Must be CS-ULP-GD (upper-left point + given dimensions). |
box_x_ratio |
number (0–1) |
Required | X position of the upper-left corner as a ratio (0.0-1.0) of page width. |
box_y_ratio |
number (0–1) |
Required | Y position of the upper-left corner as a ratio (0.0-1.0) of page height. |
box_width_ratio |
number (0–1) |
Required | Width of the signature box as a ratio (0.0-1.0) of page width. |
box_height_ratio |
number (0–1) |
Required | Height of the signature box as a ratio (0.0-1.0) of page height. |
page_number |
integer | "all" |
Required | Zero-based page number, or "all" to place on every page. |
signer_ref |
integer |
Required | Reference number of the signer who must sign this field. Must match a signer ref in the request. |
Used by: create-request
ApiSfieldText¶
Static text field positioned using the CS-CP-AD coordinate system (center point + auto-derived dimensions).
| Field | Type | Required | Description |
|---|---|---|---|
type |
"text" |
Required | Field type. Must be text. |
box_coordinate_system |
"CS-CP-AD" |
Required | Coordinate system. Must be CS-CP-AD (center point + auto-derived dimensions). |
box_center_x_ratio |
number (0–1) |
Required | X position of the center point as a ratio (0.0-1.0) of page width. |
box_center_y_ratio |
number (0–1) |
Required | Y position of the center point as a ratio (0.0-1.0) of page height. |
page_number |
integer |
Required | Zero-based page number where the field is placed. |
text |
string |
Required | Text content to display in the field. |
font_size |
number |
Required | Font size in points. |
Used by: create-request
ApiSfieldParaph¶
Paraph (initials) field positioned using the CS-CP-AD coordinate system (center point + auto-derived dimensions).
| Field | Type | Required | Description |
|---|---|---|---|
type |
"paraph" |
Required | Field type. Must be paraph. |
box_coordinate_system |
"CS-CP-AD" |
Required | Coordinate system. Must be CS-CP-AD (center point + auto-derived dimensions). |
box_center_x_ratio |
number (0–1) |
Required | X position of the center point as a ratio (0.0-1.0) of page width. |
box_center_y_ratio |
number (0–1) |
Required | Y position of the center point as a ratio (0.0-1.0) of page height. |
page_number |
integer | "all" |
Required | Zero-based page number, or "all" to place on every page. |
signer_ref |
integer |
Required | Reference number of the signer who must initial this field. Must match a signer ref in the request. |
font_size |
number |
Required | Font size in points. |
Used by: create-request
ApiSfieldDate¶
Automatic date field positioned using the CS-CP-AD coordinate system (center point + auto-derived dimensions).
| Field | Type | Required | Description |
|---|---|---|---|
type |
"date" |
Required | Field type. Must be date. |
box_coordinate_system |
"CS-CP-AD" |
Required | Coordinate system. Must be CS-CP-AD (center point + auto-derived dimensions). |
box_center_x_ratio |
number (0–1) |
Required | X position of the center point as a ratio (0.0-1.0) of page width. |
box_center_y_ratio |
number (0–1) |
Required | Y position of the center point as a ratio (0.0-1.0) of page height. |
page_number |
integer |
Required | Zero-based page number where the field is placed. |
font_size |
number |
Required | Font size in points. |
Used by: create-request
ApiSigner¶
| Field | Type | Required | Description |
|---|---|---|---|
ref |
integer |
Required | Reference number for this signer within the request. Used by signature/paraph fields to indicate which signer they belong to. |
email |
string (email) |
Required | Email address of the signer. An invitation will be sent to this address. |
first_name |
string |
Required | First name of the signer. |
last_name |
string |
Required | Last name of the signer. |
telephone |
string | null |
Personal mobile phone number in E.164 format. Only French mobile numbers are accepted (+336… or +337…, e.g. +33612345678). Reserved for future use; providing a value will return a 422 error. | |
reminder_days |
array[integer] | null |
Days after creation to send reminder emails. Example: [3, 7] sends reminders on day 3 and day 7. |
Used by: create-request
CreateRequestResponse¶
| Field | Type | Required | Description |
|---|---|---|---|
request_id |
string |
Required | Unique identifier for the created signature request. |
status |
"created" |
Required | Status of the request. Always created on success. |
signers |
array[SignerStatusResponse] | Required | List of signers with their initial status. |
Used by: create-request
SignerStatusResponse¶
| Field | Type | Required | Description |
|---|---|---|---|
email |
string (email) |
Required | Email address of the signer. |
status |
string |
Required | Current signing status. |
Used by: create-request
GetRequestResponse¶
| Field | Type | Required | Description |
|---|---|---|---|
request_id |
string |
Required | Unique identifier of the signature request. |
status |
string |
Required | Overall request status. |
description |
string | null |
Required | Description provided when creating the request. |
created_at |
string (date-time) | null |
Required | ISO 8601 UTC timestamp when the request was created. |
signed_at |
string (date-time) | null |
Required | ISO 8601 UTC timestamp when all signers completed, or null. |
signers |
array[GetRequestSignerResponse] | Required | List of signers with their detailed status. |
Used by: get-request-status
GetRequestSignerResponse¶
| Field | Type | Required | Description |
|---|---|---|---|
email |
string (email) |
Required | Email address of the signer. |
first_name |
string |
Required | First name of the signer. |
last_name |
string |
Required | Last name of the signer. |
status |
string |
Required | Signing status. |
signed_at |
string (date-time) | null |
Required | ISO 8601 UTC timestamp when the signer signed, or null if not yet signed. |
Used by: get-request-status
Errors Table¶
All API errors share a consistent JSON envelope:
Request errors (400/404): business-logic and resource errors:
Authentication errors (401/403): missing, invalid, or unauthorized API key:
Validation errors (422): request body failed schema validation:
{
"error": {
"code": "invalid_request",
"message": "Request body failed validation",
"details": [
{
"field": "signers[0].email",
"message": "Value is not a valid email address"
}
]
}
}
Server errors (500): unexpected internal failures:
400: Bad Request¶
| Code | Default message |
|---|---|
not_signed |
Signature request is not fully signed yet |
401: Unauthorized¶
| Code | Default message |
|---|---|
missing_api_key |
Missing API key |
invalid_api_key |
Invalid API key |
api_key_revoked |
API key has been revoked |
403: Forbidden¶
| Code | Default message |
|---|---|
api_feature_disabled |
API feature is not enabled for this company |
not_owned_resource |
Signature request belongs to a different company |
404: Not Found¶
| Code | Default message |
|---|---|
signature_request_not_found |
Signature request not found |
signed_pdf_not_found |
Signed PDF not found |
422: Validation Error¶
| Code | Default message |
|---|---|
invalid_request |
Invalid request |
invalid_base64 |
Invalid base64 encoding for document |
invalid_pdf |
Document is not a valid PDF |
pdf_too_large |
PDF exceeds maximum allowed size |
duplicate_signer_refs |
Duplicate signer refs |
invalid_signer_refs |
Signer refs are out of valid range |
conflicting_signer_info |
Same signer email appears multiple times with different contact information |
signer_info_mismatch |
A signer with this email already exists with different contact information |
telephone_not_supported |
The telephone field is not yet supported |
unknown_signer_ref |
Field references an unknown signer ref |
signer_field_mismatch |
Signer and field identifiers do not match |
date_field_multi_signer |
Date fields are not supported in multi-signer requests |
page_number_out_of_bounds |
Field page number exceeds document page count |
invalid_locale_default |
locale_default is required when locales contains more than one entry, and must be a value present in locales |
500: Server Error¶
| Code | Default message |
|---|---|
company_not_found |
Company not found for this API key |
email_send_error |
Failed to send signature invite emails |
What's Next¶
Now that you're familiar with the API surface, here are some useful next steps:
- Getting Started tutorial: step-by-step walkthrough of your first signature request.
- Set Up Webhooks: receive real-time notifications when signature requests change status.
- API Evolution Policy: stay informed about new endpoints, fields, and improvements.
API Updates
The VoidSign API evolves in non-breaking ways. Your existing integration will keep working as we add new capabilities. See the API Evolution Policy to learn more.