API reference
Every call goes to your issued base URL — https://api.verdictlabs.eu.org/…, path included. All endpoints speak JSON.
Overview
| Endpoint | Key | Purpose |
|---|---|---|
POST /v1/decisions | optional | Ask questions about one input. |
GET /v1/models | no | The served models. |
GET /api/info | no | Models, limits and service metadata as JSON. |
GET /api/status | no | Service state and latency. |
GET /api/stats | no | Aggregate usage counters. |
POST /api/keys/challenge | no | Start key creation (returns a proof-of-work challenge). |
POST /api/keys | no | Finish key creation. |
GET /api/keys/self | yes | Your key's status and usage. |
DELETE /api/keys/self | yes | Revoke your key. |
Authentication
No key is required. Your base URL carries the access path; treat that URL as the credential
and do not publish it. Calls made without the path return the same 404 as any unknown
route.
If you do send a key it must be valid; an unknown or revoked key is rejected with 401.
Keys are optional and free: created on this site in one click, without an account, or from a terminal with the two proof-of-work calls below. Only a hash of each key is stored; a lost key cannot be recovered — create another one.
POST /api/keys/challenge -> {"challenge":"...","difficulty":20,"expires_at":"..."}
POST /api/keys -> {"challenge":"...","nonce":"...","accept_terms":true}
<- {"api_key":"sk-vrd-...","key_id":"...","created_at":"..."}
Solve the challenge by finding a decimal nonce such that SHA-256 of
challenge + ":" + nonce starts with difficulty zero bits.
Request format
| Field | Type | Meaning |
|---|---|---|
model | string | One of the model IDs below. |
state | string | The input the questions are about. |
questions | object | Question IDs, each with its question. Answers return under the same IDs. |
images | string[] | Optional base64 data URLs (PNG, JPEG, WebP). |
videos | string[] | Optional base64 data URLs (MP4, WebM, QuickTime, Matroska). |
states | object | Optional. Several inputs in one call, each with its own state and questions. |
Ask everything you need about one input in a single request: the input is read once and every question is answered together.
Question types
| Type | Asks | Fields | Answer |
|---|---|---|---|
choice | Which option fits? | criteria: 2 or more options | choice, probabilities, confidence |
noul | Yes or no? | optional criteria: {false, true} descriptions | noul: probability of yes |
score | How much, on an ordered scale? | criteria: 2 to 10 levels, lowest first | score: expected level, probabilities |
box | Where is it in the image? | none; the state carries one image | box: top, left, bottom, right, confidence |
Every question carries type and instructions. Box questions are answered
by the flagship model only.
Responses
{
"answers": {
"route": {"type":"choice","choice":"engineering",
"probabilities":{"billing":0.0004,"engineering":0.9996,"sales":0.0000},
"confidence":0.9993},
"urgent": {"type":"noul","noul":0.87}
},
"model": "vrd/decision-1",
"usage": {"input_tokens": 141, "output_tokens": 0}
}
Decision models produce no text: output_tokens is always 0 and
usage.input_tokens counts the input read by every question.
Models
| ID | Name | Profile | Inputs |
|---|---|---|---|
vrd/decision-1 | decision-1 | flagship | text, image, video |
Limits
No quotas on keys. Keys have no per-minute budget, no daily quota and no
concurrency cap. Calls are served without a key; the only usage ceiling is a shared budget of 6.9M input tokens per minute — and more than a normal client can absorb, so a 429 is the ceiling anyway. Exceeding it returns retry-after in seconds; honour it and do not hot-loop. The request
timeout is 180 seconds.
Request-size limits are technical, not usage limits:
| Body | 64 MB |
| Questions per request | 64 |
Inputs (states) | 8 |
| Images per request | 4 |
| Videos per request | 1 (60 s) |
Characters per state | 32,000 |
Errors
{"error":{"type":"invalid_request","code":"model_unknown","message":"..."}}
| HTTP | Type | When |
|---|---|---|
| 400 | invalid_request | Malformed JSON, missing model or questions, unknown model, invalid question. |
| 401 | unauthorized | An unknown or revoked key was sent. |
| 413 | request_too_large | Body over the size limit. |
| 429 | rate_limited | The service is over its token budget; honour retry-after. |
| 503 | service_busy | The service is saturated; retry shortly. |
| 504 | timeout | The model did not finish in time. |
Support
support@verdictlabs.eu.org