POST /v1/track
Record a single agent task. Returns the stored event with computed hours_saved, cost_saved, and net_saved.
Auth
Authorization: Bearer hh_live_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Request body
{
agent_id: string, // required, your stable id
task_type: string, // required, see /docs/api/task-types
outcome: "success" | "failure" | "needs_review",
agent_duration_seconds?: number, // wall-clock seconds the agent took
agent_cost?: number, // cost of the agent run, in org currency
human_baseline_minutes?: number, // overrides task_type default for this event only
metadata?: object, // free-form, indexed for /v1/reports
audit_sample?: {
input_excerpt?: string, // up to 2000 chars
output_excerpt?: string, // up to 2000 chars
model?: string,
tokens_in?: number,
tokens_out?: number,
},
occurred_at?: ISO 8601, // defaults to receipt time
}
Headers
| Header | Required | Notes |
|---|---|---|
Authorization | yes | Bearer hh_* |
Content-Type | yes | application/json |
Idempotency-Key | optional | Any 1–255 char string. Resending the same key returns the original event verbatim. |
Response (201)
{
"event_id": "evt_01HXY...",
"agent_id": "support-classifier",
"task_type": "email_classification",
"outcome": "success",
"resolved_baseline_minutes": 4.0,
"resolved_baseline_source": "builtin",
"resolved_hourly_rate": 45,
"currency": "EUR",
"agent_duration_seconds": 4,
"hours_saved": 0.066,
"cost_saved": 2.97,
"agent_cost": null,
"net_saved": 2.97,
"occurred_at": "2026-05-06T10:42:00.000Z"
}
resolved_baseline_source is one of request | override | builtin | custom | fallback and tells you which layer of the resolution stack supplied the baseline.
Errors
| Code | HTTP | When |
|---|---|---|
missing_authorization | 401 | No Authorization header |
invalid_api_key | 401 | Token format invalid or unrecognized |
key_revoked | 401 | Key exists but was revoked |
validation_error | 422 | Body fails schema validation |
unknown_task_type | 422 | task_type not in catalogue and no inline human_baseline_minutes |
occurred_at_out_of_range | 422 | More than 90 days old or > 24h in the future |
rate_limited | 429 | Per-key per-second cap exceeded; retry after Retry-After seconds |
quota_exceeded | 429 | Free plan monthly cap reached |
See errors for the full catalogue.
Idempotency
Send the same Idempotency-Key twice and you get the same event back. The key is scoped to your org, not the API key, so retries from a different key still dedupe correctly. Stored for 24h.
Rate limits
| Plan | Per second per API key |
|---|---|
| Free | 60 |
| Pro | 200 |
| Enterprise | 1 000 |
429 responses include Retry-After: 1 per RFC 6585.