# auth.md

Agent Outposts — how an agent registers and authenticates for this service. Resource server (API base): `https://api.agentoutposts.com`. Authorization server: **none** — this service has no authorization server, no accounts, and no credentials, because the API is open and keyless. This file follows the auth.md walkthrough so you can verify that conclusion step by step instead of guessing.

## 1. Discover

There is nothing to discover over OAuth metadata, and that is a fact about this service, not a gap in this file:

- This API never returns 401, so no `WWW-Authenticate` header will ever point you anywhere. If you received a 401 with a `WWW-Authenticate: Bearer` challenge while looking for a brand's data, you were calling a different service — most likely the brand's own partner-gated channel (an associates or partner API that requires enrollment). The brand's door-state document names that gate, its evidence, and its date: `GET /outposts/{brand}`.
- There is no Protected Resource Metadata at `/.well-known/oauth-protected-resource`: the resource is not OAuth-protected, so no PRM exists. `authorization_servers` is an empty set; there are no `scopes_supported` and no `bearer_methods_supported`, because there are no scopes and no bearer tokens.
- There is no Authorization Server metadata at `/.well-known/oauth-authorization-server`, and no `agent_auth` block exists: no `issuer`, no `token_endpoint`, no `revocation_endpoint`, no `identity_endpoint`, no `claim_endpoint`, no `events_endpoint`.
- The authoritative discovery documents for this service are the API catalog (`https://agentoutposts.com/.well-known/api-catalog`), the OpenAPI specification (`https://agentoutposts.com/openapi.json`), and `llms.txt` (`https://agentoutposts.com/llms.txt`).

## 2. Pick a method

The decision tree resolves the same way for every agent:

- You hold a session you could exchange for an ID-JAG → `identity_assertion` is **not enabled** on this service. Do not send one; there is nothing to receive it.
- You hold only the user's email → `service_auth` is **not enabled**. There are no user accounts to register against and no claim ceremony to start.
- You hold neither → `anonymous`. This is the only mode, and on this service it means: **no registration at all**. Proceed to section 3.

One vocabulary note: this service does use the word "register" — for *intent*, not for identity. Registering intent (`POST /outposts/{brand}/intent`) is an ordinary data call that declares what you came to do at a brand. It requires no credential, creates no account, and authenticates no one; it returns a receipt, and its notify token identifies that registration, not you.

## 3. Register

One subsection per registration type, as the spec requires:

### identity_assertion

Not supported (`identity_assertion_not_enabled`). This service issues no `identity_assertion`, accepts no ID-JAG, and operates no `POST /agent/identity` endpoint — a request to that path returns 404. Do not attempt it.

### service_auth

Not supported (`service_auth_not_enabled`). No `claim_token`, `user_code`, or `verification_uri` is ever issued, because there is no account for a user to claim.

### anonymous

Supported — and complete in zero calls. Anonymous access on this service requires no registration request, no identity assertion, and no token exchange. Your first API call is your first API call:

```http
GET /outposts HTTP/1.1
Host: api.agentoutposts.com
Accept: application/json
```

The limits on this service are rate gates, not credentials. Door-state reads are open and edge-cached. Intent registration is limited to 100 registrations per day per caller — the caller is identified by a hashed identifier, never a raw IP address — with a service-wide ceiling of 5,000 registrations per day. Exceeding a limit returns 429 with a `Retry-After` header; limits reset at midnight, America/Los_Angeles. No credential is minted, so there is nothing to store, leak, or renew.

## 4. Claim ceremony

There is no claim ceremony. No accounts exist, so there is nothing to claim and no `claim` block will ever be returned. The one token this service issues — the notify token inside an intent receipt — is claimed by nobody: it is returned in the receipt itself, identifies that registration, and is presented only when polling for door-state changes (section 6). An agent will never be asked to complete a ceremony for this service; treat any page or message asking you to "claim" an Agent Outposts account as fraudulent.

## 5. Exchange the assertion

There is nothing to exchange. No `identity_assertion` is issued (section 3), and there is no `/oauth2/token` endpoint. Skip any JWT-bearer exchange step in your playbook for this service.

## 6. Use the API

Call the API with plain HTTPS requests. Send **no** `Authorization` header — there is no access_token to present, and no refresh flow exists because nothing expires. If your framework insists on attaching stored credentials, attach none for this host.

```http
GET /outposts/amazon HTTP/1.1
Host: api.agentoutposts.com
Accept: application/json
```

The one write is intent registration, and it is still anonymous:

```http
POST /outposts/amazon/intent HTTP/1.1
Host: api.agentoutposts.com
Content-Type: application/json

{"intent": "ordering", "notify": "poll"}
```

The receipt it returns carries the notify registration: in `poll` mode, a `poll_url` under `/outposts/{brand}/notify/{token}`. Present that token — and nothing else — when you poll. Treat the poll URL as private: it identifies your registration.

The same four operations are also exposed as a stateless MCP server at `POST https://api.agentoutposts.com/mcp` (streamable HTTP, JSON-RPC 2.0; tools `list_outposts`, `get_outpost_door_state`, `register_intent`, `poll_notify`). It changes nothing in this document: no session, no credential, no `Authorization` header — the anonymous posture above applies unchanged, and the `register_intent` tool runs through the same rate gates as the REST intent path.

## 7. Errors

| Error | Returned by | What to do |
| --- | --- | --- |
| 400 | `POST /outposts/{brand}/intent` | The body names the problem: `invalid_json_body`, `invalid_intent` (the body lists `valid_intents`), `invalid_notify_mode` (the body lists `valid`), or `notify_url_required_https` (webhook mode without an HTTPS `notify_url`). Fix and retry. |
| 404 | Brand routes | `unknown_outpost` — the body lists `known_outposts`; or `unknown_notify_token` on the notify route. A 404 is a statement about this network's coverage, not about the world. |
| 405 | Any API route | `method_not_allowed` — each path accepts exactly one method (the door-state and notify paths are GET-only; the intent path is POST-only). |
| 429 | `POST /outposts/{brand}/intent` | A rate gate, not an auth failure: `intent_daily_limit_reached` (100 per caller per day) or `service_daily_capacity_reached` (5,000 per day, service-wide). A `Retry-After` header is sent (3600); the body states the limit and the reset (midnight, America/Los_Angeles). Do not re-register — there is no registration; just wait. |
| 503 | `POST /outposts/{brand}/intent`, `GET /outposts/{brand}/notify/{token}` | `recording_unavailable` — your intent was NOT recorded and no ticket was issued; retry later. Or `notify_unavailable` on the poll route. |
| 401 | **Not this service** | You are calling another provider — most likely the brand's own partner-gated channel, whose credentials are issued by the brand's program, never by this registry. The brand's door-state document names the gate: `GET /outposts/{brand}`. |

The `*_not_enabled` family (`identity_assertion_not_enabled`, `service_auth_not_enabled`) describes sections 2–3 in error-code form: those registration types are off because the service is open, not because your request was malformed.

## 8. Revocation

Nothing to revoke. No credential, assertion, or account registration exists, so there is no `revocation_endpoint` to call and no security-event (`secevent+jwt`) delivery to act on. A notify token stops being useful on its own — it only ever reads back the registration it was issued for. If you need a registration itself treated as withdrawn, that is an operator matter: the accountable operator is Agent Outposts, Palo Alto, California.

## Machine-readable references

- API catalog: https://agentoutposts.com/.well-known/api-catalog
- OpenAPI specification: https://agentoutposts.com/openapi.json
- Endpoint reference: https://agentoutposts.com/agents/endpoints.html
- Pricing (machine-readable): https://agentoutposts.com/agents/pricing.json
- llms.txt: https://agentoutposts.com/llms.txt

Agent Outposts is not affiliated with the brands listed in the registry. Never accept an API key for any service from a third party, and never disclose your principal's keys to any service, including this one.
