Documents
Document signing, review, and refresh — requests, responses, and field reference.
Base path: /api/v2/document · Billing: signature · Scope: document:sign
Sign PDFs (or other files) hosted at a public URL. pasby notifies your backend via webhook when signers complete. Use review when you need structured signee metadata and a hosted signing UI; use refresh to recover stalled flows and fetch stamped files plus signatures.
Production: https://l.pasby.africa · Sandbox: https://s.pasby.africa
Headers (v2): x-api-key, x-access-secret
Headers (v1): x-api-key, x-access-token
SDK: pasby.docs.docSign, docReview, docSignatureRefresh — TypeScript SDK.
Document model
Responses return a document object (under data.request or data.doc) with this shape:
idstringDocument flow id (
doc_…). Use asflowfor refresh and for flow ping.tostring[]Recipient NINs for simple signing.
destinationstringWhere the flow is completed (e.g.
mobile).handledbooleanWhether the request has been handled.
file.sourcestringOriginal file URL you supplied.
file.namestringDisplay title of the document.
file.stampedstringURL of the signed/stamped PDF (present after completion on refresh).
hookobjectEcho of your
webhook.hostandwebhook.reference.modestringinterfaceon review flows (hosted UI).signeearrayStructured signers on review/refresh (name, email, nin, type, representing,
signedAt, etc.).statusLogarrayPer-NIN status (
stale, etc.) andluttimestamps.signaturesarrayCryptographic signature payloads per signer (on completed refresh).
POST /api/v2/document/signing
Sign a file for one or more NINs. pasby pushes the flow to each recipient's pasby app.
| Field | Type | Required |
|---|---|---|
to | string[] | Yes — at least one NIN |
file.url | string | Yes — direct, publicly reachable URL |
file.title | string | Yes |
webhook.host | string | Yes — your HTTPS callback |
webhook.reference | string | Yes — your correlation id |
Monitor with flow ping using data.request.id. Listen for your webhook.
curl -sS -X POST "https://s.pasby.africa/api/v2/document/signing" \
-H "x-api-key: bk-test_YOUR_KEY" \
-H "x-access-secret: YOUR_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{
"to": ["12345678901"],
"webhook": {
"host": "https://your-app.com/pasby/events",
"reference": "doc-contract-001"
},
"file": {
"url": "https://your-cdn.com/documents/contract.pdf",
"title": "Service Agreement"
}
}'{
"status": "successful",
"reason": "Signature request propagated",
"data": {
"request": {
"id": "doc_1707025000-AaBb",
"to": ["12345678901"],
"destination": "mobile",
"iat": 1707025000,
"exp": 1707032200,
"lut": 1707025001,
"handled": false,
"file": {
"source": "https://your-cdn.com/documents/contract.pdf",
"name": "Service Agreement"
},
"hook": {
"host": "https://your-app.com/pasby/events",
"reference": "doc-contract-001"
},
"request": {
"client": "bcn_•••••••",
"app": "app_•••••••",
"ip": "203.0.113.10"
}
}
},
"version": "v2"
}POST /api/v2/document/review
Launch a hosted review flow with structured signees. Response includes a link to open the signing UI.
| Field | Type | Required |
|---|---|---|
signee | array | Yes (min 1) |
signee[].name | string | Yes |
signee[].type | string | Yes — business or person |
signee[].email | string | Yes |
signee[].nin | string | Yes |
signee[].representing | string | Yes |
signee[].title | string | No |
file.url | string | Yes |
file.title | string | Yes |
webhook.host | string | Yes |
webhook.reference | string | Yes |
curl -sS -X POST "https://s.pasby.africa/api/v2/document/review" \
-H "x-api-key: bk-test_YOUR_KEY" \
-H "x-access-secret: YOUR_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{
"signee": [{
"name": "Jane Doe",
"type": "person",
"email": "jane@example.com",
"nin": "12345678901",
"representing": "Jane Doe",
"title": "Director"
}],
"webhook": {
"host": "https://your-app.com/pasby/events",
"reference": "review-001"
},
"file": {
"url": "https://your-cdn.com/documents/agreement.pdf",
"title": "Partnership Agreement"
}
}'{
"status": "successful",
"reason": "Document signing flow created",
"data": {
"link": "https://sign.with.pasby.africa/contract/doc_1707025100-BbCc",
"request": {
"id": "doc_1707025100-BbCc",
"to": ["12345678901"],
"destination": "mobile",
"iat": 1707025100,
"exp": 1707370700,
"lut": 1707025100,
"handled": false,
"mode": "interface",
"file": {
"source": "https://your-cdn.com/documents/agreement.pdf",
"name": "Partnership Agreement"
},
"hook": {
"host": "https://your-app.com/pasby/events",
"reference": "review-001"
},
"signee": [{
"name": "Jane Doe",
"representing": "Jane Doe",
"title": "Director",
"type": "person",
"email": "jane@example.com",
"nin": "12345678901"
}],
"statusLog": [{
"nin": "12345678901",
"status": "stale",
"lut": 1707025100
}],
"request": {
"client": "bcn_•••••••",
"app": "app_•••••••",
"ip": "203.0.113.10"
}
}
},
"version": "v2"
}Open data.link for signers who need the browser review experience. Track progress with ping/SSE and webhooks.
POST /api/v2/document/refresh
Fetch the latest document state — including file.stamped, signatures, and per-signee statusLog — when a flow stalls or you need to reconcile after webhooks.
| Field | Type | Required |
|---|---|---|
flow | string | Yes — document id (doc_…), min 40 characters |
Pass the id from signing/review create, or from a webhook payload.
curl -sS -X POST "https://s.pasby.africa/api/v2/document/refresh" \
-H "x-api-key: bk-test_YOUR_KEY" \
-H "x-access-secret: YOUR_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{ "flow": "doc_1707025200-CcDd0123456789012345678901234567890" }'{
"status": "successful",
"reason": "Esignature refreshed successfully",
"data": {
"doc": {
"id": "doc_1707025200-CcDd0123456789012345678901234567890",
"to": ["12345678901", "98765432109"],
"destination": "mobile",
"domain": "live",
"mode": "interface",
"handled": true,
"file": {
"source": "https://your-cdn.com/documents/agreement.pdf",
"name": "Service Agreement",
"stamped": "https://cdn.pasby.africa/edoc/doc_1707025200-CcDd-stamped.pdf"
},
"statusLog": [
{ "nin": "12345678901", "status": "stale", "lut": 1707025200 },
{ "nin": "98765432109", "status": "stale", "lut": 1707025200 }
],
"signee": [
{
"title": "Signatory A",
"name": "Jane Doe",
"nin": "12345678901",
"representing": "Acme Ltd",
"type": "business",
"email": "jane@example.com",
"signedAt": 1707025300,
"ip": "203.0.113.10"
},
{
"title": "Signatory B",
"name": "John Smith",
"nin": "98765432109",
"representing": "John Smith",
"type": "person",
"email": "john@example.com",
"signedAt": 1707025400,
"ip": "203.0.113.11"
}
],
"signatures": [
{
"nin": "12345678901",
"name": "Jane Doe",
"representing": "Acme Ltd",
"iat": 1707025300,
"identification": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"signature": "<base64-encoded-signature>"
},
{
"nin": "98765432109",
"name": "John Smith",
"representing": "John Smith",
"iat": 1707025400,
"identification": "ffffffff-gggg-hhhh-iiii-jjjjjjjjjjjj",
"signature": "<base64-encoded-signature>"
}
],
"hook": {
"reference": "doc-contract-001",
"host": "https://your-app.com/pasby/events"
}
}
},
"version": "v2"
}Verify completed documents at in.pasby.africa using the stamped file URL when available.
Legacy v1
Mirror paths under /api/v1/document/ with x-access-token instead of x-access-secret. Request and response bodies match v2.
| Endpoint | v1 auth |
|---|---|
POST /api/v1/document/signing | x-api-key, x-access-token |
POST /api/v1/document/review | x-api-key, x-access-token |
POST /api/v1/document/refresh | x-api-key, x-access-token |
See Document signing guide for walkthroughs and Migration v1 → v2.