Endpoints
Overview
Signify exposes REST endpoints for document creation, retrieval, and download. Each endpoint accepts standard HTTP requests with the appropriate method, path, headers, and body.
Environment endpoints
| Environment | Endpoint |
|---|---|
| Production | https://app.signify.gov.sg/public/ |
| Staging | https://staging.signify.gov.sg/public/ |
Create Document (will be deprecated from 1 December 2026)
POST /v2/documents
Warning: This endpoint will be deprecated from 1 December 2026. Please switch to the new Create Document endpoint before then.
Content type
The request must be of type multipart/form-data.
Signing modes
We support two modes of signing invitation: (1) signing by email and (2) signing by link.
- In signing by email, the API caller supplies the email addresses of the signatories, and an email invite is sent out by Signify to the signatories to sign the document.
- In signing by link, no email addresses are supplied by the API caller. Signing links are returned to the API caller, who can then redirect their users to the signing link.
The signing mode is specified in the documentMode property of the request body.
Both signing modes require the API caller to specify the location of the signature placeholders.
Signing by Email
The mandatory fields in request body are:
documentName- the document namerecipients- an array of{email: string, requiredSignatures: requiredSignature[], customMessage?: string}file- the file binary
The optional fields in the request body are:
documentMode- For signing by email, you may specify this to beemail. If not specified, this will default toemail.redirectUrl- Signify will redirect to this redirectUrl upon completion of signing (by each email recipient). Only URLs with ahttpsprotocol, and a.gov.sgdomain will be accepted.
| Property | Type | Required? | Restrictions |
|---|---|---|---|
documentName |
string |
Yes | Must have at least 4 characters and at most 100 characters. Only the following character set is allowed: a-zA-Z0-9_\-./() &`;'" |
recipients |
An array of {email: string, requiredSignatures: requiredSignature[], customMessage?: string} |
Yes | Email addresses must be unique.requiredSignatures is an array of the requiredSignature object, which has the type:{ page: number, positionX: number, positionY: number }• page represents the page that the fixed signature placeholder is located.• positionX and positionY are numbers between 0 to 1. They represent the location of the fixed signature as a percentage of the total document’s width and height respectively.• requiredSignature array has a max length of 20 per email recipient.customMessage is an optional attribute of 1 to 1000 characters. The message will be sent out as part of the email invitation to the recipient. |
file |
binary |
Yes | Up to 10MB |
documentMode |
email literal |
No, optional | |
redirectUrl |
string |
No, optional | Must have a https protocol and a .gov.sg domain |
How to obtain positionX and positionY:
One way to obtain positionX and positionY is to
- Create a document via Signify web https://signify.gov.sg/
- Inspect the network call to https://app.signify.gov.sg/api/v1/documents/upload, extract
positionXandpositionYfrom the payload - Use these values in your API call
Sample CURL request:
curl -X POST "https://app.signify.gov.sg/public/v2/documents" \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: multipart/form-data' \
-F 'documentName=Testing API' \
-F 'recipients=[{"email":"<EMAIL_1>","requiredSignatures":[{"page":1, "positionX":0.1, "positionY":0.2}, {"page":1, "positionX":0.2, "positionY":0.3}], "customMessage": "Please sign on Page 3."},{"email":"<EMAIL_2>","requiredSignatures":[{"page":1, "positionX":0.5, "positionY":0.5}]}]' \
-F 'file=@"<FILE_PATH>"'Returns:
{
"documentId": 20
}Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
documentId |
The unique identifier of the document | 5 |
Signing by Link
The mandatory fields in request body are:
documentName- the document nametotalSignaturesByLink- a length 1 array of{requiredSignatures: requiredSignature[]}file- the file binarydocumentMode- this must be specified aslink
The optional fields in the request body are:
redirectUrl- Signify will redirect to this redirectUrl upon completion of signing. Only URLs with ahttpsprotocol, and a.gov.sgdomain will be accepted.
| Property | Type | Required? | Restrictions |
|---|---|---|---|
documentName |
string |
Yes | Must have at least 4 characters and at most 100 characters. Only the following character set is allowed: a-zA-Z0-9_\-./() &`;'" |
totalSignaturesByLink |
A length 1 array of {requiredSignatures: requiredSignature[]} |
Yes | Array must be of length exactly 1.requiredSignature has the type: { page: number, positionX: number, positionY: number } • page represents the page that the fixed signature placeholder is located.• positionX and positionY are numbers between 0 to 1. They represent the location of the fixed signature as a percentage of the total document’s width and height respectively. Refer below for instructions on how to retrieve these coordinates.• requiredSignature array has a max length of 20. |
file |
binary |
Yes | Up to 10MB |
documentMode |
link literal |
Yes | |
redirectUrl |
string |
No, optional | Must have a https protocol and a .gov.sg domain |
How to obtain positionX and positionY:
One way to obtain positionX and positionY is to
- Create a document via Signify web https://signify.gov.sg/
- Inspect the network call to https://app.signify.gov.sg/api/v1/documents/upload-link, extract
positionXandpositionYfrom the payload - Use these values in your API call
Sample CURL request:
curl -X POST "https://app.signify.gov.sg/public/v2/documents" \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: multipart/form-data' \
-F 'documentName=Document 1' \
-F 'totalSignaturesByLink=[{"requiredSignatures": [{"page": 1, "positionX": 0, "positionY": 0}, {"page": 2, "positionX": 0.2, "positionY": 0.3}]}]' \
-F 'documentMode=link' \
-F 'file=@"<FILE_PATH>"'Returns:
{
"documentId": "3",
"signingLinks": [
{
"signingLink": "https://app.signify.gov.sg/documents/sign/01hfk78xjafvn9n8xn084a9rsn",
"totalSignatures": 2
}
]
}Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
documentId |
The unique identifier of the document | 3 |
signingLinks |
The signing links for this document, in an array. For each link, signingLink is the link URL, and totalSignatures is the number of signatures required for that link, as specified during document creation. |
[ { "signingLink": "https://app.signify.gov.sg/documents/sign/01hfk78xjafvn9n8xn084a9rsn", "totalSignatures": 2 } ] |
Create Document (available from 3 June 2026)
POST /v3/documents
Warning: This endpoint will be available from 3 June 2026. Specifications are still subject to change until then.
How this is different from the previous API version (/v2/documents):
Documents created via this endpoint utilise the new signing flow. This new signing flow injects signatures of a larger size.
- On a regular A4 document, a Sign with Singpass signature will take up an area of 7.78cm x 2.12cm (294 x 80 pixels). This size is dictated by Singpass and cannot be changed (reference).
The API changes are:
New optional
allowedIdentifiersfield (for NRIC/FIN)Validation will be done on the location of the signature placeholder. If the placeholder does not exist within the bounds of the document, the API will return an error (400 status code).
Content type
The request must be of type multipart/form-data .
Signing modes
We support two modes of signing invitation: (1) signing by email and (2) signing by link.
- In signing by email, the API caller supplies the email addresses of the signatories, and an email invite is sent out by Signify to the signatories to sign the document.
- In signing by link, no email addresses are supplied by the API caller. Signing links are returned to the API caller, who can then redirect their users to the signing link.
The signing mode is specified in the documentMode property of the request body.
Both signing modes require the API caller to specify the location of the signature placeholders.
Signing by Email
The mandatory fields in request body are:
documentName- the document namerecipients- an array of{email: string, requiredSignatures: requiredSignature[], customMessage?: string, uin?: string}file- the file binary
The optional fields in the request body are:
documentMode- For signing by email, you may specify this to beemail. If not specified, this will default toemail.redirectUrl- Signify will redirect to this redirectUrl upon completion of signing (by each email recipient). Only URLs with ahttpsprotocol, and a.gov.sgdomain will be accepted.
| Property | Type | Required? | Restrictions |
|---|---|---|---|
documentName |
string |
Yes | Must have at least 4 characters and at most 100 characters. Only the following character set is allowed: a-zA-Z0-9_\-./() &`;'" |
recipients |
An array of {email: string, requiredSignatures: requiredSignature[], customMessage?: string, allowedIdentifiers?: string[]} |
Yes | Email addresses must be unique.requiredSignatures is an array of the requiredSignature object, which has the type:{ page: number, positionX: number, positionY: number }• page represents the page that the fixed signature placeholder is located.• positionX and positionY are numbers between 0 to 1. They represent the location of the fixed signature as a percentage of the total document’s width and height respectively. Refer below for instructions on how to retrieve these coordinates.• requiredSignature array has a max length of 20 per email recipient.customMessage is an optional attribute of 1 to 1000 characters. The message will be sent out as part of the email invitation to the recipient.allowedIdentifiers array is an optional attribute of a valid NRIC/FIN authorised to view the document. If provided, only this NRIC/FIN will be able to view the document. This array has a max length of 1. |
file |
binary |
Yes | Up to 10MB |
documentMode |
email literal |
No, optional | |
redirectUrl |
string |
No, optional | Must have a https protocol and a .gov.sg domain |
How to obtain positionX and positionY:
One way to obtain positionX and positionY is to
- Create a document via Signify web https://signify.gov.sg/
- Inspect the network call to https://app.signify.gov.sg/api/v1/documents/upload, extract
positionXandpositionYfrom the payload - Use these values in your API call
Sample CURL request:
curl -X POST "https://app.signify.gov.sg/public/v3/documents" \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: multipart/form-data' \
-F 'documentName=Testing API' \
-F 'recipients=[{"email":"<EMAIL_1>","requiredSignatures":[{"page":1, "positionX":0.1, "positionY":0.2}, {"page":1, "positionX":0.2, "positionY":0.3}], "customMessage": "Please sign on Page 3."},{"email":"<EMAIL_2>","requiredSignatures":[{"page":1, "positionX":0.5, "positionY":0.5}]}]' \
-F 'file=@"<FILE_PATH>"'Returns:
{
"documentId": 20
}Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
documentId |
The unique identifier of the document | 5 |
Signing by Link
The mandatory fields in request body are:
documentName- the document nametotalSignaturesByLink- a length 1 array of{requiredSignatures: requiredSignature[], allowedIdentifiers?: []}file- the file binarydocumentMode- this must be specified aslink
The optional fields in the request body are:
redirectUrl- Signify will redirect to this redirectUrl upon completion of signing. Only URLs with ahttpsprotocol, and a.gov.sgdomain will be accepted.uin- Array of valid NRICs/FINs. If provided, only these NRIC/FINs will be able to view the document.
| Property | Type | Required? | Restrictions |
|---|---|---|---|
documentName |
string |
Yes | Must have at least 4 characters and at most 100 characters. Only the following character set is allowed: a-zA-Z0-9_\-./() &`;'" |
totalSignaturesByLink |
A length 1 array of {requiredSignatures: requiredSignature[]} |
Yes | Array must be of length exactly 1.requiredSignature has the type:{ page: number, positionX: number, positionY: number }• page represents the page that the fixed signature placeholder is located• positionX and positionY are numbers between 0 to 1. They represent the location of the fixed signature as a percentage of the total document’s width and height respectively. Refer below for instructions on how to retrieve these coordinates.• requiredSignature array has a max length of 20allowedIdentifiers array is optional◦ If provided, array has a min length of 1 ◦ Only valid NRIC and FIN numbers are accepted. If an invalid NRIC/FIN is given, a status code 400 error will be thrown. ◦ If provided, only these NRICs/FINs will be able to view the document. |
file |
binary |
Yes | Up to 10MB |
documentMode |
link literal |
Yes | |
redirectUrl |
string |
No, optional | Must have a https protocol and a .gov.sg domain |
How to obtain positionX and positionY:
One way to obtain positionX and positionY is to
- Create a document via Signify web https://signify.gov.sg/
- Inspect the network call to https://app.signify.gov.sg/api/v1/documents/upload-link, extract
positionXandpositionYfrom the payload - Use these values in your API call
Sample CURL request:
curl -X POST "https://app.signify.gov.sg/public/v3/documents" \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: multipart/form-data' \
-F 'documentName=Document 1' \
-F 'totalSignaturesByLink=[{"requiredSignatures": [{"page": 1, "positionX": 0, "positionY": 0}, {"page": 2, "positionX": 0.2, "positionY": 0.3}], "allowedIdentifiers": ["S8374662I"]}]' \
-F 'documentMode=link' \
-F 'file=@"<FILE_PATH>"'Returns:
{
"documentId": "3",
"signingLinks": [
{
"signingLink": "https://app.signify.gov.sg/documents/sign/01hfk78xjafvn9n8xn084a9rsn",
"totalSignatures": 2
}
]
}Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
documentId |
The unique identifier of the document | 3 |
signingLinks |
The signing links for this document, in an array. For each link, signingLink is the link URL, and totalSignatures is the number of signatures required for that link, as specified during document creation. |
[ { "signingLink": "https://app.signify.gov.sg/documents/sign/01hfk78xjafvn9n8xn084a9rsn", "totalSignatures": 2 } ] |
Get Documents
GET /v2/documents
Sample CURL request:
curl -X GET "https://app.signify.gov.sg/public/v2/documents" \
-H 'Authorization: Bearer <API_KEY>'Returns:
[
{
"id": 3,
"documentName": "Document 1",
"expiresAt": "2023-12-19T15:59:59.999Z",
"createdAt": "2023-11-19T07:21:14.065Z",
"status": "draft",
"documentMode": "link"
},
{
"id": 4,
"documentName": "Document 2",
"expiresAt": "2023-12-19T15:59:59.999Z",
"createdAt": "2023-11-19T07:22:21.272Z",
"status": "draft",
"documentMode": "email"
},
{
"id": 5,
"documentName": "Document 3",
"expiresAt": "2023-12-19T15:59:59.999Z",
"createdAt": "2023-11-19T08:23:07.277Z",
"status": "draft",
"documentMode": "email"
}
]Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
id |
The unique identifier of the document | 6 |
documentName |
The name of the document, as specified during document creation | Document 1 |
expiresAt |
The expiry time of the document, after which it can no longer be accessed | 2023-12-19T15:59:59.999Z |
createdAt |
The creation time of the document | 2023-11-19T08:23:20.488Z |
status |
The status of the document. Either signed if all signatures required have been completed, or draft otherwise |
signed |
documentMode |
Type of signing for this document. Either link if the document is signing by link, or email otherwise |
link |
Get Single Document
GET /v2/documents/:id
Warning: The “documentUrl” property will be deprecated from 1 December 2026. Please refer to the Download Document endpoint to retrieve the PDF document.
Sample CURL request:
curl -X GET "https://app.signify.gov.sg/public/v2/documents/6" \
-H 'Authorization: Bearer <API_KEY>'Returns:
For signing by email:
{
"id": 6,
"documentName": "Document 1",
"documentUrl": "https://app.signify.gov.sg/api/v1/bucket/01hfkatk5tc2mgxq1wefhyn52d",
"expiresAt": "2023-12-19T15:59:59.999Z",
"createdAt": "2023-11-19T08:23:20.488Z",
"status": "draft",
"signingInvitations": [
{
"signatory": "email1@open.gov.sg",
"totalSignatures": 3,
"status": "draft",
"completedSignatures": []
},
{
"signatory": "email2@open.gov.sg",
"totalSignatures": 1,
"status": "signed",
"completedSignatures": [
{
"name": "MY NAME",
"timeStamp": "2023-11-19T08:31:36.000Z"
}
]
}
],
"documentMode": "email"
}For signing by link:
{
"id": 313,
"documentName": "Document 1",
"documentUrl": "https://app.signify.gov.sg/api/v1/bucket/01hfna3nxdxf9nzvev5hw7aaf1",
"expiresAt": "2023-12-20T15:59:59.999Z",
"createdAt": "2023-11-20T02:49:17.105Z",
"status": "signed",
"signingInvitations": [
{
"signingLink": "https://app.signify.gov.sg/documents/sign/01hfna3p1f095s5aqph2dsjr07",
"totalSignatures": 3,
"status": "signed",
"completedSignatures": [
{
"name": "MY NAME",
"timeStamp": "2023-11-20T02:49:37.000Z"
},
{
"name": "MY NAME",
"timeStamp": "2023-11-20T02:50:00.000Z"
},
{
"name": "MY NAME",
"timeStamp": "2023-11-20T02:53:04.000Z"
}
]
}
],
"documentMode": "link"
}Explanation of fields returned:
| Field returned | What it means | Example |
|---|---|---|
id |
The unique identifier of the document | 6 |
documentName |
The name of the document, as specified during document creation | Document 1 |
documentUrl |
The url where the document file can be retrieved. ⚠️ The document file URL is only guaranteed to be valid for 30 minutes. You should refetch the URL again after that time. |
https://app.signify.gov.sg/api/v1/bucket/01hfkatk5tc2mgxq1wefhyn52d |
expiresAt |
The expiry time of the document, after which it can no longer be accessed | 2023-12-19T15:59:59.999Z |
createdAt |
The creation time of the document | 2023-11-19T08:23:20.488Z |
status |
The status of the document. Either signed if all signatures required have been completed, or draft otherwise |
signed |
signingInvitations |
Details of the signing invitations sent out. • signatory - Email address of the signatory (only for signing by email)• signingLink - Link for signing (only for signing by link)• totalSignatures - Number of signatures required from this invite• status - signed if all signatures have been collected for this invite, draft otherwise• completedSignatures - details of the signatures already collected |
{ "signatory": "email2open.gov.sg", "totalSignatures": 1, "status": "signed", "completedSignatures": [ { "name": "MY NAME", "timeStamp": "2023-11-19T08:31:36.000Z" } ] } |
documentMode |
Type of signing for this document. Either link if the document is signing by link, or email otherwise |
link |
Delete Document
DELETE /v2/documents/:id
Sample CURL request:
curl -X DELETE "https://app.signify.gov.sg/public/v2/documents/6" \
-H 'Authorization: Bearer <API_KEY>'Returns:
{
"message": "Document deleted"
}Download Document
GET /v2/documents/:id/download
Sample CURL request:
curl -X GET "https://app.signify.gov.sg/public/v2/documents/6/download" \
-H 'Authorization: Bearer <API_KEY>'Returns:
Binary PDF file