Skip to content

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

  1. 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.

  2. Find the template

    The API sends templates you have already built in Signx. List them to get the id of the one you want.

  3. 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.

  4. 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.

  5. 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.

Request
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.

Request
curl "https://api.signx.ae/api/v1/public/templates?page=1&limit=20" \
  -H "Authorization: Bearer $SIGNX_API_KEY"
Response
{
  "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.

Request
curl https://api.signx.ae/api/v1/public/templates/3f6c1a2e-8b4d-4c9a-9e21-7d5b0a4f1c88 \
  -H "Authorization: Bearer $SIGNX_API_KEY"
Response
{
  "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.
Request
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."
  }'
Response
{
  "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.

Request
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.

Request
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.
Example error
{
  "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."
}