API reference

Send calls, read spend and export the ledger over HTTPS. Bearer-key authentication, JSON in and out.

Base URL: https://veqen-app.com. Authenticate with Authorization: Bearer vq_live_.... The OpenAPI document is at /openapi.json.

Send calls

POST /v1/events (ingest key). Up to 1,000 events and 5 MB per request (a larger batch is refused whole); Content-Encoding: gzip is welcome.

curl https://veqen-app.com/v1/events \
  -H "Authorization: Bearer $VEQEN_API_KEY" -H "Content-Type: application/json" \
  -d '{"events": [{"id": "9f1c2e7a5b3d4c6e", "ts": "2026-10-22T14:03:11Z", "provider": "openai",
        "model": "gpt-5-mini", "input_tokens": 1200, "output_tokens": 340, "cache_read_tokens": 0,
        "customer": "acme", "feature": "support-bot"}]}'
Field Type Notes
id string, 8–64 characters Unique per call. Retries with the same id and ts are stored once
ts ISO 8601 Within the last 35 days, and no more than 24 hours ahead
provider, model string As the provider names them; Veqen normalizes and prices them
input_tokens integer Uncached input
output_tokens integer Including reasoning
cache_read_tokens, cache_write_tokens, cache_write_1h_tokens integer Optional
audio_input_tokens, audio_output_tokens integer Optional, for realtime and audio models
units number Images, seconds, characters, queries or pages, for models billed per unit
variant string Image size and quality (hd/1024x1792) or video resolution (1080p)
batch boolean Batch API call
service_tier, residency string priority, flex; us
cost_usd number Kept when the model has no price, or when the call reports no usage
customer, feature, user, project, environment string See Tags
tags object Up to 32 free-form tags
latency_ms, status integer, ok or error Optional

Response:

{"accepted": 1, "duplicates": 0, "dropped": 0, "rejected": []}

dropped counts calls over your plan's cap or your own bill budget (not stored, not billed). rejected lists {"index", "error"} for invalid events; the rest of the batch is still stored.

POST /v1/otlp/v1/traces accepts OpenTelemetry instead: see OpenTelemetry.

Budget status

GET /v1/budgets/status (ingest key) → {"blocked": [{"scope": "customer", "value": "acme", "limit_usd": 5.0}]}. The SDKs poll this every 30 seconds.

Read spend

GET /v1/usage (full key)

Parameter
start, end YYYY-MM-DD, inclusive; defaults to the last 30 days; up to two years
group_by provider, model, customer, feature, user, project or environment
provider, model, customer, feature, user, project, environment Filters (exact match; an empty value means untagged)
daily true adds a per-day series
limit Groups to return, up to 1,000
{"start": "2026-09-23", "end": "2026-10-22",
 "totals": {"calls": 48211, "cost": 1284.37, "input_tokens": 51200443, "output_tokens": 9102114,
            "cache_read_tokens": 30110022, "cache_write_tokens": 1022011, "units": 12400, "unpriced_calls": 0},
 "groups": [{"key": "acme", "calls": 12001, "cost": 412.2, "share": 0.321, "...": "..."}]}

GET /v1/usage/models?days=30 (ingest key; Pro and Team) → calls and tokens per model, used by veqen diff.

GET /v1/export.csv?start=&end= (full key) → daily rollups as CSV, one row per day and tag combination.

GET /v1/account (ingest key) → organization, plan, this month's tracked calls and limits.

Prices

GET /v1/prices?model=gpt-5-mini (no key) → the model's kind, its unit if it's billed per unit, rates (per million tokens, or per unit), context window and retirement date. Add what one call uses (input_tokens, output_tokens, cached_tokens, audio_input_tokens, audio_output_tokens, units, variant, batch=true) to get cost_per_call: /v1/prices?model=sora-2&units=8 prices an 8-second clip. The whole price book is at /prices.json.

Simulate a workload

POST /v1/simulate (no key) prices a month of calls across any mix of models at list prices: the same engine as the simulator.

curl https://veqen-app.com/v1/simulate -H "Content-Type: application/json" -d '{"growth_pct": 5, "lines": [
  {"label": "support", "model": "anthropic/claude-sonnet-4-5", "calls": 600000, "input_tokens": 2400, "cached_tokens": 12000, "output_tokens": 380},
  {"label": "captions", "model": "deepgram/nova-3", "calls": 20000, "units": 1800}]}'

Each line takes the model, calls a month and what one call uses: the token fields, units (images, seconds, characters, queries or pages), variant and batch. Up to 25 lines. The response has each line's per_call, monthly and share; a ladder placing the call among every current model of its kind (cheaper_than is the share of those models that cost more); same_model, the same model on other hosts, cheapest first; and cheaper, cheaper models from the same provider. Totals: monthly, first_year, and a projection per month with growth_pct applied. Limited to a few requests a second per IP address.

Limits

Ingest: 200 requests a second per organization (batch calls instead of raising this). Read endpoints: 10 requests a second per key. Exceeding either returns 429 with Retry-After.

Request bodies: 5 MB, or 25 MB once gzip is inflated. /v1/events takes up to 1,000 events a request; an OTLP export can hold any number of spans within the size limit.