Parse API

Extract structured fields from PDFs and images using REST. This guide covers parse endpoints, API keys, job polling, and future webhooks.

Base URL

https://api.warakai.com

How it works

Parse requests are asynchronous. A successful enqueue returns HTTP 202 with a job id. Poll GET /api/v1/parse/jobs/:jobId until the job completes or fails, or subscribe to a webhook URL when we enable delivery (coming soon).

Usage rows in your account reference parseJobId — the same id as the single job or the shared bulk job id for every file in a bulk run.

Authentication

Include credentials on every request using one of:

  • Header X-Api-Key: wk_…
  • Authorization: Bearer wk_…
  • Authorization: Bearer JWT — your active API key is used for quota and usage (you still need at least one key).

API keys

Create a test or live key under API Keys. The secret is shown only once. Without an active key, parse requests return API_KEY_REQUIRED_FOR_PARSE.

Manage API keysarrow_forward

Endpoints

MethodPathDescription
POST/api/v1/parse/documentEnqueue a single document (multipart: file, schema JSON string, optional documentType).
POST/api/v1/parse/bulkEnqueue a bulk run (ZIP or multiple files) with the same schema shape.
GET/api/v1/parse/jobsList recent jobs still in Redis (summary only; may be truncated).
GET/api/v1/parse/jobs/:jobIdPoll job status; response has either bulk or single object.

POST /api/v1/parse/document

Send multipart/form-data with a file and a schema field containing a JSON string that describes field names and types. Successful responses return 202 with id, status, and createdAt.

Form fields

file
PDF or image (allowed types depend on your plan).
schema
JSON string, e.g. {"total":"number","vendor":"string"}.
documentType
Optional label (max 40 characters).

On success you may receive X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Plan.

Request
curl -sS -X POST "https://api.warakai.com/api/v1/parse/document" \ -H "X-Api-Key: wk_your_key_here" \ -F "file=@invoice.pdf" \ -F 'schema={"total":"number","vendor":"string"}' \ -F "documentType=invoice"
Response · 202 Accepted
{ "id": "550e8400-e29b-41d4-a716-446655440000", "status": "queued", "createdAt": "2026-01-01T12:00:00.000Z" }

POST /api/v1/parse/bulk

Same multipart pattern, but uploads go to object storage for large batches. Use one ZIP archive, or attach multiple file parts as documented in Postman.

Bulk jobs return a single job id; each file’s usage row shares the same parseJobId.

Request
curl -sS -X POST "https://api.warakai.com/api/v1/parse/bulk" \ -H "X-Api-Key: wk_your_key_here" \ -F 'schema={"total":"number","vendor":"string"}' \ -F "file=@archive.zip"
Response · 202 Accepted
{ "id": "550e8400-e29b-41d4-a716-446655440001", "status": "processing", "createdAt": "2026-01-01T12:00:00.000Z", "finishedAt": null }

GET /api/v1/parse/jobs

Returns jobs and truncated when more rows existed than the server limit. Use GET /api/v1/parse/jobs/:jobId for full detail.

Request
curl -sS "https://api.warakai.com/api/v1/parse/jobs" \ -H "X-Api-Key: wk_your_key_here" \ -H "Accept: application/json"
Response · 200 OK
{ "jobs": [ { "kind": "bulk", "id": "550e8400-e29b-41d4-a716-446655440001", "status": "processing", "createdAt": "2026-01-01T12:00:00.000Z", "finishedAt": null, "totalFiles": 3, "processedFiles": 1, "failedFiles": 0 }, { "kind": "single", "id": "550e8400-e29b-41d4-a716-446655440002", "status": "processing", "createdAt": "2026-01-01T11:59:00.000Z", "finishedAt": null } ], "truncated": false }

GET /api/v1/parse/jobs/:jobId

Exactly one of bulk or single is non-null. When completed, single.fields holds extracted values with confidence. Failed jobs may include single.error or bulk.errors.

Request
curl -sS "https://api.warakai.com/api/v1/parse/jobs/JOB_ID" \ -H "X-Api-Key: wk_your_key_here" \ -H "Accept: application/json"
Response · 200 OK — Single job
{ "bulk": null, "single": { "id": "550e8400-e29b-41d4-a716-446655440000", "status": "completed", "createdAt": "2026-01-01T12:00:00.000Z", "finishedAt": "2026-01-01T12:00:15.000Z", "fields": { "total": { "value": 99.5, "confidence": 0.95 }, "vendor": { "value": "Acme LLC", "confidence": 0.88 } }, "usageLogId": "660e8400-e29b-41d4-a716-446655440000" } }
Response · 200 OK — Bulk job
{ "bulk": { "id": "550e8400-e29b-41d4-a716-446655440001", "userId": "770e8400-e29b-41d4-a716-446655440000", "status": "completed_with_errors", "totalFiles": 3, "processedFiles": 2, "failedFiles": 1, "createdAt": "2026-01-01T12:00:00.000Z", "finishedAt": "2026-01-01T12:05:00.000Z", "errors": [ { "docId": "uuid:parse/bulk/uuid/bad.pdf", "fileName": "bad.pdf", "code": "DOCUMENT_FAILED", "message": "Could not process file", "at": "2026-01-01T12:03:00.000Z" } ] }, "single": null }

Rate limits & quotas

Plan quotas and per-minute parse rate limits apply. A 429 response includes a machine-readable code (e.g. RATE_LIMIT_PARSE_DOCUMENT or LIMIT_EXCEEDED).

Errors

Typical JSON error shape:

Validation errors may include a details object. Always log requestId when contacting support.

Example error
{ "error": "Too many parse requests. Try again in a minute.", "code": "RATE_LIMIT_PARSE_DOCUMENT", "requestId": "880e8400-e29b-41d4-a716-446655440000" }

Webhooks

schedule

You will be able to register an HTTPS URL to receive job completion payloads (signed) for your integration. This is not active yet — poll until then.

When enabled, we will document the payload schema, signature verification, and retry policy here.