Pluckbox

Pluckbox API

Turn PDFs, images and emails into the JSON fields you define, each with a confidence score. Every request carries an API key as Authorization: Bearer pbk_…

The OpenAPI 3.1 file is at /openapi.json: import it into Postman, Insomnia or a client generator.

Quickstart

Sign in at https://pluckbox.onibaku.co.uk/app and copy your key. Then make a parser, send it a PDF and read the result:

curl https://pluckbox.onibaku.co.uk/v1/parsers -H "Authorization: Bearer $PLUCKBOX_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Invoices","template":{"type":"object","properties":{"invoice_number":{"type":"string"},"total":{"type":"number"}}}}'

curl https://pluckbox.onibaku.co.uk/v1/parsers/1/documents -H "Authorization: Bearer $PLUCKBOX_KEY" \
  -H "Content-Type: application/pdf" --data-binary @invoice.pdf

curl https://pluckbox.onibaku.co.uk/v1/documents/1 -H "Authorization: Bearer $PLUCKBOX_KEY"

Documents parse in the background, usually in a few seconds. Poll the document, or add a webhook and we’ll post it to you, signed with Pluckbox-Signature: t=<unix time>,v1=<hex HMAC-SHA256 of "t.body">. Failed deliveries retry 8 times over about two days.

Every field comes back with a confidence from 0 to 1. Anything under the parser’s threshold sets needsReview and lists the field in lowConfidenceFields; correct it with PATCH /v1/documents/{id}. A field left blank scores 0 and sends the document to review, unless the template’s required list leaves it out.

Errors are RFC 9457 problem details. Each key gets 120 requests a minute; the RateLimit-* headers say how many are left.

Account

GET /v1/openapi.json

This OpenAPI document.

No key needed.

GET /v1/me

The key’s workspace, scopes and usage.

Scope: read

GET /v1/usage

Pages used this month and the plan’s allowance.

Scope: read

Parsers

GET /v1/parsers

List parsers.

Scope: read

POST /v1/parsers

Create a parser.

Scope: parsers:write

POST /v1/parsers/infer

Propose a template from a sample document. Doesn’t create anything or use pages. Send the result to POST /v1/parsers. Limited to 20 a day.

Scope: parsers:write

GET /v1/parsers/{id}

Get a parser.

Scope: read

PATCH /v1/parsers/{id}

Change a parser. Send only what changes.

Scope: parsers:write

DELETE /v1/parsers/{id}

Delete a parser and its documents.

Scope: parsers:write

GET /v1/parsers/{id}/export

Export a parser’s documents as CSV or JSON.

Scope: read

Documents

POST /v1/parsers/{id}/documents

Send a document to a parser. Queues it and returns straight away; poll GET /v1/documents/{id} or use a webhook. Pages are counted now and refunded if it fails for good. Up to 20 MB and 50 pages.

Scope: documents:write

GET /v1/documents

List documents, newest first. Also works as a Zapier polling trigger: deduplicate on id.

Scope: read

GET /v1/documents/{id}

Get a document and its fields.

Scope: read

PATCH /v1/documents/{id}

Review a document: correct fields or approve it. Corrected fields get confidence 1 and the document becomes parsed. Fires document.reviewed.

Scope: documents:write

DELETE /v1/documents/{id}

Delete a document and its file.

Scope: documents:write

POST /v1/documents/{id}/retry

Parse a document again.

Scope: documents:write

Webhooks

GET /v1/webhooks

List webhooks.

Scope: read

POST /v1/webhooks

Add a webhook (Zapier: subscribe).

Scope: webhooks:write

DELETE /v1/webhooks/{id}

Remove a webhook (Zapier: unsubscribe).

Scope: webhooks:write

GET /v1/webhooks/{id}/deliveries

The last 50 deliveries to a webhook.

Scope: read

Keys

GET /v1/keys

List API keys.

Scope: read

POST /v1/keys

Create an API key.

Scope: keys:write

POST /v1/keys/{id}/rotate

Rotate a key. Makes a new key with the same name and scopes. The old one keeps working for graceHours (default 24).

Scope: keys:write

DELETE /v1/keys/{id}

Revoke a key now.

Scope: keys:write