Skip to main content

Rate Limiting & Error Handling

The MCP Tools & Servers API enforces rate limits to protect service stability and returns structured error responses to help you diagnose and recover from failures. This page covers the rate-limiting model, policy evaluation, error response format, and troubleshooting guidance.

Rate Limiting

Rate Limit Model

The API uses fixed-window, per-principal rate limiting. Each authenticated principal (user or service key) is allocated a maximum number of requests per minute (RPM). The window resets at fixed intervals regardless of when the first request was made.

Rate limits are tracked in Redis for consistency across API instances, with an in-memory fallback if Redis is temporarily unavailable.

Rate Limit Headers

All API responses include rate limit headers so your application can track its current usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the current window resets

Handling Rate Limits

When the rate limit is exceeded, the API returns an HTTP 429 response with a Retry-After header indicating how many seconds to wait before retrying.

Example 429 response:

{
"error_code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 32 seconds.",
"details": {}
}

Best practices:

  • Implement exponential backoff with jitter — avoid retrying at fixed intervals, which can cause request bursts when the window resets.
  • Check rate limit headers proactively — if X-RateLimit-Remaining is low, slow down before hitting the limit.
  • Cache responses when possible — tool definitions and toolset configurations change infrequently and are good candidates for client-side caching.
  • Use batch operations — prefer POST /v1/toolsets:from_nexsets and POST /v1/tools:reconcile over individual create/update calls.

Policy Evaluation

Tool execution is subject to policy evaluation before any data is returned. The policy evaluator checks the caller's Nexset role and produces a decision that determines how the execution proceeds:

DecisionDescription
allowExecution permitted
denyExecution blocked — insufficient permissions
allow_with_redactionsExecution permitted with sensitive data redacted from the result
allow_with_limitsExecution permitted with result limits applied (e.g., reduced row count)

Policy decisions are recorded in execution receipts for auditing. If a tool execution is denied, the API returns a 403 Forbidden error with a message describing the required role.

Error Response Format

All errors follow a standard JSON structure:

{
"error_code": "ERROR_CODE",
"message": "Human-readable description of the error",
"details": {}
}
FieldTypeDescription
error_codestringMachine-readable error code from the table below
messagestringHuman-readable description of what went wrong
detailsobjectAdditional context (varies by error type; may be empty)

Error Codes Reference

CodeHTTP StatusDescription
UNAUTHORIZED401Invalid or expired authentication token
FORBIDDEN403Insufficient permissions for this operation
NOT_FOUND404Resource does not exist
INVALID_ARGUMENT400Invalid request parameter or body
VALIDATION_FAILED400Request body failed schema validation
INVALID_STATE400Operation not allowed in current resource state
ALREADY_EXISTS409Resource already exists (duplicate)
CONFLICT409State conflict (concurrent modification)
RATE_LIMITED429Rate limit exceeded
INTERNAL500Internal server error
UPSTREAM_ERROR502External service (Nexla API) error
SERVICE_UNAVAILABLE503Service not ready (e.g., database unavailable)
TIMEOUT504Request timed out
PARTIAL_FAILURE207Bulk operation partially succeeded — check details for per-item results

Common Error Scenarios

401 Unauthorized

Causes:

  • Expired service key
  • Missing Bearer prefix in the Authorization header
  • Invalid or malformed token

How to fix:

  • Regenerate your service key in the Nexla UI (see Service Keys).
  • Verify the header format is Authorization: Bearer <NEXLA_SERVICE_KEY>.
  • Confirm you are using a service key, not an API key or session token.

403 Forbidden

Causes:

  • Insufficient Nexset role for the requested operation (e.g., executing a tool without operator role)
  • Attempting to access resources belonging to another organization

How to fix:

  • Request the appropriate role from the Nexset owner. See Authentication for the role-to-permission mapping.
  • Verify the tool or toolset belongs to your organization.

400 Invalid Argument

Causes:

  • Missing required fields in the request body
  • Invalid enum values (e.g., unsupported kind or status)
  • Malformed JSON

How to fix:

  • Check the request body against the endpoint documentation in Tools API or ToolSets API.
  • Validate your JSON payload with a linter before sending.
  • Review the details field in the error response for specific field-level errors.

429 Rate Limited

Causes:

  • Too many requests within the current rate limit window

How to fix:

  • Read the Retry-After header and wait before retrying.
  • Implement exponential backoff with jitter.
  • Reduce request frequency by caching responses and using batch endpoints.

502 Upstream Error

Causes:

  • The Nexla platform API is temporarily unavailable or returned an unexpected error

How to fix:

  • Retry the request with exponential backoff.
  • If the error persists, check the Nexla status page for platform incidents.
  • For tool executions, query the Receipts API to verify whether the operation completed before retrying.

Best Practices

  • Monitor rate limit headers — check X-RateLimit-Remaining before making rapid successive requests to avoid hitting the limit.
  • Use exponential backoff with jitter — for all retry logic, not just rate-limit errors. This prevents thundering-herd effects.
  • Prefer batch endpoints — use POST /v1/toolsets:from_nexsets instead of separate tool creation and toolset creation calls.
  • Cache infrequently changing data — tool definitions and toolset configurations are stable between deployments and safe to cache.
  • Use reconcile for bulk updates — call POST /v1/tools:reconcile to sync multiple tools with their Nexsets in a single request instead of refreshing tools individually.
  • Handle partial failures — when a bulk operation returns 207 PARTIAL_FAILURE, inspect the details object to identify which items succeeded and which failed.