# auth.md

This file tells an agent how to authenticate against the CoworkingView public
API — `api.coworkingview.com`, the `/v1` gateway described in full at
`https://coworkingview.com/openapi.json`. Read it before writing any client
code: this API does not implement OAuth 2.0 client registration, credential
claiming, or token issuance. Where the spec this file follows
(`https://workos.com/auth-md`) expects a live flow, the honest answer below is
"not applicable" — do not guess at a flow that isn't there; it will not work.

## Discover

`GET /.well-known/oauth-protected-resource` and
`GET /.well-known/oauth-authorization-server` both resolve on this origin and
are safe to fetch, but they describe an API with **no OAuth-protected
resources**: `scopes_supported` and `bearer_methods_supported` are empty
arrays, and the authorization-server document's `grant_types_supported` is
also empty. The only thing of substance in the authorization-server document
is `agent_auth.skill`, which points back at this file — that is the whole
discovery hop. There is no `WWW-Authenticate` header on any response from this
API, on a 401 or otherwise, because no endpoint ever asks for a bearer
credential.

A client that treats a page URL as the resource identifier (RFC 9728 §3.1)
inserts the well-known segment in front of that path. For
`https://coworkingview.com/en` the document is
`GET /.well-known/oauth-protected-resource/en`. Same account as the root
document — empty scopes, this origin as `authorization_servers` — with
`resource` set to the page URL the client started from. Deeper pages follow
the same shape (`/.well-known/oauth-protected-resource/en/coworking/berlin`).

## Pick a method

There is nothing to pick. Every `GET` under `/v1/*` — properties, search,
market rates, rankings, health — is unauthenticated. No API key, no client
ID, no session. The one exception, `POST /v1/leads/inquiry`, isn't gated by
an agent credential either: it's gated by a Cloudflare Turnstile token that a
human's browser mints by solving a challenge on `coworkingview.com`'s own
inquiry form. That token is tied to that page render and is not something an
agent can obtain by calling an endpoint.

## Register

Not applicable — there is no client-registration endpoint. An earlier
version of this API's `.well-known` metadata advertised a `register_uri` at
`/oauth/register`; that path 404s and always has. It has been removed from
the metadata rather than left to mislead a client that tries it. Reads need
no identity, so there is nothing to register for. Registering a bot account
to reach the write endpoint would not help either — see Pick a method above.

## Claim

Not applicable — there is no claim ceremony. This API does not implement an
`identity_assertion`/ID-JAG exchange, issues no `user_code` or
`verification_uri` for a device-style hand-off, and the `claim_uri` that used
to appear in `/.well-known/oauth-authorization-server` (`/oauth/claim`) also
404s and has been removed for the same reason as `register_uri` above. There
is no credential on the other end of a claim to go get.

## Use the credential

For reads, there is no credential to attach — call the endpoint with no
`Authorization` header:

```
curl -s "https://api.coworkingview.com/v1/properties?locale=en&city=berlin&pageSize=3"
```

For the one write endpoint, attach `turnstileToken` from a real, freshly
rendered Turnstile widget. There is no programmatic way to mint one outside a
browser, and that is deliberate anti-spam protection for the operators whose
inquiries land in this system — do not invent a token or replay one; it will
fail verification server-side.

## Errors

Every error is `application/problem+json` (RFC 9457): `type`, `title`,
`status`, and usually `code`. The ones an agent will actually hit:

- `400 VALIDATION_FAILED` — request body or query params failed schema
  validation; `errors` lists the offending fields.
- `403 CHALLENGE_FAILED` — `POST /v1/leads/inquiry` without a valid
  `turnstileToken`. This is not an auth failure to retry with a different
  credential; there isn't one to switch to.
- `429` — rate limited. Every response, success or error, carries
  `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds); a
  `429` adds `Retry-After`. Pace requests from those headers instead of
  retrying blind.

## Revocation

Not applicable — nothing is issued, so nothing can be revoked. There is no
`/oauth2/revoke`, no token to invalidate, and no Security Event Token stream
to subscribe to for out-of-band revocation. If a specific caller needs to be
blocked, that happens at the network edge, not through this file.
