# One Move auth.md

You are an agent. One Move has a public read API and a WorkOS auth.md profile. Follow this walkthrough in order.

## Discover

Every protected entry point answers `401 Unauthorized` with:

```
WWW-Authenticate: Bearer resource_metadata="https://api.getonemove.app/.well-known/oauth-protected-resource"
```

Fetch the [protected-resource metadata](https://api.getonemove.app/.well-known/oauth-protected-resource). It returns:

```json
{
  "resource": "https://api.getonemove.app/",
  "resource_name": "One Move",
  "authorization_servers": ["https://api.getonemove.app/"],
  "scopes_supported": ["reports:read", "reports:write", "docs:read"],
  "bearer_methods_supported": ["header"]
}
```

Then fetch the [authorization-server metadata](https://api.getonemove.app/.well-known/oauth-authorization-server). Its `agent_auth` block points at the `identity_endpoint` and back at this skill.

## Pick a method

- **anonymous** — public reads. No registration. Use `GET /v1/constraints`, `GET /v1/free-reports/{site}/{username}` and `GET /v1/jobs/{id}` directly. This is the right method for most report lookups.
- **service_auth** — an agent acting for a known account. Register a client with `POST /v1/clients` and use the OAuth 2.0 `client_credentials` grant. The account owner authorises the client out of band through the normal sign-in and billing flow; no identity assertion is minted by One Move for a third-party IdP.
- **identity_assertion / id-jag** — not accepted yet. `identity_assertion.assertion_types_supported` is empty. Use service_auth or anonymous.

## Register

For service_auth:

```bash
curl -sS -X POST https://api.getonemove.app/v1/clients \
  -H 'Content-Type: application/json' \
  -d '{"client_name":"my-agent"}'
```

Response:

```json
{
  "client_id": "om_...",
  "client_secret": "shown-once",
  "scopes": ["reports:read", "reports:write", "docs:read"],
  "token_endpoint": "https://api.getonemove.app/oauth2/token"
}
```

The secret is shown once. Store it in the agent's secret store, not in a prompt.

For anonymous there is nothing to register. You may still POST `{"type":"anonymous"}` to the `identity_endpoint` to receive a short-lived identity assertion; exchanging it is optional for public reads.

## Claim

The `claim_endpoint` exists for compatibility with the auth.md profile but One Move does not use a device-code claim ceremony. Public data needs no claim. Account ownership is established through the normal magic-link sign-in at https://getonemove.app/sign-in; an agent must not ask a user for their sign-in token or email link.

## Exchange

```bash
curl -sS -X POST https://api.getonemove.app/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=om_...' \
  -d 'client_secret=...'
```

Response:

```json
{
  "access_token": "om_at_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "reports:read reports:write docs:read"
}
```

If you registered anonymously, exchange the assertion with `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=...` at the same endpoint.

## Use the access_token

Send `Authorization: Bearer <access_token>`. Tokens are scoped; request only the scopes you need. A token with `reports:read` can read every public endpoint and the docs MCP server.

## Errors

| Code | Where | What to do |
| --- | --- | --- |
| `invalid_client` | `/oauth2/token` | Client id or secret is wrong. Re-register. |
| `invalid_grant` | `/oauth2/token` | Assertion expired or replayed. Start again. |
| `unsupported_grant_type` | `/oauth2/token` | Use `client_credentials` or the JWT-bearer URN. |
| `invalid_scope` | `/oauth2/token` | Request a subset of `reports:read reports:write docs:read`. |
| `rate_limited` | any 429 | Honour `Retry-After`. |
| `interaction_required` | `/agent/identity` | Not used for public data; use anonymous. |

## Revocation

POST `token=<access_token>&token_type_hint=access_token` to `https://api.getonemove.app/oauth2/revoke`. It is idempotent and returns 200. To revoke every token for a client, send the client id through https://getonemove.app/support.

Spec: https://github.com/workos/auth.md
