API reference
The Vavan REST API — authenticate with an organization API key and read/write your accounts, contacts, orders, and products.
The Vavan API is a REST interface for reading and writing your core business objects programmatically. It is built on the same Vavan Core that powers every Vavan application, so the records you read and write through the API are the same objects your team sees in Vavan CRM, Dispatch, and the rest of the platform — there is no separate copy or shadow schema.
Every request is organization-scoped: an API key belongs to exactly one organization, and the API can only ever see and modify that organization's data. The server derives your organization from the key on every request, so there is no way to read or write across organization boundaries. For the full isolation model, see Security & isolation.
Authentication
Every request must include an Authorization header with a bearer
token — your Vavan API key:
Authorization: Bearer vk_live_... API keys are created in the platform under Developers (platform.vavan.ai → Developers). A key's secret is shown only once at creation time, so store it somewhere safe; if you lose it you will need to create a new key. Keys are organization-scoped — each key can only access the organization it was created in.
Each key carries one or both of two scopes:
read— required for allGETrequests.-
write— required for allPOSTandPATCHrequests.
Keys can be revoked at any time from the Developers area, and
a key may be given an expiry. A revoked or expired key is
rejected with a 401.
Example request:
curl https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts \
-H "Authorization: Bearer vk_live_..." Base URL & versioning
All endpoints live under a single base URL:
https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api
Append the resource path to the base URL — for example,
https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts.
api.vavan.ai alias may be
offered later. Until then, use the base URL above. When the alias becomes
available, the paths and behavior will be identical — only the host changes.
Resources
The API exposes four resources, each mapping to a core object type in your organization:
| Resource | Path | Description |
|---|---|---|
| Accounts | /accounts | Your companies — leads, prospects, and customers. |
| Contacts | /contacts | People at those accounts. |
| Orders | /orders | Orders placed by your accounts. |
| Products | /products | Items in your catalog. |
Every resource supports the same four endpoints. Using accounts as
the example:
| Method & path | Scope | Description |
|---|---|---|
GET /accounts | read | List records (paginated, searchable). |
GET /accounts/{id} | read | Retrieve a single record. |
POST /accounts | write | Create a record. |
PATCH /accounts/{id} | write | Update a record. |
Listing & pagination
GET list endpoints accept the following query parameters:
| Parameter | Default | Description |
|---|---|---|
limit | 25 | Number of records to return. Maximum 100. |
offset | 0 | Number of records to skip, for paging through results. |
q | — | Text search. The field searched depends on the resource (see below). |
The q parameter searches a different field per resource:
- Accounts — by name.
- Products — by name.
- Contacts — by full name.
- Orders — by order number.
Example — list the first 50 accounts matching "interstate":
curl "https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts?limit=50&q=interstate" \
-H "Authorization: Bearer vk_live_..." A list response is shaped like this:
{
"object": "list",
"data": [ { /* record */ } ],
"pagination": { "limit": 25, "offset": 0, "total": 137, "has_more": true }
}
Use pagination.has_more to decide whether to fetch the next page,
and advance by adding limit to offset.
Retrieve, create & update
Single-record responses — retrieve, create, and update — return the record
wrapped in a data envelope:
{ "data": { /* record */ } } Retrieve
Fetch a single account by id:
curl https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts/{id} \
-H "Authorization: Bearer vk_live_..." Create
POST the writable fields as JSON. A successful create returns
HTTP 201:
curl -X POST https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts \
-H "Authorization: Bearer vk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Interstate Oil",
"entity_type": "customer",
"physical_city": "Houston",
"physical_state": "TX",
"phone": "+1-555-0100",
"industry": "Oil & Gas"
}' Response (201 Created):
{
"data": {
"id": "...",
"name": "Interstate Oil",
"entity_type": "customer",
"physical_city": "Houston",
"physical_state": "TX",
"phone": "+1-555-0100",
"industry": "Oil & Gas"
}
} Update
PATCH sends only the fields you want to change. Omitted fields are
left untouched:
curl -X PATCH https://ahlrdnfbmudtnpdrqmug.supabase.co/functions/v1/api/accounts/{id} \
-H "Authorization: Bearer vk_live_..." \
-H "Content-Type: application/json" \
-d '{ "pipeline_stage": "qualified", "estimated_value": 50000 }' Writable fields
Each resource accepts a defined set of writable fields. Any other or internal fields in the request body are ignored — so it is safe to send a record you read back, and only the recognized fields will be applied.
Accounts
name, display_name, entity_type,
customer_status, assigned_rep,
physical_city, physical_state, phone,
email, website, industry,
pipeline_stage, estimated_value,
fleet_size, territory, notes,
tags, customer_since, metadata.
Contacts
entity_id (required), full_name,
first_name, last_name, email,
phone, mobile, role, title,
department, is_primary,
is_decision_maker, status, notes,
metadata.
Orders
entity_id, contact_id, order_number,
po_number, status, total_amount,
currency, placed_at, product_name,
priority, source, notes,
metadata.
Products
name, sku, category, unit,
unit_price, unit_cost, description,
is_active, brand, metadata.
org_id from your API key — it cannot be set or
changed through the API, and any org_id you send is ignored.
For contacts, entity_id is required on create and
must reference an account in your organization. For orders,
entity_id is optional, but if provided it must belong to your
organization. Any cross-organization reference is rejected.
Errors
Errors use a consistent shape with a machine-readable code and a
human-readable message:
{ "error": { "code": "...", "message": "..." } } | Status | Meaning |
|---|---|
400 | Invalid request or validation error. |
401 | Missing, invalid, revoked, or expired API key. |
403 | The key is missing the scope required for this request. |
404 | Unknown resource or id. |
405 | Method not allowed for this endpoint. |
Rate limits & fair use
We track usage per API key. There are no published per-second or per-day numbers to rely on today, but please be reasonable — batch where you can, page through lists rather than hammering them, and avoid tight retry loops. Limits may be applied to protect platform stability, and abusive usage tied to a key can be throttled or have the key revoked.