#Overview
The Geteken API lets you create and manage e-signing envelopes. It is interface-compatible with the PandaDoc v1 API — if you already have a PandaDoc integration, you only need to swap the base URL.
| Base URL | https://geteken.co.za |
| Version | v1 |
| Protocol | HTTPS only |
| Content-Type | application/json |
#Authentication
All requests require an API key in the Authorization header.
Both formats are accepted:
Authorization: API-Key sk_signing_<your_key>Authorization: Bearer sk_signing_<your_key>
Find your API key in Settings → API Keys in your dashboard.
# Example authenticated request
curl https://geteken.co.za/api/public/v1/documents \
-H "Authorization: API-Key sk_signing_your_key_here"#All Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/public/v1/documents | Create envelope (draft) |
| GET | /api/public/v1/documents | List envelopes (paginated) |
| GET | /api/public/v1/documents/{id} | Get envelope detail + status |
| GET | /api/public/v1/documents/{id}/preview | Preview template (JSON or HTML) |
| POST | /api/public/v1/documents/{id}/send | Send envelope to signers |
| GET | /api/public/v1/documents/{id}/download | Download completed/source PDF |
| POST | /api/public/v1/documents/{id}/cancel | Cancel (void) envelope |
| GET | /api/public/v1/balance | Wallet balance (cents + plan) |
| POST | /api/public/v1/topup | Start a wallet top-up (returns Paystack checkout link) |
#POST/api/public/v1/documents
Create a new signing envelope in draft status. You can supply a template UUID or a direct document URL. The envelope is ready to send after creation.
#Request body
| Field | Type | Description |
|---|---|---|
| name* | string | Human-readable name of the envelope. |
| template_uuid | string | UUID or external ID of a Geteken template. |
| url | string | HTTPS URL of a PDF to use directly (if template_uuid is not supplied). |
| recipients* | array | List of signers. See structure below. |
| tokens | object | Key-value pairs to pre-fill template tokens. |
| metadata | object | Store your own ID or reference. |
#Recipient structure
| Field | Type | Description |
|---|---|---|
| email* | string | Recipient's email address. |
| first_name | string | First name. |
| last_name | string | Last name. |
| role | string | Role name matching a template role (e.g. "Buyer"). |
| signing_order | integer | 1-based order. Recipients sharing the same number sign in parallel. |
curl -X POST https://geteken.co.za/api/public/v1/documents \
-H "Authorization: API-Key sk_signing_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Service Agreement — Acme Corp",
"template_uuid": "3a8f1b20-1234-4abc-abcd-000000000001",
"recipients": [
{
"email": "buyer@example.com",
"first_name": "Jane",
"last_name": "Smith",
"role": "Buyer",
"signing_order": 1
}
],
"tokens": {
"company_name": "Acme Corp",
"contract_date": "2026-06-08"
},
"metadata": { "deal_id": "crm-9876" }
}'#Response — 201 Created
{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.draft",
"date_created": "2026-06-08T10:00:00.000Z",
"metadata": { "deal_id": "crm-9876" }
}#GET/api/public/v1/documents
List all your envelopes, sorted newest-first. Use the ?count= parameter to control pagination (max 100).
#Query parameters
| Parameter | Type | Default / Description |
|---|---|---|
| count | integer | Number of results to return. Default: 25, max: 100. |
curl https://geteken.co.za/api/public/v1/documents?count=10 \
-H "Authorization: API-Key sk_signing_..."{
"results": [
{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.completed",
"date_created": "2026-06-08T10:00:00.000Z",
"metadata": {}
}
]
}#GET/api/public/v1/documents/{id}
Retrieve envelope details including all recipients and their signing progress.
curl https://geteken.co.za/api/public/v1/documents/env_01abc23def456 \
-H "Authorization: API-Key sk_signing_..."{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.sent",
"date_created": "2026-06-08T10:00:00.000Z",
"date_completed": null,
"expiration_date": null,
"metadata": {},
"recipients": [
{
"email": "buyer@example.com",
"first_name": "Jane",
"last_name": "Smith",
"role": "Buyer",
"signing_order": 1,
"status": "sent",
"signed_at": null,
"viewed_at": "2026-06-08T11:00:00.000Z"
}
]
}#GET/api/public/v1/documents/{id}/preview
Get a rendered preview of the envelope's template (tokens substituted) plus the recipient and field plan — without requiring a signing token. Useful for a pre-send preview inside a Bubble iframe.
#Query parameters
| Parameter | Type | Description |
|---|---|---|
| format | "html" | Return raw rendered HTML (Content-Type: text/html) for iframe embedding. |
# JSON response (default)
curl https://geteken.co.za/api/public/v1/documents/env_01abc23def456/preview \
-H "Authorization: API-Key sk_signing_..."
# Raw HTML for iframe
curl "https://geteken.co.za/api/public/v1/documents/env_01abc23def456/preview?format=html" \
-H "Authorization: API-Key sk_signing_..."#POST/api/public/v1/documents/{id}/send
Transitions the envelope from draft to sent. Invite emails are dispatched to all recipients at the lowest signing order (parallel signers go simultaneously). If the envelope is already sent, calling this again re-sends without additional charge.
#Optional request body
| Field | Type | Description |
|---|---|---|
| message | string | Custom message included in the invitation email. |
| subject | string | Subject line for the invitation email. |
curl -X POST https://geteken.co.za/api/public/v1/documents/env_01abc23def456/send \
-H "Authorization: API-Key sk_signing_..." \
-H "Content-Type: application/json" \
-d '{
"subject": "Please sign: Service Agreement",
"message": "Hi Jane, please review and sign at your earliest convenience."
}'{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.sent",
"notified_recipients": 1
}#GET/api/public/v1/documents/{id}/download
Returns a signed URL to the PDF. For completed envelopes this is the final stamped PDF with the audit seal. For in-progress envelopes it is the source PDF. URL expires after 24 hours.
| Parameter | Type | Description |
|---|---|---|
| inline | "1" | Redirect (302) directly to the signed URL instead of returning JSON. |
# Returns JSON with download_url
curl https://geteken.co.za/api/public/v1/documents/env_01abc23def456/download \
-H "Authorization: API-Key sk_signing_..."
# Redirect directly to the PDF (useful for <a href> or <iframe>)
curl -L "https://geteken.co.za/api/public/v1/documents/env_01abc23def456/download?inline=1" \
-H "Authorization: API-Key sk_signing_..." \
-o signed_document.pdf{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.completed",
"download_url": "https://storage.geteken.co.za/signing-documents/...",
"expires_in_seconds": 86400,
"final_pdf_hash_sha256": "e3b0c44298fc1c14...",
"issued_at": "2026-06-08T14:32:00.000Z"
}#POST/api/public/v1/documents/{id}/cancel
Voids an envelope. Recipients can no longer sign. Cannot be called on completed or already-voided envelopes.
curl -X POST https://geteken.co.za/api/public/v1/documents/env_01abc23def456/cancel \
-H "Authorization: API-Key sk_signing_..." \
-H "Content-Type: application/json" \
-d '{ "reason": "Contract terms changed" }'{
"id": "env_01abc23def456",
"name": "Service Agreement — Acme Corp",
"status": "document.voided"
}#Status Values
The status field follows PandaDoc convention (document.*).
| Status | Meaning |
|---|---|
| document.draft | Envelope created but not yet sent. |
| document.sent | Invitations sent to signers. |
| document.viewed | First recipient has opened the document. |
| document.partially_signed | Some signers have signed, but not all. |
| document.completed | All signers have signed. The GOLD SEAL has been issued. |
| document.voided | Envelope cancelled via the /cancel endpoint. |
| document.declined | A recipient declined to sign. |
#Errors
Errors are returned as JSON with an "error" key. Use the HTTP status code for control flow.
| HTTP | error | When |
|---|---|---|
| 400 | Invalid JSON body | Body is not valid JSON. |
| 400 | `name` and `recipients[]` are required | Required fields missing. |
| 400 | invalid document_url | URL is not HTTPS or the document could not be fetched. |
| 401 | Invalid or missing API key | Authorization header missing or key invalid. |
| 402 | insufficient_credits | Balance too low. upgrade: true is included in response. |
| 403 | Forbidden | Resource belongs to a different tenant. |
| 404 | Not found | Envelope ID does not exist. |
| 409 | Cannot cancel envelope in status '...' | State transition not allowed. |
{ "error": "insufficient_credits", "upgrade": true }#Pricing
R12 per document
One charge per envelope covers all signers on that document. Your first two documents are free to send. No contract or monthly fee — you only pay when you send.