Base path
All endpoints sit under/api/v1 on your FormBharo server. For example, to list agents on a server at , the full URL is /api/v1/agents.
Exception:
POST /offer (the WebRTC signalling endpoint) is at the bare path — /offer — with no /api/v1 prefix.Pagination
List endpoints support two query parameters for paging through results:cursor is a positional offset, not tied to a specific row’s identifier. This means live inserts that happen between two page requests can cause the same record to appear on two consecutive pages, or for a record to be skipped entirely. For most use cases this is acceptable — but avoid building deduplication logic that depends on cursor-based paging being gap-free.
When the last page is reached, next_cursor in the response is null.
Two response shapes on the same list endpoint
Some list endpoints return different JSON shapes depending on whether you include pagination parameters: Withoutlimit or cursor — the response is a plain JSON array:
limit or cursor present — the response is a paginated envelope object:
GET /api/v1/agentsGET /api/v1/agents/{agent_id}/conversationsGET /api/v1/workspaces
GET /api/v1/conversations (the cross-agent conversation list) always returns the envelope shape — { "data": [...], "next_cursor": ... } — regardless of whether you pass pagination parameters.Timestamps
All timestamps in FormBharo are unix seconds expressed as a fractional (floating-point) number. There are no date strings and no timezone objects.since and until query parameters on list endpoints filter on created_at. In FormBharo, created_at is the last-write time — it is updated whenever the record is modified, not set once at creation.
Transcript inclusion
GET /api/v1/agents/{agent_id}/conversations includes the full call transcript for each conversation by default. Transcripts can be large — if you only need form data and metadata, pass include_transcript=false to omit them.
transcript key is absent from each conversation record entirely — it is not present with a null or empty value. Check for key existence, not for a falsy value, if your code needs to distinguish “transcript omitted” from “no transcript recorded”.