Geteken REST API

API Reference

PandaDoc-compatible REST API. Base URL: https://geteken.co.za. Version: v1.

#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 URLhttps://geteken.co.za
Versionv1
ProtocolHTTPS only
Content-Typeapplication/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.

bash
# Example authenticated request
curl https://geteken.co.za/api/public/v1/documents \
  -H "Authorization: API-Key sk_signing_your_key_here"

#All Endpoints

MethodPathDescription
POST/api/public/v1/documentsCreate envelope (draft)
GET/api/public/v1/documentsList envelopes (paginated)
GET/api/public/v1/documents/{id}Get envelope detail + status
GET/api/public/v1/documents/{id}/previewPreview template (JSON or HTML)
POST/api/public/v1/documents/{id}/sendSend envelope to signers
GET/api/public/v1/documents/{id}/downloadDownload completed/source PDF
POST/api/public/v1/documents/{id}/cancelCancel (void) envelope
GET/api/public/v1/balanceWallet balance (cents + plan)
POST/api/public/v1/topupStart 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

FieldTypeDescription
name*stringHuman-readable name of the envelope.
template_uuidstringUUID or external ID of a Geteken template.
urlstringHTTPS URL of a PDF to use directly (if template_uuid is not supplied).
recipients*arrayList of signers. See structure below.
tokensobjectKey-value pairs to pre-fill template tokens.
metadataobjectStore your own ID or reference.

#Recipient structure

FieldTypeDescription
email*stringRecipient's email address.
first_namestringFirst name.
last_namestringLast name.
rolestringRole name matching a template role (e.g. "Buyer").
signing_orderinteger1-based order. Recipients sharing the same number sign in parallel.
bash
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

json
{
  "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

ParameterTypeDefault / Description
countintegerNumber of results to return. Default: 25, max: 100.
bash
curl https://geteken.co.za/api/public/v1/documents?count=10 \
  -H "Authorization: API-Key sk_signing_..."
json
{
  "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.

bash
curl https://geteken.co.za/api/public/v1/documents/env_01abc23def456 \
  -H "Authorization: API-Key sk_signing_..."
json
{
  "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

ParameterTypeDescription
format"html"Return raw rendered HTML (Content-Type: text/html) for iframe embedding.
bash
# 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

FieldTypeDescription
messagestringCustom message included in the invitation email.
subjectstringSubject line for the invitation email.
bash
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."
  }'
json
{
  "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.

ParameterTypeDescription
inline"1"Redirect (302) directly to the signed URL instead of returning JSON.
bash
# 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
json
{
  "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.

bash
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" }'
json
{
  "id": "env_01abc23def456",
  "name": "Service Agreement — Acme Corp",
  "status": "document.voided"
}

#Status Values

The status field follows PandaDoc convention (document.*).

StatusMeaning
document.draftEnvelope created but not yet sent.
document.sentInvitations sent to signers.
document.viewedFirst recipient has opened the document.
document.partially_signedSome signers have signed, but not all.
document.completedAll signers have signed. The GOLD SEAL has been issued.
document.voidedEnvelope cancelled via the /cancel endpoint.
document.declinedA recipient declined to sign.
document.draftdocument.sentdocument.vieweddocument.partially_signeddocument.completed

#Errors

Errors are returned as JSON with an "error" key. Use the HTTP status code for control flow.

HTTPerrorWhen
400Invalid JSON bodyBody is not valid JSON.
400`name` and `recipients[]` are requiredRequired fields missing.
400invalid document_urlURL is not HTTPS or the document could not be fetched.
401Invalid or missing API keyAuthorization header missing or key invalid.
402insufficient_creditsBalance too low. upgrade: true is included in response.
403ForbiddenResource belongs to a different tenant.
404Not foundEnvelope ID does not exist.
409Cannot cancel envelope in status '...'State transition not allowed.
json
{ "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.