Skip to main content
Developers

Getting Started with the Papyrus API

Authenticate, make your first call, upload a document, and read back the AI-extracted metadata — all from cURL.

Getting Started with the Papyrus API

This is the 5-minute version. By the end you will have uploaded a document via API and read back the AI extraction.

Step 1 — Get an API key

In your tenant, navigate to Admin → API Keys → New Key. Choose the scopes:

  • documents:read — list and fetch documents
  • documents:write — upload, update, delete
  • workflows:write — start workflows

Copy the key immediately — it's shown once. Treat it like a password.

Step 2 — Authenticate

Every request includes Authorization: Bearer <key> and X-Tenant-Id: <tenant-slug>:

curl https://yourtenant.papyrus.io/api/v1/documents \
  -H "Authorization: Bearer pk_live_xxxxxxxxxxxx" \
  -H "X-Tenant-Id: yourtenant"

Successful authentication returns 200 + a paginated document list.

Step 3 — Upload a document

Multipart form upload:

curl https://yourtenant.papyrus.io/api/v1/documents \
  -X POST \
  -H "Authorization: Bearer pk_live_xxxxxxxxxxxx" \
  -H "X-Tenant-Id: yourtenant" \
  -F "file=@invoice.pdf" \
  -F "folderId=11111111-1111-1111-1111-111111111111" \
  -F "tags=invoice,acme,2026-q2"

Response (truncated):

{
  "success": true,
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "title": "invoice.pdf",
    "status": "Processing",
    "uploadedAt": "2026-05-13T14:32:11Z"
  },
  "meta": { "requestId": "req_8a3b9c2d" }
}

The document is now being processed. Classification and extraction typically complete within 30 seconds.

Step 4 — Read back the AI extraction

Poll the document until processing is complete:

curl https://yourtenant.papyrus.io/api/v1/documents/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: Bearer pk_live_xxxxxxxxxxxx" \
  -H "X-Tenant-Id: yourtenant"

Once status is Active, the response includes AI fields:

{
  "success": true,
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "title": "Invoice INV-2026-0418",
    "status": "Active",
    "aiClassification": {
      "type": "Invoice",
      "confidence": 0.94
    },
    "extractedFields": {
      "invoiceNumber": "INV-2026-0418",
      "issueDate": "2026-04-18",
      "vendorName": "Acme Ltd",
      "vendorKraPin": "P051234567A",
      "totalAmount": 145000.00,
      "currency": "KES"
    }
  }
}

Better: subscribe to a webhook

Polling works but webhooks scale better. See Webhook Events and Payload Reference.

What's next

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.