Appearance
API overview
Verity exposes a small read-focused JSON API, plus one write endpoint for creating entities, and outbound webhooks for review lifecycle events.
Base
https://<your-verity-host>/api/v1All requests need a bearer API key. Every response is scoped to that key's account, and nothing crosses the boundary.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/entities | List entities in the account (paginated) |
POST | /api/v1/entities | Create an entity and run its configured intake checks |
GET | /api/v1/entities/:id | One entity with its checks and reviews |
GET | /api/v1/entity_reviews/:id | One review with its entity summary |
That is the whole surface. Everything else — running checks, deciding reviews, adjudicating matches — is deliberately operator-only and has no API, because each is a human decision with an audit trail attached.
Formats
JSON by default. The two show endpoints also serve Markdown, which is useful for pasting a merchant's state into a ticket or handing it to a language model:
bash
curl -H "Authorization: Bearer $VERITY_API_KEY" \
-H "Accept: text/markdown" \
https://your-host/api/v1/entities/42Or GET /api/v1/entities/42.md.
Conventions
- Timestamps are ISO 8601 strings
- IDs are integers
- Enum values are the snake_case strings documented on each field
- Absent values are
null, never omitted-and-implied
The one rule worth reading twice
risk_level is emitted only when an assessment actually ran:
json
{ "risk_level": "medium", "risk_level_updated_at": "2026-08-09T12:00:00Z" }and otherwise:
json
{ "risk_level": null, "risk_level_assessed": false }The underlying column has a database default of low. Publishing it unconditionally told consumers that every unassessed merchant was low risk, with no way to tell the difference. Never treat a missing risk_level_updated_at as low risk.
current_score is verification coverage on a 0–100 scale — a different question, and it is present whenever the entity has been scored regardless of whether risk was assessed.