# Caretta Authentication for Agents (auth.md)

This document follows the auth.md convention (https://workos.com/auth-md): a prose walkthrough an agent can follow to discover, obtain, use, and revoke credentials for Caretta. Canonical: https://www.caretta.so/auth.md · Last updated: 2026-08-24.

## Discover

Caretta's agent-facing surface is the MCP server at `https://gateway.caretta.app/mcp` (Streamable HTTP). It is an OAuth 2.1 protected resource.

- Protected resource metadata (RFC 9728): https://gateway.caretta.app/.well-known/oauth-protected-resource/mcp (mirrored at https://www.caretta.so/.well-known/oauth-protected-resource)
- The metadata lists `authorization_servers`; fetch `<authorization_server>/.well-known/oauth-authorization-server` (RFC 8414) for the authorization, token, and registration endpoints.
- An unauthenticated request to the MCP endpoint returns `401` with `WWW-Authenticate: Bearer realm="caretta-mcp", resource_metadata="https://gateway.caretta.app/.well-known/oauth-protected-resource/mcp"` — follow that `resource_metadata` link to start.
- Server card: https://www.caretta.so/.well-known/mcp/server-card.json · API catalog: https://www.caretta.so/.well-known/api-catalog · OpenAPI: https://www.caretta.so/openapi.json

## Pick a method

| Method | Use when | Credential |
| --- | --- | --- |
| `agent_auth` via OAuth 2.1 + PKCE (S256) | An agent acts on behalf of a Caretta user (Claude, ChatGPT, Cursor, custom agents) | Short-lived Bearer access token + refresh token |
| Bearer token from the Caretta app | Server-side integrations calling the REST API (`/api/v1`) | User-issued Bearer token |
| None | Public endpoints: `/api/v1/health`, `/openapi.json`, `/llms.txt`, `/.well-known/*` | — |

There is no API-key or client-credentials flow; every credential is bound to a signed-in Caretta user. Identity assertion (`id-jag` / `identity_assertion`) is not currently supported.

## Register

1. Read the authorization-server metadata discovered above. If it advertises a `registration_endpoint` (`register_uri`), perform dynamic client registration (RFC 7591) with your `redirect_uris`; otherwise use the public MCP client registration your MCP host performs automatically.
2. Record the returned `client_id`. No client secret is required for public clients using PKCE.

## Claim

1. Generate a PKCE `code_verifier` and `code_challenge` (S256).
2. Open the `authorization_endpoint` with `response_type=code`, your `client_id`, `redirect_uri`, `code_challenge`, `resource=https://gateway.caretta.app/mcp`, and `scope=openid`. `openid` is the only OAuth scope the authorization server accepts; the Caretta permissions (`calls:read`, `todos:read`, `todos:write`) are granted on the MCP consent screen, not as OAuth scopes.
3. The user signs in to Caretta in the browser and approves the requested permissions.
4. Exchange the returned `code` at the `token_endpoint` with the `code_verifier` to receive `access_token`, `refresh_token`, and `expires_in`.

## Use the credential

- MCP: send `Authorization: Bearer <access_token>` on every request to `https://gateway.caretta.app/mcp`. Tools: `caretta_list_calls`, `caretta_list_my_calls`, `caretta_search_transcripts`, `caretta_get_call`, `caretta_list_todos`, `caretta_create_todo`, `caretta_update_todo`.
- REST: send `Authorization: Bearer <token>` to `https://www.caretta.so/api/v1/...`. Responses include `X-API-Version` and RFC RateLimit headers (60 requests/minute).
- Refresh: when the access token expires, POST `grant_type=refresh_token` to the `token_endpoint`.

## Errors

| Status | Meaning | What to do |
| --- | --- | --- |
| `401` + `WWW-Authenticate: Bearer` | Missing, expired, or invalid token | Follow `resource_metadata`, refresh or re-authorize |
| `403` (`insufficient_scope`) | Token lacks a required scope | Re-authorize requesting the scope named in the response |
| `429` + `Retry-After` | Rate limit exceeded | Wait for `Retry-After` seconds, then retry |
| `404` JSON `{ "error": { "code": "not_found" } }` | Unknown REST path | Check https://www.caretta.so/openapi.json |

All REST errors are JSON: `{ "error": { "code", "message", "status", "resolution" } }`.

## Revocation

- Users revoke agent access at any time from the Caretta app (Settings → Connected apps); revoked tokens immediately return `401`.
- If the authorization server advertises a `revocation_endpoint` (RFC 7009), agents should call it when discarding a credential.
- Webhooks are signed with HMAC-SHA256 (`X-Caretta-Signature`); rotate secrets from the Caretta app. See https://www.caretta.so/docs/webhooks.

## Support

hello@caretta.so · https://www.caretta.so/contact · Docs: https://www.caretta.so/docs/caretta-mcp
