Add a custom API tool
POST/v1/agents/:agentId/custom-api-tools
x-scope: "custom_api:write"
A new tool, switched off: test it (testCustomApiTool), then switch it on
(updateCustomApiTool with active: true). The link decides the login: a link that
starts with the address of a login your company already has uses it (the longest when
several match), so leave login out; any other link gets a new login for its site (its
scheme, host and port), the login you send or none. A login other tools use changes for
all of them, so changing it also needs change_shared_login: true (409 login_shared
otherwise). Adding a tool to a login, or changing it, needs a key that can act on every
agent whose tools use it (403 shared_with_other_agents otherwise). Everything is
checked before anything is saved, as the dashboard checks it: a broken rule is 422 invalid_request with the field in param, and changes nothing. Custom API is on paid
plans; on the free plan every operation here is 403 feature_not_available.
When the AI calls a tool, Mojeeb by default waits up to 15 seconds for your system,
refuses a response over 1 MB, and gives the AI the first 50,000 characters of the
response. A test waits as long and refuses the same size. When CSRF is switched on for the
site's login (SAP and other OData servers; set in the dashboard), a POST, PUT, PATCH or
DELETE sends an extra request first to fetch a token, with its own wait. It carries the
login and the header and query values typed into the tool as they are, such as
sap-client=100, never anything written as a {{placeholder}}.
Request
Responses
- 201
- 401
- 403
- 404
- 409
- 413
- 422
- 429
- 500
- 503
The tool, switched off.
Response Headers
Correlation id for this request — paste into support tickets.
Authentication failed. Single code (invalid_api_key) covers every
sub-case: missing header, wrong scheme, malformed, unknown, revoked or
expired key. The message field disambiguates for humans debugging.
One exception: when the key could not be checked because of a server-side
fault, the status is still 401 but type is internal_error and code
is internal_server_error; retry with backoff.
Response Headers
Correlation id for this request — paste into support tickets.
Authenticated, but not allowed. insufficient_scope (the key lacks
custom_api:read or custom_api:write), agent_not_authorized (the
key is limited to other agents), shared_with_other_agents (the
tool's login is also used by tools of agents the key can't act on, so
the key can't add a tool to it or change it) or feature_not_available
(Custom API isn't on your company's plan).
Response Headers
Correlation id for this request — paste into support tickets.
agent_not_found when the agent is not one of your company's agents (the API never confirms
whether another company's agent exists); endpoint_not_found for a path or method no
endpoint serves, including an id that is not a UUID.
Response Headers
Correlation id for this request — paste into support tickets.
login_shared: the login sent differs from the tool's saved one, or
carries a secret, and other tools use it; send change_shared_login: true to change it for all of them. tool_not_tested: active: true before a passing test of the
tool's current request.
Response Headers
Correlation id for this request — paste into support tickets.
The request body is larger than 1 MB.
Response Headers
Correlation id for this request — paste into support tickets.
invalid_request_body when the body isn't valid JSON for the operation, a
field has the wrong type, or a field breaks a limit in its schema (a
query parameter that doesn't parse, on listCustomApiToolRuns).
invalid_request when the tool breaks one of the rules the dashboard
checks too (its link, inputs, headers, body or login), or the cursor
isn't one this list gave out. param names the field when there is one,
and the message says what to change.
Response Headers
Correlation id for this request — paste into support tickets.
Per-key rate limit hit. Default is 60/min/key; an endpoint with an
x-rate-limit-per-minute of its own counts in a budget of its own
(today listWhatsAppTemplates, which allows 10/min/key, and
sendConversationMessage, which allows 20/min/key), and its 429
reports that limit in X-RateLimit-Limit. Retry-After tells you when to retry;
X-RateLimit-Reset is the Unix timestamp of the next window.
Per-success-response
X-RateLimit-*headers are a known gap; on 2xx responses these headers are NOT currently emitted. Customers should rely on 429 +Retry-Afterfor backoff signals.
Response Headers
Correlation id for this request — paste into support tickets.
Seconds to wait before retrying.
The per-minute request limit of the endpoint called. Every key has the same limits today.
Remaining requests in the current window. 0 on rejection.
Unix timestamp at which the current window resets.
Unexpected server-side failure. Retry with exponential backoff. If
the failure persists, send us the correlation_id.
Response Headers
Correlation id for this request — paste into support tickets.
Mojeeb couldn't check access because of a temporary fault: the key's,
or on assignLead and assignConversation the teammate's. Nothing was
changed. Retry with backoff.
Response Headers
Correlation id for this request — paste into support tickets.