API reference
The Two Minute Reports API is a REST API that sends and receives JSON. Use it to manage your profile, teams, connections, and clients, and to run data queries from your own code.
v1. All endpoints are prefixed with /v1.Base URL
https://api.twominutereports.com/v1
All paths in this reference are relative to this base URL. For example, GET /users/me means GET https://api.twominutereports.com/v1/users/me.
Authentication
Every request must include a bearer token in the Authorization header:
curl https://api.twominutereports.com/v1/users/me \
-H "Authorization: Bearer tmrc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Create the key with the intended use API: in the Hub, on the Automations tab of the AI tools page, or in Settings › API keys. A key made for the MCP server does not work here. See Authentication.
Response format
Every response uses a consistent envelope so you can branch on a single success flag.
{
"success": true,
"data": { }
}
On success, data holds the result. It is an object or an array, depending on the endpoint.
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "The requested resource was not found"
}
}
On failure, error.code is a stable machine-readable string and error.message is human-readable. See Errors.
Conventions
- Content type: Request bodies are JSON (
Content-Type: application/json), except file uploads which usemultipart/form-data. - IDs: Resource IDs such as
teamId,userId, andclientIdare UUID v7 strings. Account IDs are strings that the platform defines, such as1234567890for a Google Ads account. In a data query, an account ID starts with its connector ID, such asgadw_1234567890. - Timestamps: All timestamps are ISO 8601 strings in UTC (for example
2026-06-16T09:30:00.000Z). - Team permissions: Team-scoped endpoints need a team permission, such as
clients.read. The role of the person who created the key must include it. Each endpoint page names the permission it needs.
Keys, scopes and permissions
Two separate checks run on every team-scoped request, and a call has to pass both.
- What the key is allowed to do. Every key has scopes, chosen when you create it, and a call outside them is refused.
- What the person who created the key is allowed to do. A key carries the team permissions of its holder.
The effective permission is the intersection: a key's scopes can only narrow its holder's permissions, never widen them. A key created by a member who can only read cannot write, whatever scopes it was given. If that member's access on the team is later reduced, the key's access is reduced with it. Nobody has to change the key.
- A key belonging to somebody who leaves the team stops working. If an integration matters, create its key under an account that is staying.
- Permissions are per team. The same key can be accepted for one team and refused for another, because the person behind it has different access in each. A
403on one team and a200on another is not a broken key. Check the role the key holder has in the team that the request names. See Seats.
Using the API itself does not need a seat. An integration set up by somebody who later loses their seat can still read teams, connections and clients. Writes stop, and so do data queries, because running a query needs a seat.
The user object
Several resources tell you who did something: who created a connection, who last edited it, or who enabled an account. Wherever that appears, it is the same object rather than a bare ID. You can show a name and an avatar without a second lookup.
{
"id": "0190f8b7-3c4d-7e5f-9a0b-1c2d3e4f5a6b",
"name": "Priya Raman",
"firstName": "Priya",
"lastName": "Raman",
"avatarUrl": "https://assets.gox.ai/tmr/avatars/priya.png",
"email": "[email protected]"
}
null if the user has not set one. It is firstName and lastName joined with a
space, so it is never something the two parts do not say.null if not set.null if not set. A one-word name is a firstName with no lastName, so do not
read an absent lastName as missing data.null if the user has no avatar.The object itself may be null. A record created before we started tracking who acted on it has
nobody to name, and that is reported as null rather than as a placeholder user. Always check the
object before you read its fields.
updatedBy always names a person. Background work (cache refreshes, vote and view counters,
scheduled recomputes) updates records without changing it. It never reports a machine as the editor,
and it never clears whoever edited last.
createdBy used to be a bare UUID string on
connections and clients. It is now the object above. If you were reading createdBy as an ID, read createdBy.id instead.Reference
| Resource | Description |
|---|---|
| Authentication | Bearer tokens and API keys |
| Rate limits | Request quotas and the 429 response |
| Errors | Error envelope and status codes |
| Users | Profile and preferences |
| Teams | Teams, members, roles, and seats |
| Connections | A team's connections |
| Connectors | Connectors, accounts, and fields |
| Clients | Clients, their contacts, and their assigned accounts |
| Data | Run data queries |
| Platform | Plans, connectors, roadmap, and changelog |