API Documentation
Table of Contents
Official SDKs
eSignBase provides official SDKs for various programming languages. These simplify integration with our REST API by handling authentication, request management, and error handling. The SDKs are optional – you can, of course, work directly with the REST API as well.
Python
- Source & Issues: GitHub - esignbase-python-sdk
- Package: PyPI - esignbase-sdk
Installation:
pip install esignbase-sdk
Node.js
- Source & Issues: GitHub - esignbase-node-sdk
- Package: npm - esignbase-sdk
Installation:
npm install esignbase-sdk
Note: The Node.js SDK requires Node.js version 18 or higher.
General Information
All dates in this documentation follow the ISO 8601 format: YYYY-MM-DDTHH:MM:SS+00:00.
For example: 2025-08-25T13:49:00+00:00.
IDs such as the document ID or template ID are currently UUIDs. However, we recommend not relying on any specific format and treating them simply as unique strings.
If you’re looking for a step-by-step example, check out our guide: How to Create and Sign a Document using the eSignBase REST API.
Authentication
The eSignBase API uses OAuth2 for authentication. Two grant types are supported depending on your use case:
| Grant Type | Use Case |
|---|---|
| Client Credentials | Server-to-server integrations where you control both sides. Simpler to implement. |
| Authorization Code | Third-party integrations (e.g. Zapier, Make) where your app acts on behalf of an eSignBase user. |
In both cases, every API call must include the access token in the request header:
Authorization: Bearer <your_access_token>
Client Credentials Grant
Best suited for direct API integrations where you own the eSignBase account being accessed.
How to get an Access Token
First, retrieve your Client ID and Client Secret at https://app.esignbase.com/oauth2/client by creating an OAuth2 Client.
Next, base64-encode the concatenation of the Client ID and Client Secret, separated by a colon (:):
basic_auth_credentials = base64(client_id + ":" + client_secret)
Request:
POST /oauth2/token
Headers:
Authorization: Basic <basic_auth_credentials>
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
grant_type=client_credentials&scope=all
Available scopes:
| Scope | Description |
|---|---|
all | Full access (read, create, delete). Does not include sandbox. |
read | Read documents and templates. |
create_document | Create and send documents for signature. |
delete | Delete documents. |
sandbox | Sandbox mode — no credits consumed, uses sandbox templates only. |
You can request multiple scopes by providing a space-separated list:
grant_type=client_credentials&scope=all sandbox
Response:
{ "access_token": "<your_access_token>" }
Access tokens are valid for 5 minutes, after which a new one must be retrieved.
Revoke an Access Token
Request:
POST /oauth2/revoke
Headers:
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
token=<your_access_token>
Authorization Code Grant
Use this grant type when building third-party integrations where your application acts on behalf of an eSignBase user — for example when building a Zapier or Make integration. The user logs in to eSignBase and explicitly approves access; your application never handles their password.
Before using this flow, register your OAuth2 client at https://app.esignbase.com/oauth2/client and add your redirect URI to the allowed list.
Step 1: Redirect the User to the Authorization Endpoint
Redirect the user’s browser to:
GET https://app.esignbase.com/oauth2/authorize
With the following query parameters:
| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Your OAuth2 Client ID. |
response_type | Yes | Must be code. |
redirect_uri | Yes | The URI to redirect to after approval. Must match a registered URI on your client. |
scope | Yes | Space-separated list of requested scopes (see scope table above). |
state | Recommended | A random string your application generates. Returned unchanged after authorization. Use it to prevent CSRF attacks. |
Example URL:
https://app.esignbase.com/oauth2/authorize
?client_id=YOUR_CLIENT_ID
&response_type=code
&redirect_uri=https://yourapp.com/oauth/callback
&scope=all
&state=random_csrf_string
The user will be prompted to log in to eSignBase (if not already) and approve the requested permissions.
After approval, the user is redirected to your redirect_uri with an authorization code:
https://yourapp.com/oauth/callback?code=AUTH_CODE&state=random_csrf_string
Important: Always verify that the returned
statevalue matches the one you sent. Reject the request if they do not match.
The authorization code is short-lived and can only be used once.
Step 2: Exchange the Code for an Access Token
Exchange the authorization code for an access token by making a server-side POST request:
POST /oauth2/token
Headers:
Authorization: Basic <basic_auth_credentials>
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://yourapp.com/oauth/callback
Where basic_auth_credentials is base64(client_id + ":" + client_secret).
The redirect_uri must exactly match the one used in Step 1.
Response:
{
"access_token": "<your_access_token>",
"refresh_token": "<your_refresh_token>",
"token_type": "Bearer",
"expires_in": 300
}
Access tokens are valid for 5 minutes. Use the refresh_token to obtain a new access token without
requiring the user to re-authorize.
Step 3: Refresh an Access Token
When an access token expires, use the refresh token to obtain a new one:
POST /oauth2/token
Headers:
Authorization: Basic <basic_auth_credentials>
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
grant_type=refresh_token
&refresh_token=<your_refresh_token>
Response:
{
"access_token": "<new_access_token>",
"refresh_token": "<new_refresh_token>",
"token_type": "Bearer",
"expires_in": 300
}
Store the new refresh token from each response — refresh tokens may rotate on use.
Templates
Templates are used to generate documents which recipients can fill out and sign. You can upload PDFs as templates at: https://app.esignbase.com/dashboard
Once uploaded, the template editor allows you to add form fields and signature fields.
Get A List Of All Templates:
Request:
GET /api/templates
Headers:
Authorization: Bearer <your_access_token>
Response:
[
{
"id": "the_template_id",
"ctime": "2025-08-25T13:49:00+00:00",
"filename": "my_file.pdf",
"num_of_pages": 2,
"page_standard": "a4",
"form_role_names": ["signee_1"]
},
{
"id": "another_template_id",
"ctime": "2025-08-25T14:49:00+00:00",
"filename": "my_other_file.pdf",
"num_of_pages": 1,
"page_standard": "letter",
"form_role_names": ["signee_1", "viewer_1"]
}
]
Supported page standards:
| page_standard | Description |
|---|---|
a4 | 210mm × 297mm (8.27in × 11.69in). Commonly used internationally. |
letter | 8.5in × 11in (216mm × 279mm). Commonly used in the US and Canada. |
Get Infos For One Specific Template:
Request:
GET /api/template/<template_id>
Headers:
Authorization: Bearer <your_access_token>
Response:
{
"id": "<template_id>",
"ctime": "2025-08-25T13:49:00+00:00",
"filename": "my_file.pdf",
"num_of_pages": 2,
"page_standard": "a4",
"form_role_names": ["signee_1"]
}
For each value in form_role_names, a corresponding recipient must be specified in the
Create Document request using the role_name field.
Documents
Get A List Of All Documents:
Retrieval of documents is paginated. You can retrieve a maximum of 100 documents at a time using
the limit parameter. The offset parameter specifies the starting point.
Request:
GET /api/documents?limit=1&offset=0
Headers:
Authorization: Bearer <your_access_token>
Response:
{
"documents": [
{
"id": "the_document_id",
"template_id": "template_id_this_document_is_based_of",
"name": "Employee Contract",
"owner": "name used in mails if send to signees",
"ctime": "2025-08-25T13:49:00+00:00",
"mtime": "2025-09-25T13:49:00+00:00",
"expiration_date": "2025-10-25T13:49:00+00:00",
"page_standard": "a4",
"num_of_pages": 2,
"completed_date": null,
"status": "SENT",
"recipients": [
{
"email": "signee@mail.com",
"first_name": "John",
"last_name": "Doe",
"days_before_voided": 5,
"form_role": "signee_1",
"locale": "en"
}
],
"user_defined_metadata": {
"internal_id": "42",
"internal-name": "contract-developer"
}
}
],
"count": 1
}
The count field indicates the total number of available documents, which determines the maximum
useful offset during pagination.
Document Status
| Status | Description |
|---|---|
DRAFT | Document created but not yet sent to any recipients. |
PARTIALLY_SENT | Sent to some recipients but not all. |
SENT | Sent to all recipients. |
PARTIALLY_SIGNED | Signed by some signees but not all. |
WAITING_FOR_PREPARATION | Fully signed but PDF generation is pending. |
WAITING_FOR_DIGITAL_SIGNATURE | PDF generated, awaiting digital signature application. |
DIGITAL_SIGNATURE_CREATED | PDF generated with digital signature applied. |
COMPLETED | Document signing procedure is complete. |
VOIDED | Document has been voided. |
user_defined_metadata is an optional JSON object where every value must be a string. A document
can have a maximum of 10 fields; keys up to 25 characters, values up to 500 characters.
Get Infos For One Specific Document:
Request:
GET /api/document/<document_id>
Headers:
Authorization: Bearer <your_access_token>
Response:
{
"id": "<document_id>",
"template_id": "template_id_this_document_is_based_of",
"name": "Employee Contract",
"owner": "name used in mails if send to signees",
"ctime": "2025-08-25T13:49:00+00:00",
"mtime": "2025-09-25T13:49:00+00:00",
"expiration_date": "2025-10-25T13:49:00+00:00",
"page_standard": "a4",
"num_of_pages": 2,
"completed_date": null,
"status": "COMPLETED",
"recipients": [
{
"email": "signee@mail.com",
"first_name": "John",
"last_name": "Doe",
"days_before_voided": 5,
"form_role": "signee_1",
"locale": "de"
}
],
"user_defined_metadata": {
"internal_id": "42",
"more_info": "some text"
}
}
Create A New Document
Creating a new document uses an existing template and defines who the recipients will be. Calling this endpoint initiates a new signing request.
For each role_name defined in the template’s form_role_names, a matching recipient must be
provided. The expiration_date is optional — once a document expires its status becomes VOIDED.
A document cannot be edited after creation.
Supported recipient locales:
| Locale | Language |
|---|---|
en | English (default) |
de | German |
es | Spanish |
Request:
POST /api/document
Headers:
Content-Type: application/json
Authorization: Bearer <your_access_token>
Request body:
{
"name": "Your Contract",
"template_id": "id_of_template_used_for_document",
"recipients": [
{
"email": "signee@mail.com",
"first_name": "John",
"last_name": "Doe",
"role_name": "signee_1",
"locale": "es"
}
],
"user_defined_metadata": {
"any_key": "any string value"
},
"expiration_date": "2025-09-25T13:49:00+00:00"
}
Response:
{"document_id": "new_doc_id", "status": "DRAFT"}
Download A Completed Document
Downloads the finalized, signed PDF. Only available once the document has reached one of these statuses:
DIGITAL_SIGNATURE_CREATEDCOMPLETED
Request:
GET /api/document/<document_id>/download
Headers:
Authorization: Bearer <your_access_token>
Response:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="yourfile.pdf"
Content-Length: <file_size_in_bytes>
Last-Modified: Tue, 18 Feb 2026 12:34:56 GMT
Accept-Ranges: bytes
<binary pdf content>
The endpoint supports range requests:
Range: bytes=0-1023
Successful partial response:
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/245678
Delete A Existing Document
Request:
DELETE /api/document/<document_id>
Headers:
Authorization: Bearer <your_access_token>
Returns HTTP 200 OK on success.
Webhook for Completed Signature Processes
To be notified when a signature process is completed, activate the “Document Completed Hook” in the API Settings.
Security Validation: Each webhook request includes a signature header for validation. Use the “Document Completed Hook Secret” displayed in your API settings to verify the authenticity of incoming requests.
Configuration:
- Enter the callback URL to be called when a document is completed
- Requests are sent via POST
- Validate each request using the signature header
Request:
POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
X-Signature-Secret: your_hook_secret_here
{
"document_id": "<id of the document>",
"status": "<the document status>"
}
Check How Many Document Credits Are Available
One credit is required to start the signing process for a document, regardless of the number of signatures or recipients involved.
Request:
GET /api/credits
Headers:
Authorization: Bearer <your_access_token>
Response:
{"credits": 100}