API overview
The Agent Handler REST API is the management plane - your backend uses it to create Registered Users, manage Tool Packs, mint Link tokens, and configure the rest of your account. The MCP server is a separate surface (it’s what your agent talks to); see MCP integration for that side.
This page covers the conventions that apply across every endpoint. Per-endpoint reference is in the sidebar - Connectors, Credentials, Tool Packs, Registered Users, and so on.
Base API URL
All API endpoints in the reference documentation are relative to the following base URL:
If you are using our EU tenant, all API endpoints in the reference documentation are relative to the following base URL:
Authentication
Every request needs an Access Key in the Authorization header:
The word Bearer is required. Tokens are not URL parameters - never put them in the path or query string.
Two key environments:
- Production keys call against production data. Any number, and each one can be scoped to specific Tool Packs or Registered Users.
- Test keys call against a sandbox. Test Registered Users, test credentials, isolated audit log. Any number of test keys.
Mixing them produces 404 not_found on resources that exist in the other environment. Pick the right one for the call you’re making.
Errors
Every error response uses the same shape:
Errors are stable - when we add a new variant, we add a new code value rather than changing existing ones, so you can match on code safely.
Rate limits
Default limits per organization:
When you exceed a limit, the response is 429 with these headers:
Honor Retry-After. Backing off by the suggested amount keeps you well-behaved; aggressive retry through a 429 will keep getting 429s until the bucket refills.
These limits are separate from your monthly credit allotment, which is what Billing and usage covers: a 429 means you are calling too fast, a 402 means you are out of credits. Contact your account team if the defaults aren’t enough.
Idempotency
POST endpoints that create resources are idempotent on a stable client-supplied key:
/registered-users- idempotent onorigin_user_id. A repeat call with the sameorigin_user_idreturns the existing Registered User (status200), not a duplicate (status201)./registered-users/{id}/link-token- not idempotent. Each call mints a new link token; tokens are single-use and short-lived./credentials/export- not idempotent.
For endpoints that aren’t idempotent on a natural key, you can pass a request-scoped Idempotency-Key header with any unique value. Repeat requests with the same key within a 24-hour window return the original response without re-executing.
Use UUIDs or any other globally-unique value. Don’t reuse keys across logically distinct calls.
Pagination
List endpoints are cursor-paginated. The response shape is consistent across resources:
Pass next_cursor as the cursor query parameter on the next request. When has_more is false, you’ve reached the end.
Default limit is 50; max is 250. The cursor is opaque - don’t try to decode or construct your own.
Versioning
The current API version is v1. New, backwards-compatible fields and endpoints are added without bumping the version. Breaking changes (renaming a field, removing an endpoint, changing semantics) ship under v2 - both versions run side by side during a migration window.
When breaking changes are coming, you’ll see them announced in the changelog with at least 90 days of notice and a migration guide.
Webhooks
Outbound webhooks fire from a separate domain (https://ah-api.merge.dev/webhooks/... is for inbound; outbound originates from Agent Handler to your endpoint). Verify signatures before trusting payloads - see Webhooks for the full guide.
SDKs
Official SDKs are in development. For now, the API is callable directly with any HTTP client - examples in the per-endpoint reference cover cURL, Python, and TypeScript.
For MCP-side integration (the agent’s view, not the management API), see MCP integration.
Status and support
API status, incidents, and uptime live at status.merge.dev. For support, file from the dashboard - include the request ID from the X-Request-ID header on the response and we can find your call in our logs immediately.