Papersaurus API Documentation

Base URL: http://api.papersaurus.com

Authentication

{
  "public": "No Authorization header.",
  "api": "Authorization: Bearer ak_your_api_key",
  "admin": "Authorization: Bearer ADMIN_TOKEN"
}

Roles

[
  {
    "role": "owner",
    "process": true,
    "manageKeys": true,
    "readAccount": true
  },
  {
    "role": "admin",
    "process": true,
    "manageKeys": true,
    "readAccount": true
  },
  {
    "role": "worker",
    "process": true,
    "manageKeys": false,
    "readAccount": true
  },
  {
    "role": "readonly",
    "process": false,
    "manageKeys": false,
    "readAccount": true
  }
]

Workflow

  1. POST /account/request
  2. Open emailed /account/claim/:token link
  3. Copy API key
  4. POST /api/estimate
  5. POST /api/process or /api/process-async
  6. Decode returned contentsBase64 or download using downloadUrl

Decode returned PDF

curl -s -X POST http://api.papersaurus.com/api/process \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"message":"make a one page dinosaur fact sheet"}' \
  | python3 -c 'import sys,json,base64; r=json.load(sys.stdin); f=r["pdfFiles"][0]; open(f["filename"],"wb").write(base64.b64decode(f["contentsBase64"]))'

Endpoints

GET /health

Health check.

Auth: none

curl

curl -s http://api.papersaurus.com/health

Example response

{
  "ok": true,
  "delegatedUser": "printer@papersaurus.com",
  "billingRate": {
    "usdPerMillionOutputChars": 1
  }
}

GET /openapi.json

Machine-readable OpenAPI spec.

Auth: none

curl

curl -s http://api.papersaurus.com/openapi.json

Example response

{
  "openapi": "3.1.0",
  "info": {
    "title": "Voicemail Artifact API",
    "version": "1.0.0"
  }
}

POST /account/request

Request an emailed account claim link.

Auth: none

curl

curl -s -X POST http://api.papersaurus.com/account/request \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com"}'

Example response

{
  "ok": true,
  "sent": true,
  "email": "you@example.com",
  "expiresAt": "2026-06-23T20:14:31.000Z"
}

GET /account/claim/:token

Claim an account request and display the API key once.

Auth: none

curl

curl -L "http://api.papersaurus.com/account/claim/CLAIM_TOKEN"

Example response

Returns an HTML page containing the new API key.

POST /api/estimate

Estimate output size and cost.

Auth: api key

curl

curl -s -X POST http://api.papersaurus.com/api/estimate \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"message":"create a Yosemite postcard"}'

Example response

{
  "ok": true,
  "estimatedOutputChars": 28000,
  "estimatedCostUsd": 0.028,
  "creditBalanceUsd": 49.97,
  "monthSpendUsd": 1.22,
  "billingRate": {
    "usdPerMillionOutputChars": 1
  }
}

POST /api/process

Run a synchronous processing job. Supports Idempotency-Key.

Auth: api key: owner, admin, worker

curl

curl -s -X POST http://api.papersaurus.com/api/process \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Idempotency-Key: customer-job-001" \
  -H "Content-Type: application/json" \
  -d '{"message":"create a printable Yosemite postcard","emails":["you@example.com"]}'

Example response

{
  "ok": true,
  "requestId": "c1f25d97-f82d-4974-9fd9-ffb6f48c88fb",
  "apiCaller": "production",
  "apiCallerRole": "owner",
  "apiCallerEmail": "you@example.com",
  "returnedFileBytes": 148201,
  "outputChars": 22491,
  "billableUsd": 0.022491,
  "creditBalanceUsd": 49.95,
  "billingRate": {
    "usdPerMillionOutputChars": 1
  },
  "pdfFiles": [
    {
      "filename": "yosemite-postcard.pdf",
      "contentsBase64": "JVBERi0xLjQ..."
    }
  ],
  "htmlFiles": [],
  "urls": []
}

POST /api/cards

Create or replace a public NFC card website and return the URL to write to the card.

Auth: api key: owner, admin, worker

curl

curl -s -X POST http://api.papersaurus.com/api/cards \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"uuid":"demo-card-001","title":"Demo Papersaurus Card","description":"Created by NFC writer","metadata":{"createdAtMillis":1783961937000,"latitude":37.441883,"longitude":-122.143019}}'

Example response

{
  "ok": true,
  "card": {
    "uuid": "demo-card-001",
    "title": "Demo Papersaurus Card",
    "url": "http://api.papersaurus.com/card/demo-card-001",
    "metadata": {
      "createdAtMillis": 1783961937000,
      "latitude": 37.441883,
      "longitude": -122.143019
    }
  }
}

GET /api/cards

List NFC cards created by the current account.

Auth: api key

curl

curl -s "http://api.papersaurus.com/api/cards?limit=100" \
  -H "Authorization: Bearer ak_your_api_key"

Example response

{
  "ok": true,
  "cards": []
}

GET /card/:uuid

Public NFC card website. This is the URL written to the card.

Auth: none

curl

curl -L http://api.papersaurus.com/card/demo-card-001

Example response

Returns HTML.

POST /api/process-async

Start an async job. Poll /api/jobs/:id or use webhookUrl.

Auth: api key: owner, admin, worker

curl

curl -s -X POST http://api.papersaurus.com/api/process-async \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"message":"create a kids trivia game","webhookUrl":"https://example.com/webhook"}'

Example response

{
  "ok": true,
  "async": true,
  "requestId": "6c5c0dd7-ef62-4f86-9f8a-0b5677d72d0c",
  "status": "queued",
  "checkUrl": "/api/jobs/6c5c0dd7-ef62-4f86-9f8a-0b5677d72d0c",
  "estimatedOutputChars": 30000,
  "estimatedCostUsd": 0.03
}

GET /api/jobs/:id

Check an async job owned by this API key.

Auth: api key

curl

curl -s http://api.papersaurus.com/api/jobs/REQUEST_ID \
  -H "Authorization: Bearer ak_your_api_key"

Example response

{
  "ok": true,
  "async": true,
  "requestId": "6c5c0dd7-ef62-4f86-9f8a-0b5677d72d0c",
  "status": "completed",
  "result": {
    "ok": true,
    "pdfFiles": [
      {
        "filename": "trivia-game.pdf",
        "contentsBase64": "JVBERi0xLjQ...",
        "downloadUrl": "http://api.papersaurus.com/api/download/REQUEST_ID/pdf/0?sig=SIGNED_VALUE"
      }
    ],
    "htmlFiles": [],
    "urls": []
  }
}

GET /api/download/:requestId/:type/:index

Download a generated PDF or HTML file.

Auth: api key + signed URL

curl

curl -L "http://api.papersaurus.com/api/download/REQUEST_ID/pdf/0?sig=SIGNED_VALUE" \
  -H "Authorization: Bearer ak_your_api_key" \
  -o output.pdf

Example response

Binary PDF or HTML response.

GET /account/balance

Get account credit balance and limits.

Auth: api key

curl

curl -s http://api.papersaurus.com/account/balance \
  -H "Authorization: Bearer ak_your_api_key"

Example response

{
  "ok": true,
  "email": "you@example.com",
  "role": "owner",
  "balanceUsd": 49.95,
  "monthSpendUsd": 3.81,
  "hardLimitUsd": 100,
  "monthlyLimitUsd": 100
}

GET /account/api-keys

List API keys for this account.

Auth: api key

curl

curl -s http://api.papersaurus.com/account/api-keys \
  -H "Authorization: Bearer ak_your_api_key"

Example response

{
  "ok": true,
  "apiKeys": [
    {
      "id": "8cb35c91-0000-0000-0000-000000000001",
      "name": "production",
      "role": "owner",
      "revoked": false,
      "created_at": "2026-06-23T20:00:00.000Z",
      "revoked_at": null
    }
  ]
}

POST /account/api-keys

Create a secondary account API key.

Auth: api key: owner, admin

curl

curl -s -X POST http://api.papersaurus.com/account/api-keys \
  -H "Authorization: Bearer ak_owner_or_admin_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"production-worker","role":"worker"}'

Example response

{
  "ok": true,
  "apiKey": {
    "id": "91a82c91-0000-0000-0000-000000000002",
    "name": "production-worker",
    "email": "you@example.com",
    "role": "worker",
    "key": "ak_new_key_returned_once"
  }
}

DELETE /account/api-keys/:id

Revoke a secondary API key.

Auth: api key: owner, admin

curl

curl -s -X DELETE http://api.papersaurus.com/account/api-keys/API_KEY_ID \
  -H "Authorization: Bearer ak_owner_or_admin_key"

Example response

{
  "ok": true,
  "revoked": true
}

GET /account/statement.json

Download account statement as JSON.

Auth: api key

curl

curl -s http://api.papersaurus.com/account/statement.json \
  -H "Authorization: Bearer ak_your_api_key"

Example response

{
  "ok": true,
  "email": "you@example.com",
  "balanceUsd": 49.95,
  "transactions": [
    {
      "type": "usage",
      "amount_usd": -0.022491,
      "output_chars": 22491
    }
  ]
}

GET /account/statement.csv

Download account statement as CSV.

Auth: api key

curl

curl -s http://api.papersaurus.com/account/statement.csv \
  -H "Authorization: Bearer ak_your_api_key"

Example response

id,email,api_key_id,request_id,type,amount_usd,output_chars,memo,created_at

POST /billing/create-checkout

Placeholder billing checkout endpoint.

Auth: api key

curl

curl -s -X POST http://api.papersaurus.com/billing/create-checkout \
  -H "Authorization: Bearer ak_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"amountUsd":25}'

Example response

{
  "ok": true,
  "mode": "manual_or_stripe_placeholder",
  "email": "you@example.com",
  "amountUsd": 25
}

POST /billing/webhook

Billing webhook placeholder.

Auth: none

curl

curl -s -X POST http://api.papersaurus.com/billing/webhook \
  -H "Content-Type: application/json" \
  -d '{"event":"payment_succeeded"}'

Example response

{
  "ok": true
}

POST /admin/api-keys

Create an API key for any account.

Auth: admin token

curl

curl -s -X POST http://api.papersaurus.com/admin/api-keys \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"customer@example.com","name":"owner-key","role":"owner"}'

Example response

{
  "ok": true,
  "apiKey": {
    "id": "8cb35c91-0000-0000-0000-000000000001",
    "name": "owner-key",
    "email": "customer@example.com",
    "role": "owner",
    "key": "ak_new_key_returned_once"
  }
}

GET /admin/api-keys

List all API keys.

Auth: admin token

curl

curl -s http://api.papersaurus.com/admin/api-keys \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "apiKeys": []
}

POST /admin/api-keys/:id/revoke

Revoke any API key.

Auth: admin token

curl

curl -s -X POST http://api.papersaurus.com/admin/api-keys/API_KEY_ID/revoke \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "revoked": true
}

POST /admin/credits/apply

Apply account credit.

Auth: admin token

curl

curl -s -X POST http://api.papersaurus.com/admin/credits/apply \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"customer@example.com","amountUsd":50,"memo":"Initial credit"}'

Example response

{
  "ok": true,
  "email": "customer@example.com",
  "appliedUsd": 50,
  "balanceUsd": 50
}

POST /admin/accounts/set-limit

Set account limits or enabled state.

Auth: admin token

curl

curl -s -X POST http://api.papersaurus.com/admin/accounts/set-limit \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"customer@example.com","hardLimitUsd":100,"monthlyLimitUsd":25,"enabled":true}'

Example response

{
  "ok": true,
  "account": {
    "email": "customer@example.com",
    "enabled": true
  }
}

GET /admin/accounts

List accounts.

Auth: admin token

curl

curl -s http://api.papersaurus.com/admin/accounts \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "accounts": []
}

GET /admin/transactions

List credit transactions. Supports email, apiKeyId, limit.

Auth: admin token

curl

curl -s "http://api.papersaurus.com/admin/transactions?email=customer@example.com&limit=100" \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "email": "customer@example.com",
  "transactions": []
}

GET /admin/ledger

List usage ledger rows.

Auth: admin token

curl

curl -s "http://api.papersaurus.com/admin/ledger?limit=100" \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "ledger": []
}

GET /admin/usage-summary

Summarize usage by API key.

Auth: admin token

curl

curl -s http://api.papersaurus.com/admin/usage-summary \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "usage": []
}

GET /admin/jobs

List async jobs.

Auth: admin token

curl

curl -s "http://api.papersaurus.com/admin/jobs?limit=100" \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "jobs": []
}

GET /admin/cards

Download all NFC card records as JSON.

Auth: admin token

curl

curl -s "http://api.papersaurus.com/admin/cards?limit=5000" \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "count": 0,
  "cards": []
}

GET /admin/cards.csv

Download all NFC card records as CSV.

Auth: admin token

curl

curl -L "http://api.papersaurus.com/admin/cards.csv" \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -o papersaurus-cards.csv

Example response

Returns text/csv attachment.

GET /admin/audit-log

List audit log entries.

Auth: admin token

curl

curl -s "http://api.papersaurus.com/admin/audit-log?limit=100" \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "auditLog": []
}

POST /admin/cleanup

Clean up expired jobs.

Auth: admin token

curl

curl -s -X POST http://api.papersaurus.com/admin/cleanup \
  -H "Authorization: Bearer ADMIN_TOKEN"

Example response

{
  "ok": true,
  "deletedJobs": 3
}

Errors

[
  {
    "status": 400,
    "error": "invalid_request"
  },
  {
    "status": 401,
    "error": "invalid_or_revoked_api_key"
  },
  {
    "status": 401,
    "error": "unauthorized_admin"
  },
  {
    "status": 402,
    "error": "account_disabled"
  },
  {
    "status": 402,
    "error": "insufficient_credits"
  },
  {
    "status": 403,
    "error": "insufficient_api_key_role"
  },
  {
    "status": 404,
    "error": "job_not_found"
  },
  {
    "status": 409,
    "error": "idempotency_key_reused_with_different_request"
  },
  {
    "status": 429,
    "error": "rate_limited"
  }
]