PapermarkDocs

Getting started

Make your first API request.

The Papermark API is HTTP, JSON, and bearer-token-authenticated. There is no SDK to install — every endpoint is one fetch away.

Base URL

https://api.papermark.com

All endpoints sit under /v1/. The v1 prefix is in the path, not a header — so the absolute path of the documents list is /v1/documents.

Authentication

Every request carries an Authorization: Bearer … header. Mint a token in the dashboard at Settings → API Tokens (pm_live_…) and treat it like a password. See Authentication for the spec, including the OAuth 2.1 device flow.

Your first request

curl https://api.papermark.com/v1/documents \
  -H "Authorization: Bearer pm_live_…"

Response shape:

{
  "data": [
    {
      "id": "doc_…",
      "name": "Pitch Deck.pdf",
      "createdAt": "2026-04-22T12:34:56.000Z",
      "updatedAt": "2026-04-22T12:34:56.000Z"
    }
  ],
  "next_cursor": null
}

Empty? You don't have any documents yet. Upload one:

# Step 1: get a presigned upload URL
curl -X POST https://api.papermark.com/v1/documents/upload-url \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{"filename": "pitch.pdf", "contentType": "application/pdf"}'

# Step 2: PUT the file to the returned `uploadUrl`

# Step 3: register the document
curl -X POST https://api.papermark.com/v1/documents \
  -H "Authorization: Bearer pm_live_…" \
  -H "Content-Type: application/json" \
  -d '{"name": "Pitch Deck", "key": "<the s3 key from step 1>"}'

The CLI does all three steps in one call — papermark documents upload ./pitch.pdf — but doing it directly is good practice for understanding the surface.

Pagination

List endpoints return up to 25 records by default and accept:

  • ?limit=N — between 1 and 100
  • ?cursor=<id> — pass back the next_cursor from the previous response

When next_cursor is null, there are no more pages.

curl "https://api.papermark.com/v1/documents?limit=50&cursor=doc_KlmN456" \
  -H "Authorization: Bearer pm_live_…"

Errors

Failures come back with HTTP 4xx/5xx and a structured envelope:

{
  "error": {
    "code": "unauthorized",
    "message": "Bearer token missing or invalid.",
    "doc_url": "https://papermark.com/docs/api/errors#unauthorized"
  }
}

Every error.code has a matching anchor on the Errors page so the doc_url resolves.

Rate limits

The default budget is 60 requests per minute per token. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so you can pace yourself. See Rate limits.

Where to go next

  • Reference — every endpoint, generated from openapi.json
  • Scopes — what each scope unlocks
  • CLI — the same surface from the command line

On this page