Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Errors and rate limits

An error returns an HTTP status and a JSON body. code is the gRPC status code and message says what went wrong. details holds an ErrorInfo whose error_code is a stable name to match on. Match on error_code, not on the message text.

Scalekit or the app?

A tool call can fail in Scalekit or in the app the tool calls, such as Gmail or Slack. error_code tells you which:

error_codeWho rejected the callWhat to do
TOOL_ERRORThe app. tool_error_info says why.Read tool_error_info.tool_error_code, below.
Anything else, such as RESOURCE_NOT_FOUND, UNAUTHENTICATED, INVALID_ARGUMENTScalekit, before the app was called.Fix the request. Each endpoint page lists the errors it returns.

Tool errors

tool_error_info has three fields: tool_error_code, tool_error_message (what the app returned) and execution_id (quote it to support).

tool_error_codeHTTPMeaningWhat to do
REAUTHENTICATION_NEEDED, UNAUTHENTICATED401The user's access to the app was revoked or expired, or the connected account is EXPIREDThe user must authorize again: send them a new authorization link.
FORBIDDEN, PERMISSION_DENIED403The user's account lacks the scope this tool needsAdd the scope to the connection, then have the user authorize again.
RESOURCE_NOT_FOUND404The app couldn't find what the call refers to, such as an event IDCheck the IDs in params.
RATE_LIMITED429The app's rate limit or quotaBack off and retry. See [Rate limits](#rate-limits).
INVALID_ARGUMENT400The app or the tool rejected the input, or a tool from an MCP server returned an errorRead tool_error_message and fix the parameters.
EXECUTION_ERROR400The app returned an error for this callRead tool_error_message, fix the parameters or the account, and retry.
INTERNAL_ERROR400 or 500400: the app rejected the call. 500: Scalekit couldn't run the toolFor 400, read tool_error_message. For 500, retry later, and quote execution_id to support if it persists.
TOOL_ERROR400 or 500From a tool on an app's MCP server: 400 when the server rejected the call, 500 when it failed, rate-limited the call or couldn't be reachedFor 400, read tool_error_message. For 500, back off before you retry.

Tools from an MCP server

A tool from an app's own MCP server maps what the server returned to these codes. The server's status and message are in tool_error_message.

  • 401 with REAUTHENTICATION_NEEDED: the server rejected the user's credentials. The user must authorize again.
  • 403 with FORBIDDEN: the server refused the call.
  • 400 with INVALID_ARGUMENT: the tool returned an error result, or the server rejected the input. 400 with TOOL_ERROR: the server returned any other 4xx status.
  • 500 with TOOL_ERROR: the server returned 408, 429 or a 5xx status, or Scalekit couldn't reach it in time. A retry can run the tool twice, so retry only tools that are safe to repeat.

Rate limits

When an app rate-limits a call, Scalekit returns HTTP 429 with error_code TOOL_ERROR and tool_error_code RATE_LIMITED. Each app sets its own limits, per user or per OAuth app. With your own OAuth app, you get your own quota at apps that count per app.

The response has no Retry-After header. Retry with exponential backoff and jitter, for example 1, 2, then 4 seconds, and stop after a few tries.

Two exceptions. A tool from an app's own MCP server returns HTTP 500 with TOOL_ERROR when the server rate-limits the call, as [Tools from an MCP server](#tools-from-an-mcp-server) describes. The API proxy returns the app's status and headers unchanged, including its Retry-After.

Troubleshooting covers the errors users see while connecting.