Appearance
Authentication, Limits, and Errors
Base URL
All endpoints are under:
https://agentapi-prod-eastus-1.bronco.run/api/v2The machine-readable OpenAPI document for the API is at /openapi.json.
Authentication
Send your API key as a bearer token with every request:
Authorization: Bearer brk_live_...- A key belongs to one Bronco account and can be limited to specific advertisers.
- A key has the permissions chosen when it was created. Reporting grants
reports:read. Audiences grantsaudiences:readandaudiences:write. Each endpoint lists the permission the key needs. - A key can't change campaigns, see billing, or manage users and keys.
- Keys created in Bronco don't expire. Admins revoke them under Settings → API Keys, and a revoked key stops working at once.
- An account can have up to 50 active keys.
Keep keys out of client-side code and source control. If a key may have been exposed, revoke it and create a new one.
Rate limits
Requests are limited per key, per minute: 120 requests, plus a separate 600 for adding and removing audience members. Every response carries:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the current window. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | Seconds until the window resets. |
The headers describe whichever of the two allowances the request counted against.
Past the limit the API answers 429 with a Retry-After header giving the seconds to wait. Requests that are refused for another reason still count toward the limit.
Errors
Errors use standard HTTP status codes and a JSON body:
json
{
"statusCode": 403,
"timestamp": "2026-09-12T14:03:27.000Z",
"path": "/api/v2/reports/query",
"message": "This API key has no access to advertiser 57"
}message is a string, or a list of strings when several fields failed validation.
Some errors carry two more fields:
codeis a short, machine-readable reason, such asTENANT_DISABLED. It stays the same when the wording ofmessagechanges, so branch oncodewhen it is there.errorsis an object with details that go withmessage.
| Status | When |
|---|---|
400 | The request body isn't valid JSON, or failed validation: an unknown field, a bad date, more than four dimensions, or neither a preset nor a start and end date. |
401 | The key is missing, invalid, or revoked. |
403 | The key lacks the permission the endpoint needs, or asked for an advertiser it isn't limited to. Also returned, with code set to TENANT_DISABLED, when the account is on hold. |
404 | The thing asked for doesn't exist, or belongs to another account. |
409 | The request conflicts with what already exists. code says how. |
413 | The request body is larger than 5 MB. |
429 | The rate limit was exceeded. Wait for Retry-After seconds. |
500 | Something went wrong on our side. Retry, and contact support if it continues. |
Sandbox
To build an integration before you have live campaigns, ask Bronco for a key on a demo account. It returns generated sample data instead of real delivery: three advertisers and five campaigns covering the year up to today, with the same numbers on every call.
Audiences on a demo account behave like real ones, but no matching takes place. An audience becomes ready once it holds 1,000 emails or 1,000 phone numbers. If it is still smaller ten minutes after its first people were added, it becomes notEnoughMatches, and turns ready when it grows past 1,000. A removal is applied within about an hour, when removalsPending returns to 0.
Stability
Fields and enum values may be added to these endpoints. Existing ones are not renamed or removed, so write clients that ignore fields they don't recognize.