DocsGetting Started

Getting Started

Create an API key, add funds, and run your first extraction in a few minutes.

Veralens turns messy inputs — document images, scans, and raw text — into clean, structured data. You describe the shape you want with a JSON Schema (or a natural-language prompt), send your sources, and get back typed JSON, Markdown, or plaintext.

Everything runs as an asynchronous job: you create a job, then poll it (or receive a webhook) for the result. This page takes you from zero to your first extraction.

1. Create an account and an API key

  1. Sign up at veralens.ai.
  2. Open Keys in the dashboard and create a key.
  3. Copy the secret — it starts with vl_ and is shown once. Store it somewhere safe.

API keys authenticate programmatic requests. You pass the secret as a Bearer token:

http
Authorization: Bearer vl_your_secret_key

2. Add funds

Veralens is prepaid. Open Billing in the dashboard and add funds. Each job places a small hold on your balance when it is created and settles to the real cost when it finishes. Failed jobs are refunded. See Pricing & Funds for the details.

3. Run your first extraction

Send one or more sources and a schema describing the output. The base URL is:

text
https://api.veralens.ai/v1
bash
curl -X POST https://api.veralens.ai/v1/jobs/create \
  -H "Authorization: Bearer vl_your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      { "type": "text", "data": "Invoice #A-1029 — Acme Corp — Total: $412.50 — Due 2025-03-01" }
    ],
    "schema": {
      "type": "object",
      "properties": {
        "invoiceNumber": { "type": "string", "description": "Invoice or reference number exactly as printed." },
        "vendor":        { "type": "string", "description": "Company that issued the invoice." },
        "total":         { "type": "number", "description": "Total amount due. Dot as decimal separator." },
        "dueDate":       { "type": "string", "description": "Due date in ISO format YYYY-MM-DD." }
      },
      "required": ["invoiceNumber", "total"]
    }
  }'

The response is the full job, already in pending — the same shape you'll poll later. usage.cost here is the precharge hold (an estimate); output and the settled usage arrive once it finishes:

json
{
  "status": "success",
  "data": {
    "id": "V1StGXR8_Z5jdHi6B",
    "status": "pending",
    "target": "json",
    "model": "vera-1.0-high",
    "usage": { "cost": 0.0021, "inputTokens": null, "outputTokens": null },
    "output": null,
    "durationMs": null
  }
}

4. Get the result

Poll the job until its status is no longer pending:

bash
curl https://api.veralens.ai/v1/jobs/V1StGXR8_Z5jdHi6B/get \
  -H "Authorization: Bearer vl_your_secret_key"
json
{
  "status": "success",
  "data": {
    "id": "V1StGXR8_Z5jdHi6B",
    "status": "completed",
    "target": "json",
    "model": "vera-1.0-high",
    "output": "{\"invoiceNumber\":\"A-1029\",\"vendor\":\"Acme Corp\",\"total\":412.5,\"dueDate\":\"2025-03-01\"}",
    "usage": { "cost": 0.0021, "inputTokens": 48, "outputTokens": 32 },
    "durationMs": 1840
  }
}

The extracted data is a JSON string in output — parse it on your side.

In production, prefer webhooks over polling. Pass a webhook_url when you create the job and Veralens posts the result to you the moment it's ready — no polling loop, lower latency, and less load on both sides. See Jobs & Queue.

Full example (JavaScript)

js
const BASE = "https://api.veralens.ai/v1"
const KEY = process.env.VERALENS_API_KEY

async function extract(text) {
  const create = await fetch(`${BASE}/jobs/create`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      sources: [{ type: "text", data: text }],
      schema: {
        type: "object",
        properties: {
          title: { type: "string", description: "Document title." },
          date: { type: "string", description: "Date in YYYY-MM-DD." },
        },
        required: ["title"],
      },
    }),
  })
  const { data } = await create.json()

  //poll until the job leaves the pending state
  while (true) {
    const res = await fetch(`${BASE}/jobs/${data.id}/get`, {
      headers: { Authorization: `Bearer ${KEY}` },
    })
    const job = (await res.json()).data
    if (job.status !== "pending") return JSON.parse(job.output ?? "null")
    await new Promise((r) => setTimeout(r, 1000))
  }
}

Next steps