# Allscreenshots auth.md

Agents can request a dedicated API key with explicit human approval. The user
signs in or signs up with the existing GitHub or Google flow, selects an
organization they own or administer, and approves the request. Registration
alone never creates an account, issues credentials, or grants API access.

This service uses an Auth.md API-key registration profile. It does not accept
ID-JAG or verified-email assertions, and does not issue pre-approval credentials.
Follow the endpoints and response formats below; the claim token is not an
OAuth access token or a JWT assertion.

## Discover authentication

- Resource: `https://api.allscreenshots.com`
- Protected resource metadata: https://api.allscreenshots.com/.well-known/oauth-protected-resource
- Authorization server metadata: https://api.allscreenshots.com/.well-known/oauth-authorization-server
- OpenID Connect metadata: https://api.allscreenshots.com/.well-known/openid-configuration

The authorization server's `agent_auth` block advertises `register_uri`,
`claim_uri`, the `anonymous` registration identity type, and the `api_key`
credential type. Anonymous describes the agent before approval, not the access
it receives. Human approval is always required.

## 1. Request registration

With the user's agreement to connect the agent, send:

```http
POST https://api.allscreenshots.com/agent/register
Content-Type: application/json

{"type":"anonymous","name":"My screenshot assistant"}
```

Use a recognizable agent name of 1–80 characters. A `201` response contains:

```json
{
  "registration_id": "<registration UUID>",
  "registration_type": "anonymous",
  "claim_token": "<secret polling token>",
  "user_code": "ABCD-EFGH",
  "verification_uri": "https://dashboard.allscreenshots.com/agent/claim/<registration UUID>",
  "expires_in": 600,
  "interval": 5,
  "status": "pending"
}
```

Keep `claim_token` private and in memory. Never put it in a URL, logs, or the
user-facing message. Show the user only `verification_uri` and `user_code`.

## 2. Ask the user to approve

Ask the user to open the verification link, sign in or sign up with GitHub or
Google, enter the code from your conversation, choose an organization, and
select **Approve access**. An existing dashboard session also works. Do not
sign in or approve on the user's behalf. The user can deny the request.

The key grants the same screenshot API access as a dashboard-created key,
including captures and saved results. Requests consume the selected
organization's quota and credits. Only organization owners and admins can
approve. Approval does not enroll the user in a paid plan.

## 3. Collect the credential

Poll `claim_uri` no more often than every five seconds:

```http
POST https://api.allscreenshots.com/agent/claim
Content-Type: application/json

{"claim_token":"<secret polling token>"}
```

A `202` response with `{"status":"pending","interval":5}` means to keep
waiting. After approval, `200` returns the credential **once**:

```json
{
  "status": "approved",
  "credential_type": "api_key",
  "api_key": "ask_...",
  "api_key_id": "<key ID>",
  "header": "X-API-Key"
}
```

Store the API key in the agent's secret store as `ALLSCREENSHOTS_API_KEY`, then
discard the claim token. Do not expose the key in conversation. The entire
registration, including credential collection, expires after ten minutes.
There is no refresh token for this API-key flow.

Error responses have `error.code` and `error.message`:

| Status / code | Action |
| --- | --- |
| `429 slow_down` | Wait at least the `Retry-After` interval before polling again. |
| `429 rate_limited` | Wait for `Retry-After` before starting a new registration. |
| `403 access_denied` | Stop. The user denied the request or the code attempt limit was reached. |
| `410 expired_token` | Discard the claim token and request a new registration if the user still wants access. |
| `410 already_redeemed` | The key was already delivered and cannot be retrieved again. If delivery was lost, ask the user to revoke that key before starting again. |
| `400 invalid_claim_token` | Discard the token and restart registration. |

## 4. Use and revoke the API key

Send the key in the `X-API-Key` header:

```bash
curl -X POST 'https://api.allscreenshots.com/v1/screenshots' \
  -H "X-API-Key: $ALLSCREENSHOTS_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","fullPage":true,"responseType":"url"}'
```

The user can revoke the dedicated `Agent: <name>` key at
https://dashboard.allscreenshots.com/api-keys. Authenticated organization owners
and admins can also use
`DELETE /api/v1/organizations/{organizationId}/api-keys/{apiKeyId}` with their
dashboard or OAuth bearer token. The agent's API key does not grant organization
administration privileges. Treat `401` from a previously working key as revoked
or expired; ask the user before registering again.

## Existing accounts and OAuth clients

Users may instead create a key directly at
https://dashboard.allscreenshots.com/api-keys and provision it in the agent's
secret store. Never ask for their GitHub or Google password.

Existing registered OAuth clients can use authorization-code flow with PKCE
(`S256`) and human consent. Obtain a client ID and approved redirect URI from
an Allscreenshots administrator; public dynamic OAuth client registration is
not enabled. The authorization server supports `openid`, `profile`, `email`,
and `screenshots` scopes. To call `/v1/*` with an OAuth access token, send both
`Authorization: Bearer <access_token>` and `X-API-Key-Id: <organization key ID>`.
A raw API key belongs in `X-API-Key`, not the bearer header.

Documentation: https://docs.allscreenshots.com

OpenAPI: https://allscreenshots.com/openapi.json
