Reads and commands
The HeadHoncho API model is the app's own, in two halves. A read is a GET over a read model the app already draws, so a number in the API is the number on the screen. A command is a POST that runs one of the app's own commands and answers with an acknowledgement. Nothing is computed in the API that the app does not compute.
Commands are posted to /api/v1/commands/<verb>, where the verb is the app's own command name:
| Verb | Endpoint | Call |
|---|---|---|
create-job | Create job | POST /api/v1/commands/create-job |
update-job | Update job | POST /api/v1/commands/update-job |
change-job-status | Change job status | POST /api/v1/commands/change-job-status |
assign-worker | Assign worker | POST /api/v1/commands/assign-worker |
unassign-worker | Unassign worker | POST /api/v1/commands/unassign-worker |
add-job-note | Add job note | POST /api/v1/commands/add-job-note |
Every command needs an Idempotency-Key
Send an Idempotency-Key header with every command. Any unique string works, and a new random UUID per intended action is the usual choice.
- The same key with the same body returns the first answer and runs nothing twice. A retry after a dropped connection is safe.
- The same key with a different body is refused with status 409 and `idempotency_mismatch`.
- No key at all is refused with status 400 and `missing_idempotency_key`.
See your own write
Every command answer carries a position: where the change landed in the event log. A read accepts ?after=<position> and waits up to two seconds for the read model to catch up, so the next read shows what you just wrote. Get job history returns the same positions beside each event.
curl -X POST ".../commands/add-job-note" ...
# answer: {"accepted": true, "job_id": "job_1203", "position": 88411, ...}
curl ".../jobs/job_1203?after=88411" ...
Lists, cursors and counts
A list answers {items, next, count}. items is the page, count is how many match in all, and next is an opaque cursor for the following page, or null at the end. Pass the cursor back as cursor and change nothing else. Do not read inside it: it is not a promise about how paging works. List jobs is the example; Read table pages with limit and offset instead, because a raw table has a stable order.
Ids, dates and money
- Ids are opaque text such as
cmp_14f5orjob_1138. Keep them exactly as given. - Dates and times are ISO 8601. A date range is read in the company's time zone.
- Money is a plain number in the company's currency, and the answer says which currency.
Building blocks, never the app
The API offers records, raw rows and single commands. It never offers a board, a question, a dashboard, a widget, a layout or an automation. The purpose is to let you build your own tool on top of the same facts, not to rebuild HeadHoncho from outside. The one report in the API, the Google Click ID report, is there because the customer hands its file to Google and it must exist outside the app. The roadmap lists what is planned and what is never offered.
Next: API keys for access, errors and rate limits for what a refusal looks like, and the MCP server for AI apps. The records themselves are described on the Jobs panel and the Raw data board.