API Reference
Endpoints, request and response shapes, authentication, and error codes.
The Veralens REST API is a small, predictable surface. Every endpoint lives under one base URL, speaks JSON, and returns the same envelope shape whether it succeeds or fails.
Authentication
Programmatic requests authenticate with an API key as a Bearer token. Create keys under API Keys in the dashboard. Each secret starts with vl_ and is shown once.
Key management endpoints (create, list, rotate, revoke) are part of the dashboard and use your logged-in session. You cannot manage keys with an API key. Everything below under Jobs accepts an API key.
Response envelope
Success responses wrap the payload in data:
Errors carry a stable error_code plus a matching HTTP status:
Branch on the HTTP status and error_code. The codes are stable, and human-readable text is advisory only.
POST /jobs/create
Create an extraction job. Returns immediately with a job id; the work runs asynchronously.
Body
You must send at least one of schema or target. Provide a schema for strict typed JSON, or only a target (with an optional global_prompt) for freeform Markdown/plaintext or schemaless JSON.
Source types
Document limits, all returned as 400:
- 20 MB per file, measured on the decoded file, not the base64 text (
job_document_too_large). - 200 pages per PDF (
job_document_too_many_pages). - 800,000 characters of text per Word, Excel, CSV, text or Markdown file (
job_document_content_too_large).
PDFs are read page by page as images. The other document types are read as text.
Response: 201 Created. Returns the full job object (same shape as GET /jobs/:jobId/get below), already in pending. model, target, and the hold (usage.cost) are set immediately. output and settled token usage fill in once the job runs.
Example
GET /jobs/:jobId/get
Fetch a single job by id. Poll this until status is no longer pending.
Response
Job fields
GET /jobs/list
List your jobs, most recent first.
Query parameters
Response
Error codes
These come back on the request itself, with the HTTP status shown.
A job that ends failed. Once a job is created, a failure does not come back as an error_code. The job's status turns failed, the webhook (if any) gets { "status": "error", "job_id": "..." }, and the hold is refunded in full, so a failure costs nothing. Jobs are retried before they are marked failed. If the same document keeps failing, send a smaller document or ask for fewer fields.
Rate limits
Limits apply per API key and per endpoint. Each endpoint has a short and a long window, and you must stay under both.
Over a limit you get 429 rate_limit_exceeded with these headers:
To wait for one job, fetch it every 2 to 3 seconds, or use a webhook and don't poll at all.