Signx API
Send a template for signature from your HR system, ERP or CRM, then follow it until the signed PDF is ready. Everything a person can send from the app, your system can send with a key.
The API is part of the Business and Enterprise plans. See pricing
Quick start
Create a key
In Settings, API keys, create one key for each system that connects. The full key is shown once, so store it in that system's secrets straight away.
Find the template
The API sends templates you have already built in Signx. List them to get the id of the one you want.
Read its roles and fields
A template tells you which roles sign it and which fields you fill in yourself. You need both ids to send it.
Send it
Post the template id, one recipient per role and your field values. Signx emails each signer their own link, exactly as if you had sent it from the app.
Follow it to the signed PDF
Check the document's status until it is completed, then download the signed PDF with its audit trail.
Authentication
Every request carries a workspace API key as a bearer token. Keys start with sgx_.
- Base URL
https://api.signx.ae/api/v1/public- Header
Authorization: Bearer sgx_…- Language
- Send Accept-Language: ar or en. Error messages and template names come back in that language.
- Rate limit
- 60 requests per minute for each key.
A key acts with the permissions of the member who created it, and only inside that member's workspace. It stops working the moment it is revoked or that member leaves the workspace. Never put a key in a browser or a mobile app: call the API from your server.
curl https://api.signx.ae/api/v1/public/templates \
-H "Authorization: Bearer $SIGNX_API_KEY" \
-H "Accept-Language: en"List templates
GET/templates
The workspace's templates, sorted by name, 20 to a page by default. Pass page and limit (up to 50) to page through them.
curl "https://api.signx.ae/api/v1/public/templates?page=1&limit=20" \
-H "Authorization: Bearer $SIGNX_API_KEY"{
"data": [
{
"id": "3f6c1a2e-8b4d-4c9a-9e21-7d5b0a4f1c88",
"name": "Employment contract",
"signatoryCount": 2,
"fieldCount": 14,
"updatedAt": "2026-10-01T09:12:44.000Z"
}
],
"page": 1,
"totalPages": 1,
"totalItems": 1
}Read a template
GET/templates/{templateId}
One template's signatory roles and fields.
Each signatory's id is what you pass as recipients[].signatoryId. Each field's key is what you pass under answers, but only for fields whose assignedTo is sender: the rest are filled in by the signer named in assignedTo.
curl https://api.signx.ae/api/v1/public/templates/3f6c1a2e-8b4d-4c9a-9e21-7d5b0a4f1c88 \
-H "Authorization: Bearer $SIGNX_API_KEY"{
"id": "3f6c1a2e-8b4d-4c9a-9e21-7d5b0a4f1c88",
"name": "Employment contract",
"signatoryCount": 2,
"fieldCount": 14,
"updatedAt": "2026-10-01T09:12:44.000Z",
"signatories": [
{
"id": "sig-employee",
"roleLabel": { "ar": "الموظف", "en": "Employee" },
"party": "external",
"order": 1
},
{
"id": "sig-hr",
"roleLabel": { "ar": "مدير الموارد البشرية", "en": "HR manager" },
"party": "internal",
"order": 2
}
],
"fields": [
{
"key": "employee_name",
"label": { "ar": "اسم الموظف", "en": "Employee name" },
"type": "text",
"required": true,
"assignedTo": "sender"
},
{
"key": "employee_signature",
"label": { "ar": "توقيع الموظف", "en": "Employee signature" },
"type": "signature",
"required": true,
"assignedTo": "sig-employee"
}
]
}Send a document
POST/documents
Creates a document from a template and sends it for signature straight away. The response is the new document, the same shape as checking it.
Each successful call counts as one API document. Business includes 100 a billing month and Enterprise has no limit. Sending from the app never counts toward it.
Request body
templateIduuidrequired- The template to send, from listing templates.
recipientsarrayrequired- One entry per signatory role on the template.
recipients[].signatoryIdstringrequired- The role this recipient fills: a signatory id from reading the template.
recipients[].namestring- For an external role: the signer's name.
recipients[].emailstring- For an external role: where the signing link is sent.
recipients[].phonestring- For an external role: an optional phone number in international format.
recipients[].membershipIduuid- For an internal role: the workspace member who signs.
recipients[].anyHolderboolean- For an internal role: send it to the role's job title instead of one person. Any current holder may sign, and the first one to do so does.
recipients[].branchIduuid- With anyHolder: only holders placed at this branch may sign.
recipients[].orderinteger- This role's place in the signing order, starting at 1. Leave it out to keep the template's order.
signingMode"parallel" | "sequential"- parallel lets every signer sign at once; sequential sends to each in turn. parallel is the default.
answersobject- Your values for the fields assigned to the sender, keyed by field key.
branchIdstring- The branch, for a template that asks for one.
expiresInDaysinteger- Days until unsigned links expire, from 1 to 365.
messagestring- A note added to every signing invitation, up to 2000 characters.
curl -X POST https://api.signx.ae/api/v1/public/documents \
-H "Authorization: Bearer $SIGNX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "3f6c1a2e-8b4d-4c9a-9e21-7d5b0a4f1c88",
"signingMode": "sequential",
"recipients": [
{
"signatoryId": "sig-employee",
"name": "Reem Al Hosani",
"email": "reem@example.ae"
},
{
"signatoryId": "sig-hr",
"membershipId": "c3f1e9c8-6c2f-4a71-9d3e-2b8a0f7c1234"
}
],
"answers": {
"employee_name": "Reem Al Hosani",
"basic_salary": 14500
},
"expiresInDays": 14,
"message": "Please sign before Thursday."
}'{
"id": "9a2e4c71-5f3b-4d08-a6c2-1e8b7d9f0a35",
"name": "Employment contract",
"status": "sent",
"sentAt": "2026-10-14T11:02:10.000Z",
"expiresAt": "2026-10-28T11:02:10.000Z",
"completedAt": null,
"recipients": [
{
"signatoryId": "sig-employee",
"name": "Reem Al Hosani",
"email": "reem@example.ae",
"state": "pending",
"signedAt": null
},
{
"signatoryId": "sig-hr",
"name": "Salem Al Marri",
"email": "salem@example.ae",
"state": "waiting",
"signedAt": null
}
],
"signedPdfUrl": null
}Check a document
GET/documents/{documentId}
Where a document is: its status, and each recipient's state and signing time. The response has the same shape as the one sending it returns. Poll it at a sensible interval, a few minutes rather than a few seconds.
curl https://api.signx.ae/api/v1/public/documents/9a2e4c71-5f3b-4d08-a6c2-1e8b7d9f0a35 \
-H "Authorization: Bearer $SIGNX_API_KEY"Download the signed PDF
GET/documents/{documentId}/signed-pdf
Redirects (302) to a short-lived link to the signed PDF, with the audit trail attached. Follow the redirect and save the file straight away, since the link expires. Answers 404 until the document is completed.
curl -L -o signed.pdf \
https://api.signx.ae/api/v1/public/documents/9a2e4c71-5f3b-4d08-a6c2-1e8b7d9f0a35/signed-pdf \
-H "Authorization: Bearer $SIGNX_API_KEY"Statuses
Document status
awaiting_fill- Waiting for a colleague to fill it in. No signer has been told yet.
sent- Sent. Signers have their links and nobody has signed yet.
partially_signed- Some have signed, or everyone has and the signed PDF is still being produced.
completed- Everyone signed and the signed PDF is ready to download.
voided- Cancelled by the workspace. The links no longer work.
expired- The links expired before everyone signed.
Recipient state
waiting- Not sent yet: someone ahead of them in a sequential order has not signed.
pending- The link is with them and they have not signed.
signed- Signed.
declined- Declined to sign.
Errors and limits
Errors are JSON with the HTTP status and a message in the language you asked for. Show the message, but decide what to do from the status and the code, never from the wording.
400Bad Request- The body is invalid: a missing field, an unknown one, or a value of the wrong type. The message names the field.
401Unauthorized- The key is missing, wrong or revoked, or the member who created it has left the workspace.
402PLAN_API_LIMIT- This billing month's API documents are used up. Nothing was sent. Sending from the app still works.
402PLAN_FEATURE_UNAVAILABLE- The workspace's plan no longer includes the API.
403Forbidden- The member who created the key is not allowed to send documents.
404Not Found- No such template or document in this workspace, or the signed PDF is not ready yet.
429Too Many Requests- More than 60 requests in a minute from this key. Wait a minute and retry.
{
"statusCode": 402,
"code": "PLAN_API_LIMIT",
"plan": "business",
"limit": 100,
"used": 100,
"upgradeTo": "enterprise",
"message": "You've reached your 100 API documents/month limit. Upgrade to Enterprise for full API access."
}