> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phosra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Provider Discovery — the directory

> Browse GET /api/v1/directory to find a provider counterparty by DID, role, and capability, then resolve how to reach it with GET /providers/{did}/connect. The directory is an index over the signed Trust List — never a key gate.

Before a platform can run the connect ceremony it needs a **provider counterparty**: a DID that
is on the Trust List, active, and reachable. `GET /api/v1/directory` is the public browse index
for exactly that — "who is registered, in what role, with what capabilities, and does it have a
sealed-classify enclave I can connect to."

<Note>
  **The directory is an index, not a key gate.** It serves booleans and pointers only —
  `has_payload_key`, an `enclave` marker, the Trust-List path. Actual key material is resolved
  from the one root-signed `/.well-known/ocss/trust-list` document (§11.9 / §4.2 cl.2), verified
  offline against your pinned root X. The directory never returns a public key.
</Note>

***

## `GET /api/v1/directory`

Public, unauthenticated read. No `phosra_` key, no signature.

**Query parameters (all optional):**

| Param            | Meaning                                                                                                                                                                                                                    |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `role=<r>`       | Keep entries whose Trust-List `entry_role` equals `<r>`. `role=routing` matches the default (empty) role. Vocabulary: `classifier-accredited`, `verifying-agency`, `enforcement-agent`, `independent-advocate`, `routing`. |
| `capability=<c>` | Keep entries that declare §5.3 manifest cell `<c>` as `enforce` or `alert_only` on at least one OS (e.g. `capability=addictive_pattern_block`).                                                                            |
| `status=all`     | Include non-active entries (default: active only).                                                                                                                                                                         |

**`200` response:**

```json theme={null}
{
  "trust_list": "/.well-known/ocss/trust-list",
  "issue_number": 57,
  "issued_at": "2026-07-03T13:10:45Z",
  "entries": [
    {
      "entity": "Loopline (OCSS reference emitter)",
      "did": "did:ocss:loopline",
      "role": "",
      "tier": "verified",
      "status": "active",
      "jurisdiction": [],
      "valid_through": "2026-12-30T13:10:45Z",
      "capabilities": [],
      "has_payload_key": true,
      "enclave": {
        "enclave_id": "01f05283-…",
        "endpoint_url": "…",
        "mode": "standin",
        "attested": false
      }
    }
  ]
}
```

| Field             | Meaning                                                                                                                                                                                                                                                                                   |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `did`             | The counterparty DID you pass to the connect-config lookup below.                                                                                                                                                                                                                         |
| `role`            | Trust-List `entry_role` (empty = a routing entry).                                                                                                                                                                                                                                        |
| `tier`            | `provisional` \| `verified` \| `accredited` (§3.6 ladder).                                                                                                                                                                                                                                |
| `has_payload_key` | `true` ⇒ the DID publishes an encryption JWK on its Trust-List entry, so you can seal a payload to it once you resolve its JWKS from the signed list.                                                                                                                                     |
| `enclave`         | Present when the DID has an **active sealed-classify enclave** registered — the "there is a connectable classify counterparty here" marker. `attested` reflects live attestation (a stored-but-expired attestation reads `false`).                                                        |
| `capabilities`    | Union of §5.3 manifest cells the entry declares `enforce`/`alert_only`. **Empty until the provider declares a capability manifest** (a §5.3 accreditation-time step), so a freshly self-registered sandbox provider is *listed and connectable but not yet filterable* by `?capability=`. |

<Warning>
  **`role` and `capabilities` are accreditation-declared metadata.** A provider that has not yet
  declared an `entry_role` or a §5.3 capability manifest still appears in the unfiltered listing
  and is still connectable — it just won't match a `?role=` / `?capability=` filter. In sandbox,
  most reference providers ship without those declarations, so **enumerate unfiltered and select
  on the `enclave` marker (and a `200` from the connect-config lookup below) rather than relying on
  the facet filters.**
</Warning>

***

## Recipe — find a connectable provider

```ts theme={null}
const CENSUS = "https://phosra-api-sandbox-production.up.railway.app"

// 1. Browse the directory (unfiltered — see the warning above).
const dir = await (await fetch(`${CENSUS}/api/v1/directory`)).json()

// 2. Candidates = active entries that advertise a sealed-classify enclave.
const candidates = dir.entries.filter((e) => e.enclave)

// 3. Resolve HOW to reach one: the connect-config lookup.
//    200 → connectable (returns authorize_url/token_url/profiles_url).
//    404 → on the Trust List but no connect config registered yet (skip it).
for (const c of candidates) {
  const res = await fetch(
    `${CENSUS}/api/v1/providers/${encodeURIComponent(c.did)}/connect`
  )
  if (res.ok) {
    const cfg = await res.json()          // { authorize_url, token_url, profiles_url, scopes, name }
    // feed cfg into the connect ceremony (initPlatformOAuth)
    break
  }
}
```

`GET /api/v1/providers/{did}/connect` is the companion lookup — it returns the OAuth
`authorize_url` / `token_url` / `profiles_url` the ceremony needs. See
[Get provider connect config](/api-reference/providers/connect) for its full contract (and the
deliberate `404` for an unknown, revoked, or connect-config-less DID — no existence leak).

***

## Next

* [Get provider connect config](/api-reference/providers/connect) — the `{did}` → OAuth-endpoints lookup
* [Platform Registration](/integration/platform-registration) — mint your own endpoint + `connect_secret`
* [Platform Quickstart](/integration/platform) — receive the connection, verify the profile, enforce, confirm
