Documents
Full reference for the SignYu documents API - create, add signers, send, and retrieve documents.
A document represents a PDF and its signers. It moves through three states: PENDING (created, not yet sent), SENT (out for signature), and COMPLETED (all signers have signed).
Create a document
POST /api/v1/documents
Uploads a PDF and creates a document in PENDING state. Send the request as multipart/form-data.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The PDF to be signed. Must be application/pdf and at most 10MB. |
name | string | No | A label for the document. Defaults to the file name. |
curl -X POST https://signyu.com/api/v1/documents \
-H "Authorization: Bearer sk_live_your_api_key" \
-F "file=@/path/to/agreement.pdf" \
-F "name=Service Agreement"
Response
Returns 201 Created.
{
"documentId": "b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c",
"name": "Service Agreement",
"status": "PENDING"
}
Add signers
POST /api/v1/documents/{documentId}/signers
Adds one or more signers. Only allowed while the document is PENDING. Signers sign in the order they are added, and a document can have at most 6 signers.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
signers | array | Yes | A non-empty array of signer objects. |
signers[].name | string | Yes | The signer's full name. |
signers[].phone | string | Yes | Digits only, at least 10 characters. |
signers[].email | string | Yes | A valid email address. The signing link is emailed here. |
signers[].advanced | object | No | Optional advanced options. Omit to use the default fixed signature slot. |
signers[].advanced.signaturePlacement | object | No | Custom stamp rectangles for this signer. |
signers[].advanced.signaturePlacement.positions | array | Yes (when placement is set) | One rectangle per page (min 1, max 20). Duplicate pages are rejected. |
positions[].page | integer | Yes | 1-based PDF page index. |
positions[].x | number | Yes | Left edge in PDF points. |
positions[].y | number | Yes | Bottom edge in PDF points (origin = bottom-left of the page). |
positions[].width | number | Yes | Box width in PDF points (minimum 140). |
positions[].height | number | Yes | Box height in PDF points (minimum 110). |
curl -X POST https://signyu.com/api/v1/documents/{documentId}/signers \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "signers": [{ "name": "Asha Rao", "phone": "9876543210", "email": "asha@example.com" }] }'
Advanced: signature placement
By default each signer gets a fixed stamp slot on every page. To place the Aadhaar stamp yourself, pass advanced.signaturePlacement when adding that signer. Placement is set only at create time; it cannot be changed after the signer is added.
The stamp (Aadhaar seal + Signed by + Date) must fit inside each rectangle. Use a box of at least 140 × 110 PDF points.
Coordinate system
All values are in PDF points. Origin is the bottom-left of the page:
| Field | Meaning |
|---|---|
x | Distance from the left edge to the left of the box |
y | Distance from the bottom edge to the bottom of the box |
width / height | Size of the box |
If you measure a box in a top-left tool (pdf.js, many PDF UIs) where y grows downward:
// pageHeight = page.getViewport({ scale: 1 }).height (PDF points)
const yBottom = pageHeight - yTop - height;
const position = {
page: 1, // 1-based
x: xLeft,
y: yBottom, // send this as y
width,
height,
};
Example on a Letter page (pageHeight = 792): a box drawn at top-left (31, 443) with size 253 × 110 becomes { x: 31, y: 239, width: 253, height: 110 } because 792 - 443 - 110 = 239.
One stamp on one page
curl -X POST https://signyu.com/api/v1/documents/{documentId}/signers \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"signers": [{
"name": "Asha Rao",
"phone": "9876543210",
"email": "asha@example.com",
"advanced": {
"signaturePlacement": {
"positions": [
{ "page": 2, "x": 31, "y": 257, "width": 253, "height": 110 }
]
}
}
}]
}'
Different pages, different boxes
Each entry in positions must use a distinct page. Up to 20 rectangles per signer.
curl -X POST https://signyu.com/api/v1/documents/{documentId}/signers \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"signers": [{
"name": "Asha Rao",
"phone": "9876543210",
"email": "asha@example.com",
"advanced": {
"signaturePlacement": {
"positions": [
{ "page": 1, "x": 50, "y": 100, "width": 200, "height": 120 },
{ "page": 2, "x": 50, "y": 500, "width": 200, "height": 120 }
]
}
}
}]
}'
Rules and common mistakes
| Rule | Detail |
|---|---|
Omit advanced | Signer uses the default fixed slot (same as the dashboard product). |
page | Integer ≥ 1. Pages beyond the PDF length may fail at signing time. |
| Box size | width ≥ 140 and height ≥ 110, or the API returns 400 invalid_request. |
| Duplicate pages | Two positions with the same page for one signer → 400 invalid_request. |
Top-left y sent as-is | Stamp appears in the wrong vertical place. Convert with pageHeight - yTop - height first. |
| Mix of signers | Some signers can use placement and others can omit it on the same document. |
Invalid placement returns 400 with error: "invalid_request" and a message describing the field (for example width too small or duplicate page).
Response
Returns 201 Created with the created signers and their assigned signing order. When placement was set, it is echoed under advanced.signaturePlacement.
{
"signers": [
{
"signerId": "s_1",
"name": "Asha Rao",
"email": "asha@example.com",
"signingOrder": 1,
"advanced": {
"signaturePlacement": {
"positions": [
{ "page": 2, "x": 31, "y": 257, "width": 253, "height": 110 }
]
}
}
}
]
}
Send for signature
POST /api/v1/documents/{documentId}/send
Deducts one credit per signer, marks the document SENT, emails a signing link to each signer, and returns those links. Requires at least one signer. The request has no body.
curl -X POST https://signyu.com/api/v1/documents/{documentId}/send \
-H "Authorization: Bearer sk_live_your_api_key"
Response
{
"documentId": "b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c",
"status": "SENT",
"creditsRemaining": 48,
"signers": [
{
"signerId": "s_1",
"name": "Asha Rao",
"email": "asha@example.com",
"signingOrder": 1,
"signUrl": "https://signyu.com/sign?did=b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c&sid=s_1"
}
]
}
If you do not have enough credits, the request returns 402 insufficient_credits and nothing is sent.
Retrieve a document
GET /api/v1/documents/{documentId}
Returns the document, each signer's progress, and a downloadUrl for the signed PDF once the document is COMPLETED. The download URL is a temporary, presigned link. When the document is COMPLETED, certificateUrl points at the on-demand completion certificate and audit trail PDF endpoint (Bearer auth required). Each signer's signUrl is null until the document is sent, and is populated once the status is SENT. When a signer was created with custom placement, advanced.signaturePlacement is included on that signer.
curl https://signyu.com/api/v1/documents/{documentId} \
-H "Authorization: Bearer sk_live_your_api_key"
Response
{
"documentId": "b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c",
"name": "Service Agreement",
"status": "COMPLETED",
"createdAt": "2026-07-17T06:30:00.000Z",
"updatedAt": "2026-07-17T07:15:00.000Z",
"completedAt": "2026-07-17T07:15:00.000Z",
"downloadUrl": "https://s3.ap-south-1.amazonaws.com/...",
"certificateUrl": "https://signyu.com/api/v1/documents/b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c/certificate",
"signers": [
{
"signerId": "s_1",
"name": "Asha Rao",
"email": "asha@example.com",
"phone": "9876543210",
"signingOrder": 1,
"openedAt": "2026-07-17T07:00:00.000Z",
"signedAt": "2026-07-17T07:05:00.000Z",
"hasSigned": true,
"signUrl": "https://signyu.com/sign?did=b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c&sid=s_1",
"advanced": {
"signaturePlacement": {
"positions": [
{ "page": 2, "x": 31, "y": 257, "width": 253, "height": 110 }
]
}
}
}
]
}
Download completion certificate
GET /api/v1/documents/{documentId}/certificate
Returns a PDF containing the Signature Completion Certificate and chronological Audit Trail. Available only when the document status is COMPLETED. Returns 409 invalid_state if the document is not yet complete.
curl https://signyu.com/api/v1/documents/{documentId}/certificate \
-H "Authorization: Bearer sk_live_your_api_key" \
-o completion-certificate.pdf
List documents
GET /api/v1/documents
Returns your documents, most recent first, with a summary of signer progress.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Number of documents to return (1 to 100). |
offset | number | 0 | Number of documents to skip. |
curl "https://signyu.com/api/v1/documents?limit=20&offset=0" \
-H "Authorization: Bearer sk_live_your_api_key"
Response
{
"documents": [
{
"documentId": "b6b1f0e2-1c9a-4a1e-9b1a-2f3d4e5a6b7c",
"name": "Service Agreement",
"status": "SENT",
"createdAt": "2026-07-17T06:30:00.000Z",
"signers": { "total": 2, "signed": 1 }
}
],
"limit": 20,
"offset": 0
}