Integrations
API overview and request format
Call agaro through the authenticated version 1 action API, understand actor bound keys, request shapes, methods, responses, rate limits, and errors.
agaro exposes an authenticated action API under /api/v1. It dispatches the same registered server actions used by the application, so validation, module gates, model permissions, record scope, workspace mutation checks, and activity attribution remain in force.
API key access requires an active MCP seat for the bound actor. The API is not an unmetered alternative to the MCP entitlement.
Create an actor bound key
A workspace Super Admin opens Settings → Developer and AI → API and MCP Keys.
- Confirm the workspace is on Growth or Scale and the intended actor has an active MCP seat.
- Select Create an MCP key.
- Give the key a specific name, such as
Revenue reporting integration. - Bind it to an active Super Admin or Manager.
- Choose 30 days, 90 days, one year, or never expires.
- Copy the plaintext immediately.
Only the SHA 256 hash is stored. The full key cannot be retrieved after you close the reveal. Prefer an expiring key and rotate it on a schedule.
Authentication
Current keys encode their workspace route and are bound to one actor. Send the key as a bearer token:
Authorization: Bearer <your-key>For a JSON body, also send:
Content-Type: application/jsonDo not add an actor header to change identity. The actor stored on the key is authoritative, and request headers cannot rebind it.
Direct action route
Registered actions use this pattern:
POST https://erp.agaro.ai/api/v1/{module}/{action}Examples of route shape include:
POST /api/v1/clients/list
POST /api/v1/leads/create
POST /api/v1/invoices/recordPayment
POST /api/v1/tasks/completeAction names and schemas evolve with the product. Use the current registered action surface rather than copying an old list into an integration.
Request bodies
The canonical body wraps positional action arguments in args:
{
"args": [
{
"companyName": "Example Company"
}
]
}For a one argument action, the raw input object is also accepted:
{
"companyName": "Example Company"
}An action with no arguments can receive an empty body or:
{ "args": [] }Use args for generated clients because it remains unambiguous when an action takes more than one argument.
Example request
curl -X POST \
"https://erp.agaro.ai/api/v1/clients/list" \
-H "Authorization: Bearer <your-key>" \
-H "Content-Type: application/json" \
--data '{"args":[]}'Never place the key in a URL, source repository, browser bundle, analytics event, or shared command history.
GET and mutation methods
Read actions can be called with GET where the route resolves them as nonmutating. GET accepts an encoded args query parameter or maps query parameters to a single object for supported actions.
Mutating actions cannot be called with GET. Use POST, PATCH, PUT, or DELETE as supported by the route. Sending a body through POST, PATCH, or PUT requires application/json; otherwise the API returns 415 Unsupported Media Type.
Inventory additionally supports namespaced routes such as:
/api/v1/inventory/{entity}/{action}Some inventory entities also support collection and item conventions for list, create, get, update, and archive or remove.
Response shape
Actions generally return the same structured result used by the application. A successful action can look like:
{
"ok": true,
"data": {}
}Validation or business failures that return ok: false use HTTP 400 and can include fieldErrors and formError. Dates use their normal JSON representation. Big integer money values are serialized as exact decimal strings rather than losing precision.
Status codes
| Status | Meaning |
|---|---|
| 400 | Invalid JSON, validation failure, or an action returned ok: false |
| 401 | Missing bearer credential |
| 402 | The actor lacks an active MCP seat or the workspace billing state blocks MCP |
| 403 | Invalid, expired, revoked, or unauthorized key, actor, module, or record action |
| 404 | Unknown route or deliberately unavailable internal action |
| 405 | A mutating action was attempted with GET or HEAD was used |
| 415 | A body was sent without JSON content type |
| 429 | Key, actor, source, or workspace rate limit was reached |
| 500 | Unexpected server failure |
Use the returned status and error body. Do not retry a validation or permission failure as if it were a transient network error.
Rate limits and idempotency
The API limits requests per actor and per workspace. A 429 response includes a 60 second retry hint. Apply bounded exponential backoff and avoid parallel retry storms.
Not every action is idempotent. Retrying a create action can create another business record unless that action has its own deduplication key. For payments, billing, sends, imports, and other high impact writes, keep the provider or action idempotency identifier and check the result before retrying.
Rotate and revoke
Rotate a key from the key table to issue a new plaintext for the same key record. Rotation invalidates the previous secret immediately. Update the client before its next call.
Revoke a key when the integration is retired or the secret may have been exposed. Revocation is immediate and cannot be undone. Create a new key instead of trying to recover a revoked one.
The key table shows prefix, bound actor, last used time, call count, expiry, rotation, and revocation state.
Troubleshooting
A new key returns 402
Confirm the bound actor still has an active MCP seat and the workspace is on an eligible active plan. The seat belongs to the actor, not to the key name.
A request returns 403 after a role change
Keys use live actor and creator authority. A suspended, removed, deleted, or demoted actor can lose access immediately. A key also cannot act above its creator's current privilege ceiling.
POST returns 415
Send Content-Type: application/json whenever the request contains a body.
An action is not found
Internal jobs and provider callback actions are deliberately excluded. Confirm the current registered module and action names and use the supported public integration path.