---
title: "Protected-resource metadata (RFC 9728 + auth.md agent_auth)"
method: GET
path: "/.well-known/oauth-protected-resource"
tags: ["Metadata"]
---

# Protected-resource metadata (RFC 9728 + auth.md agent_auth)

`GET /.well-known/oauth-protected-resource`

## Request

- Base URL: `https://api.rateapi.dev`
- URL: `https://api.rateapi.dev/.well-known/oauth-protected-resource`
- Auth: none required

Machine-readable description of how to obtain a credential for this API, served from the API host itself.

This is the document the `WWW-Authenticate` challenge on every 401 points at, so it MUST be keyless — a discovery document that requires the credential it explains how to get is a closed loop. It is served here rather than only on the docs site because `resource_metadata` resolves against the RESOURCE: an agent probing `api.rateapi.dev` for it and getting a 404 concludes this API publishes nothing.

It advertises exactly what rateAPI implements: opaque `rk_` API keys obtained by an unauthenticated `POST /keys`. There is no OAuth authorization server, no token endpoint, and no assertion exchange, so `authorization_servers` is absent and `identity_types_supported` is `["anonymous"]` alone.

## Response `200`

The metadata document. Edge-cached; safe to fetch once and reuse.

- ProtectedResourceMetadata: RFC 9728 protected-resource metadata, extended with the auth.md `agent_auth` block. `authorization_servers` is deliberately ABSENT: rateAPI runs no OAuth authorization server, and naming one would advertise a URI that 404s on first fetch — worse for an agent than an omitted field.
  - `resource` string, uri, required: Canonical identifier of the protected resource these credentials are for.
  - `resource_name` string: Human-readable name of this protected resource.
  - `resource_documentation` string, uri: Machine-readable documentation for the resource — this API’s OpenAPI spec.
  - `bearer_methods_supported` string[]: Only `header`. The `X-API-Key` spelling is equivalent but has no registered vocabulary term, so it is described in `agent_auth.notes` instead.
  - `bearer_token_prefix` string: Every credential starts with this. Keys are opaque and must not be parsed.
  - `scopes_supported` string[]: Empty: keys carry no scopes at all. Stated positively so a client does not read an absent field as an oversight.
  - `agent_auth` object: auth.md registration block. Every URI here is one this API serves or links to.
    - `skill` string, uri: The auth.md walkthrough.
    - `register_uri` string, uri: Where an agent registers to obtain its own credential.
    - `identity_types_supported` string[]: Drawn only from the auth.md enum. rateAPI advertises `anonymous` alone, because it implements no assertion exchange. Variants such as `verified_email` or `id-jag` are NOT identity types — they belong inside `identity_assertion.assertion_types_supported`.
    - `anonymous` object: Sibling block for the `anonymous` identity type: an unauthenticated POST returns a server-generated secret exactly once. There is no claim step.
      - `register_uri` string, uri: Where an agent POSTs to register.
      - `register_method` string: HTTP method used against `register_uri`.
      - `register_request_example` object: A registration body that works as-is.
        - `email` string, email: Contact address the key is issued against.
        - `source` string: Free-text attribution for where the registration came from.
      - `register_headers_required` object: Headers required to create a credential safely.
      - `credential_type` string: What the registration returns.
      - `credential_prefix` string: Prefix every issued credential carries.
      - `credential_delivery` string: How the secret reaches the caller. It is returned inline; a byte-identical retry can replay the encrypted response for 24 hours, after which only the long-term hash remains.
      - `identical_retry_window_seconds` integer: How long a byte-identical request using the same enrollment UUID can recover the original encrypted response.
      - `documentation` string, uri: Walkthrough for this registration flow.
    - `revocation_uri` string: Session-authenticated dashboard route; not callable with an API key alone.
    - `revocation_method` string: HTTP method used against `revocation_uri` to revoke a credential.
    - `notes` string[]: Facts about this credential scheme an agent would otherwise have to discover by trial: the token format, the accepted headers, the sandbox prefix, and the registration cap.

## Other responses

- `500`: An unexpected failure on our side. The `traceId` in the body identifies the request in our logs — quote it when reporting. Safe to retry with backoff.

---

[API](https://skmtc.dev/rateapi/apis/rate-api.md) · [All operations](https://skmtc.dev/rateapi/apis/rate-api/llms.txt) · [OpenAPI document](https://skmtc.dev/rateapi/apis/rate-api/revisions/06a6db76995f?raw)
