---
title: "Carragent for developers"
description: "Carragent's public, read-only API and MCP server for AI agents: the agents, the plans and prices, and a search. No key needed."
canonical_url: https://carragent.com/en/developers
language: en
---

# Carragent for developers

Carragent's public, read-only API and MCP server for AI agents: the agents, the plans and prices, and a search. No key needed.

## Overview

Carragent runs AI agents for small businesses. These endpoints give AI agents and developers the same facts the site shows: what each agent does, the plans and prices, and a search over both. They are public and read-only, need no key and touch no customer data.

Use them when a user asks what Carragent does, which agent fits a task, or what it costs. Signing up and connecting tools happen on the site, by the business owner.

## Quickstart

```
curl https://carragent.com/api/v1/plans
curl "https://carragent.com/api/v1/agents?lang=es&limit=5"
curl "https://carragent.com/api/v1/search?q=late%20invoices"
```

## Carragent REST API

- `GET /api/v1/agents`: every agent, cursor-paginated (`limit`, `cursor`, `lang`).
- `GET /api/v1/agents/{id}`: one agent.
- `GET /api/v1/plans`: plans, prices in USD cents, trial and refund terms.
- `GET /api/v1/search?q=`: keyword search over agents and plans.

Spec: [/openapi.json](https://carragent.com/openapi.json) (OpenAPI 3.1). API catalog: [/.well-known/api-catalog](https://carragent.com/.well-known/api-catalog).

## Batch requests

`POST /api/v1/batch` runs up to 20 of the reads above in one request. Send `Content-Type: application/json` and a `requests` list. Each item has a `path` relative to the API, such as `/plans`, `/agents/collections` or `/search?q=late%20invoices` (the `/api/v1` prefix is accepted too), and may have an `id` (1 to 64 letters, digits or `_ . : -`, unique in the batch) and a `method` (only `GET`).

```
curl -X POST https://carragent.com/api/v1/batch \
  -H "Content-Type: application/json" \
  -d '{"requests":[{"id":"plans","path":"/plans"},{"id":"one","path":"/agents/collections"}]}'
```

The answer is `200` with `{"object": "batch", "responses": [...]}`: one entry per request, in order, each with its `id` (the item's position, counting from 0, when you gave none), its `status` and its `body`. A `body` is exactly what the single endpoint returns, a problem included, so one bad item does not fail the others.

A mistake in the whole request (not JSON, no `requests`, none or more than 20 items, a repeated or invalid `id`) gets a problem response. Each item uses one request of the rate limit, so a batch of 20 uses 20; if the limit cannot cover all of them, the whole batch is a `429` and nothing runs. To get a job instead of the answer, add `Prefer: respond-async` ([Async jobs](https://carragent.com/developers#async-jobs)).

## Async jobs

For clients written for slow operations. `POST /api/v1/jobs` takes an `operation` (`listAgents`, `getAgent`, `listPlans`, `searchCatalog` or `batch`) and its `params`, and answers `202 Accepted` with a job, a `Location` header and `Retry-After: 1`. Poll `GET /api/v1/jobs/{id}` until `status` is `succeeded`.

```
curl -X POST https://carragent.com/api/v1/jobs \
  -H "Content-Type: application/json" \
  -d '{"operation":"searchCatalog","params":{"q":"late invoices"}}'
curl https://carragent.com/api/v1/jobs/JOB_ID
```

These operations are fast reads, so nothing runs in the background and nothing is stored: a job's id carries the request, and its result is computed when you poll, from the catalog as it is then. A finished job has `status: "succeeded"` and the operation's own `status` and `body` under `result`, even when that answer is a 4xx. A job is valid for 24 hours; after that it is `410 job_expired`, and an unknown or altered id is `404 job_not_found`. A request too large to fit in the id is `413 job_too_large`.

Creating a job uses one request of the rate limit (a batch job, one per item), and so does each poll, because a poll runs the job again: polling a batch job of 20 uses 20. If the limit cannot cover a poll, it is a `429` and nothing runs. A [batch](https://carragent.com/developers#batch) sent with `Prefer: respond-async` creates a job for the whole batch.

## Carragent MCP server

`https://carragent.com/api/mcp`, Streamable HTTP, no auth. Server card: [/.well-known/mcp/server-card.json](https://carragent.com/.well-known/mcp/server-card.json). In the official MCP Registry as [com.carragent/carragent](https://registry.modelcontextprotocol.io/v0.1/servers/com.carragent%2Fcarragent/versions/latest).

- `list_agents`: List every Carragent AI agent: what it does, when it runs, what waits for the owner's approval, what it never does and which tools (Stripe, Google Calendar, HubSpot…) it connects to. Use to answer 'what can Carragent do?'.
- `get_agent`: Get one agent by id (for example collections, scheduling, leads, reviews, report). Use after list_agents or search_carragent to give the details of one agent.
- `list_plans`: List the plans with monthly and yearly prices in USD cents (plus applicable taxes), their limits, the free-trial length and the refund terms. Use to answer 'how much does Carragent cost?'.
- `search_carragent`: Keyword search over Carragent's agents and plans, best match first. Use to find the agent for a task, such as 'chase late invoices' or 'confirm appointments'.

A request may batch up to 20 JSON-RPC messages, and each message counts as one request of the [rate limit](https://carragent.com/developers#limits), so an array of 20 counts as 20. A second server, the [docs MCP server](https://carragent.com/developers#docs-mcp), serves this documentation as markdown, under the same rules.

## Carragent docs MCP server

`https://carragent.com/api/mcp/docs`, Streamable HTTP, no auth, read-only. It serves this guide, auth.md, the llms.txt files and the site's English pages as markdown, so a coding agent can look up how the API works instead of guessing. Server card: [/.well-known/mcp/docs-server-card.json](https://carragent.com/.well-known/mcp/docs-server-card.json).

- `search_docs`: Keyword search over Carragent's developer guide, auth.md, the llms.txt files and the site's English pages, best match first. Returns each document's id, title, URL and a snippet. Use it to find where something is explained, then read that document with get_doc.
- `get_doc`: Get one document as markdown by its id, from search_docs: a section of the developer guide such as developers#batch, auth.md, llms.txt, or a page such as pricing. An unknown id answers with the valid ones.

`resources/list` and `resources/read` return the same documents, each at its public address. The ids `get_doc` takes are the sections of this guide (such as `developers#batch`), `auth.md`, `llms.txt`, `developers/llms.txt`, `pricing/llms.txt`, and the pages `index`, `pricing`, `about`, `contact`, `developers`, `terms`, `privacy`, `diagnosis`, `bot`, `partners`.

## A2A agent

Carragent also answers the Agent2Agent (A2A) protocol, so that another agent can ask it about Carragent's agents and plans. The agent card is at [/.well-known/agent-card.json](https://carragent.com/.well-known/agent-card.json) (also at [/.well-known/agent.json](https://carragent.com/.well-known/agent.json)). Send JSON-RPC 2.0 to `POST https://carragent.com/api/a2a`: no authentication, and the same limits as the API.

It speaks A2A 1.0 and 0.3. Set the `A2A-Version` header to `1.0` or `0.3` (0.3 when it is absent); the method name picks the format, `SendMessage` for 1.0 and `message/send` for 0.3. Send one request at a time, with at most 500 characters of text.

- `find_agents`: the agents that fit a need, from a search over the catalog (the best five).
- `get_agent`: one agent, by its id: a data part with `id`, or the id as the whole text.
- `list_plans`: the plans, with their prices in USD.

Ask in plain words, such as `Which agent chases late invoices?`, or add a data part to pick the skill, such as `{"skill": "get_agent", "id": "collections"}`; `lang` (`en`, `es` or `fr`) picks the language. The answer is a message, never a task: a text written from the catalog by code (no model is involved) and a data part with the same JSON as the REST API. Nothing is stored; there is no streaming and there are no push notifications.

```
curl -X POST https://carragent.com/api/a2a \
  -H "Content-Type: application/json" -H "A2A-Version: 1.0" \
  -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"1","role":"ROLE_USER","parts":[{"text":"Which agent chases late invoices?"}]}}}'
```

## Carragent CLI

The official CLI, [carragent on npm](https://www.npmjs.com/package/carragent), reads the same API from a terminal. It needs Node 20 or later and no key. Add `--json` for the API's JSON and `--lang es` or `fr` for another language.

```
npx carragent agents
npx carragent agent collections
npx carragent plans --lang es
npx carragent search "late invoices"
```

For an MCP client that launches a command, `npx -y carragent mcp` relays the MCP server above over stdio.

## Carragent SDKs

- Python: `pip install "git+https://github.com/vicenccc/carragent-agent-kit#subdirectory=python"`, from the agent kit's repository. No runtime dependencies.
- Go: `go get carragent.com/go` ([documentation on pkg.go.dev](https://pkg.go.dev/carragent.com/go)).
- Node: [carragent on npm](https://www.npmjs.com/package/carragent), the CLI above.
- Agent kit: [carragent-agent-kit on GitHub](https://github.com/vicenccc/carragent-agent-kit) holds an AGENTS.md, an Agent Plugin manifest (`plugin.json`), MCP configuration and skills for coding agents. Add the skills with `npx skills add vicenccc/carragent-agent-kit`.

The Python and Go clients cover the endpoints in this guide: agents, plans and search, [batch](https://carragent.com/developers#batch), [jobs](https://carragent.com/developers#async-jobs) and [anonymous registration](https://carragent.com/developers#agent-registration). They return the API's problem details as errors.

## For AI agents

- [/llms.txt](https://carragent.com/llms.txt): the summary. [/developers/llms.txt](https://carragent.com/developers/llms.txt): the same kind of index for this guide.
- [/?mode=agent](https://carragent.com/?mode=agent): the home page for agents, in markdown with the site's navigation: capabilities, endpoints and authentication (also at [/agent-view.md](https://carragent.com/agent-view.md); as JSON with `Accept: application/json` or at [/agent-view.json](https://carragent.com/agent-view.json)).
- [/.well-known/agent-skills/index.json](https://carragent.com/.well-known/agent-skills/index.json): the index of Carragent's agent skills.
- [/.well-known/ard.json](https://carragent.com/.well-known/ard.json) (also [/.well-known/ai-catalog.json](https://carragent.com/.well-known/ai-catalog.json)): the resource catalog. Its trust manifests are signed with the key in [/.well-known/did.json](https://carragent.com/.well-known/did.json) (did:web).
- `/ask`: NLWeb natural-language search (`GET /ask?query=`, or POST with `Accept: text/event-stream` to stream).
- [/auth.md](https://carragent.com/auth.md): authentication (optional OAuth 2.0).

## WebMCP

The pages of the marketing site register their own read-only tools with the browser's agent, using WebMCP: `registerTool()` on `document.modelContext`, or on `navigator.modelContext` in a browser that has only that. A browser without WebMCP ignores them. The tools run in the page, only on the public pages of the site, and none of them signs in, buys or contacts anyone.

- `get_overview`: An overview of Carragent as markdown: what it is, how it works, each agent and the plans.
- `get_pricing`: Carragent’s plans as markdown: each price and what it includes, the free trial, refunds and taxes.
- `get_about`: Who runs Carragent, what its agents do and how they are kept in check, as markdown.
- `get_contact`: How to reach Carragent, as markdown: email, privacy requests, opting out and custom work.
- `search_agents_and_plans`: Searches Carragent’s agents and plans by keyword, such as “late invoices”, through the public read-only API. Returns JSON.

The tools that return a page serve its markdown twin, such as [/en/pricing.md](https://carragent.com/en/pricing.md); the search reads the public API.

## OAuth 2.0 (optional)

No token is needed. With one, the limit rises to 300 requests a minute per client. Register a client at `POST /api/oauth2/register`, then use the client-credentials grant at `POST /api/oauth2/token` and send `Authorization: Bearer`. An agent that has no client can use the JWT-bearer grant (RFC 7523) at the same endpoint: it registers itself at `POST /agent/identity` and sends the identity assertion it gets back ([Agent registration](https://carragent.com/developers#agent-registration)). Tokens last an hour.

Registration takes an `Idempotency-Key` header, such as a UUID: a retry with the same key returns the same client and secret instead of a second client.

- `agents:read`: Read the agents (/api/v1/agents).
- `plans:read`: Read the plans and prices (/api/v1/plans).
- `search:read`: Search the agents and plans (/api/v1/search).

Metadata: [/.well-known/oauth-authorization-server](https://carragent.com/.well-known/oauth-authorization-server) and [/.well-known/oauth-protected-resource](https://carragent.com/.well-known/oauth-protected-resource).

To check a token, `GET /agent/auth` with `Authorization: Bearer`: the answer names the client, its scopes and its limit. It is the one endpoint that needs a token; without one it answers 401 with the challenge `Bearer resource_metadata="…/.well-known/oauth-protected-resource"` (RFC 9728), so an agent learns where to start from its first request.

## Agent registration

An agent can get a token on its own, with no person registering a client. `POST https://carragent.com/agent/identity` with `{"type": "anonymous"}` returns a `registration_id` and an `identity_assertion` (a signed JWT) that is good for 24 hours. Exchange it at `POST /api/oauth2/token` with the JWT-bearer grant (RFC 7523): `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer` and `assertion=<identity_assertion>`.

```
curl -X POST https://carragent.com/agent/identity \
  -H "Content-Type: application/json" -d '{"type":"anonymous"}'
curl -X POST https://carragent.com/api/oauth2/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  --data-urlencode assertion=IDENTITY_ASSERTION
```

The token is the one an OAuth client gets: it lasts an hour, carries the read scopes (`agents:read`, `plans:read`, `search:read`) and raises the limit to 300 requests a minute, counted per registration. The assertion can be exchanged again for a new token until its 24 hours are up; then register again.

Only `anonymous` is accepted. There is no claim step and no account behind a registration: it can only read the public catalog. A registration costs nothing and needs no clean-up, and is limited to 10 a minute per IP. The steps are in [/auth.md](https://carragent.com/auth.md), and the registration is advertised in the `agent_auth` block of [/.well-known/oauth-authorization-server](https://carragent.com/.well-known/oauth-authorization-server).

## Web Bot Auth

CarragentBot is the crawler behind Carragent's Prospecting agent, which reads the public websites of businesses. Its User-Agent is `CarragentBot/1.0 (+https://carragent.com/bot)`, and [/bot](https://carragent.com/bot) says what it fetches, how to opt out and whether its requests are signed.

Whenever signing is on, its requests carry an HTTP message signature (RFC 9421), the Web Bot Auth profile: Ed25519 keys, `tag="web-bot-auth"` and a `Signature-Agent` header that names `https://carragent.com`. To check a request, fetch the keys from [/.well-known/http-message-signatures-directory](https://carragent.com/.well-known/http-message-signatures-directory) and match the signature's `keyid` to a key's `kid`. A request with this User-Agent and no signature cannot be checked this way.

## Testing

There is no sandbox and no test mode, because nothing here can change anything: the endpoints, both MCP servers and the A2A agent are read-only, and none of them reaches a business's account or data. Test against the live endpoints.

The one limit to mind is the [rate limit](https://carragent.com/developers#limits): 60 requests a minute per IP, 300 with a token. OAuth clients, agent registrations and jobs are stateless: nothing is stored, so there is nothing to clean up afterwards.

## Limits, errors and versions

60 requests every 60 seconds per IP without a token, 300 per OAuth client or agent registration with one. A batch counts one request per item, and an MCP request one per message. A response that counts against the limit carries the `RateLimit` and `RateLimit-Policy` headers; one that does not, such as a 401 for a bad token, a 405 or a preflight, has none, and the OAuth endpoints send them only with a 429. The token check (`GET /agent/auth`) counts every request, its 401 included, against the caller's address unless the token is valid. A 429 carries `Retry-After`.

Errors are RFC 9457 problem details (`application/problem+json`) with a stable `code`, such as `invalid_parameter`, `agent_not_found` or `rate_limited`.

Current version: 1.0.0, in the `Carragent-Api-Version` header. The major version is in the path. Additive changes keep v1; a breaking change ships as /api/v2, and v1 then sends `Deprecation` and a `Sunset` date at least 90 days ahead.

Questions: [admin@carragent.com](mailto:admin@carragent.com).
