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

# Get Providers

> List every provider available to an app, optionally including activation state.

Returns the full provider catalog available in the current environment for the given app. By default the response is the plain `Provider` catalog (no per-app activation data). Pass `include=activation` to upgrade each entry with the app's `status` and an `activation` block describing where the provider is in the activation flow and what (if anything) is still required.

## Request

<ParamField header="Authorization" type="string" required>
  `Bearer <API_KEY>` from Console > Developers > Workspace API Keys.
</ParamField>

### Path parameters

<ParamField path="client_id" type="string" required>
  Client identifier of the app.
</ParamField>

### Query parameters

<ParamField query="include" type="string">
  Set to `activation` to include the per-app activation state alongside each provider.

  Accepted as a single value (`?include=activation`) or repeated (`?include=activation&include=...`). Unknown values are ignored; passing nothing (or omitting the parameter) returns the plain catalog.
</ParamField>

## Response

The response is a plain JSON array. Each entry is a `Provider`. With `?include=activation`, each entry is a `Provider` plus the `status` and `activation` fields below.

### Provider (always present)

<ResponseField name="id" type="string">
  Provider identifier (e.g., `mitid`, `bankidse`, `ftn`, `passport`).
</ResponseField>

<ResponseField name="name" type="string">
  Human-readable provider name.
</ResponseField>

<ResponseField name="description" type="string">
  Provider description.
</ResponseField>

<ResponseField name="logoUrl" type="string">
  URL of the provider logo.
</ResponseField>

<ResponseField name="countries" type="string[]">
  ISO country codes the provider serves.
</ResponseField>

<ResponseField name="flowTypes" type="string[]">
  Verification flow types the provider supports (`qr`, `redirect`, `push`, `dc`).
</ResponseField>

<ResponseField name="scopes" type="string[]">
  Available OIDC scopes for the provider.
</ResponseField>

<ResponseField name="loa" type="number[]">
  Levels of Assurance the provider can issue.
</ResponseField>

<ResponseField name="defaultLoa" type="number">
  Default LoA when the upstream IDP does not return one. `0` means unspecified.
</ResponseField>

<ResponseField name="type" type="number">
  Digital ID type: `1` (Centralized IdP), `2` (Chip-based), `3` (Decentralized Wallet).
</ResponseField>

<ResponseField name="verificationModel" type="string">
  `disclosure` (provider returns IDP-derived attribute claims) or `match` (provider verifies caller-supplied identity values). Omitted when not applicable.
</ResponseField>

<ResponseField name="matchGranularity" type="string">
  For match-model providers: `per_field` (one outcome per matched field) or `aggregate` (single verdict). Omitted for disclosure providers.
</ResponseField>

<ResponseField name="isActive" type="boolean">
  `true` iff the provider's derived activation status is `activated` — equivalent to `status === 'activated'`. `false` for every other status, including providers that have never been added to the app.
</ResponseField>

<ResponseField name="needAction" type="boolean">
  `true` when the provider is `activated` but its stored provider config fails the provider's `configSchema` validation (missing or malformed credentials, etc.). Use it to surface a "finish setup" nudge in the UI.
</ResponseField>

### Added by `?include=activation`

<ResponseField name="status" type="string">
  Per-app provider status, derived from the latest activation ticket.

  One of:

  * `not_activated` — never submitted, or the provider has not been added to the app.
  * `activation_requested` — a registration-type submission has been received and is waiting for operator review.
  * `activation_processing` — operator review is in progress, or (sandbox `demo: true`) the brief auto-approve window is still open.
  * `rejected` — the latest submission failed validation or was rejected by operator review. Resubmit via [Submit Activation](/api-reference/workspace/activation/submit-activation).
  * `activated` — provider is ready for live verifications.
</ResponseField>

<ResponseField name="activation" type="object">
  Activation block. Always present when `include=activation` is set, even when nothing has been submitted (in that case `status` is `not_activated` and `id`, `requestedAt`, etc. are omitted).

  <Expandable title="activation">
    <ResponseField name="status" type="string">
      Latest activation ticket status, or `not_activated` when no ticket exists. Mirrors the top-level `status`.
    </ResponseField>

    <ResponseField name="id" type="string">
      Ticket identifier (`act_<ulid>`). Present once a ticket exists.
    </ResponseField>

    <ResponseField name="requirements" type="object[]">
      Inputs the customer must (or did) submit, derived from the provider's activation spec.

      For **direct** providers (e.g., `passport`, most chip-based IDs) this is always `[]` — no inputs needed.

      For **registration** providers, one entry per required field. Common fields include `legalCompanyName`, `registrationNumber`, `serviceDescription`, `displayName`, `contactEmail`, `userDataLevel` — see [Submit Activation](/api-reference/workspace/activation/submit-activation) for the catalog.

      For **contract** providers (e.g., `ftn`, `uaepass`, `idin`), a single synthetic `info`-type entry exposes the Hopae support contact — the activation itself happens off-API.

      <Expandable title="requirement">
        <ResponseField name="id" type="string">
          Field identifier (or `supportContact` for contract providers).
        </ResponseField>

        <ResponseField name="type" type="string">
          Input type: `text`, `email`, `url`, `checkbox`, `select`, or `info`. Drives the UI control to render.
        </ResponseField>

        <ResponseField name="label" type="string">
          Human-readable label.
        </ResponseField>

        <ResponseField name="description" type="string">
          Short guidance shown to the customer.
        </ResponseField>

        <ResponseField name="example" type="string">
          Short sample value to render as the input placeholder (e.g., `DE123456789` for `vatNumber`). Present on free-text fields (`text`, `email`, `url`); omitted for `select`, `checkbox`, `info`, and the logo upload.
        </ResponseField>

        <ResponseField name="required" type="boolean">
          `true` for every input listed by a registration spec. Omitted for `info` entries.
        </ResponseField>

        <ResponseField name="maxLength" type="number">
          Maximum allowed string length, when the field declares one.
        </ResponseField>

        <ResponseField name="pattern" type="string">
          Advisory regex hint. Not enforced server-side.
        </ResponseField>

        <ResponseField name="options" type="object[]">
          Allowed values for `select` / `checkbox` fields. Each option is `{ value, description }`.
        </ResponseField>

        <ResponseField name="currentValue" type="string | boolean | null">
          Cached value from the app's `companyInfo` (or matching per-provider requirements). Use this to prefill the form.
        </ResponseField>

        <ResponseField name="submittedValue" type="string | boolean | null">
          Value most recently submitted on the ticket, or `null` when no submission has been made.
        </ResponseField>

        <ResponseField name="value" type="string">
          *(info entries only)* The exposed value — for contract providers this is the support email.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="requestedAt" type="string">
      ISO 8601 timestamp of the latest submission. Omitted when no ticket exists.
    </ResponseField>

    <ResponseField name="activatedAt" type="string">
      ISO 8601 timestamp of activation completion. Omitted until the provider becomes `activated`.
    </ResponseField>

    <ResponseField name="rejectedAt" type="string">
      ISO 8601 timestamp of the most recent rejection. Omitted unless `status` is `rejected`.
    </ResponseField>

    <ResponseField name="rejection" type="object">
      Present only when `status` is `rejected`.

      <Expandable title="rejection">
        <ResponseField name="reason" type="string">
          `missing_required_fields`, `invalid_value`, `provider_rejected`, or `other`.
        </ResponseField>

        <ResponseField name="missingFields" type="string[]">
          Field ids that triggered a `missing_required_fields` rejection.
        </ResponseField>

        <ResponseField name="message" type="string">
          Free-form message from the operator (e.g., the rejection reason).
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Sandbox behavior

Sandbox runs the same activation flow as production and writes real tickets, so `activation.id` is present and statuses are real:

* Providers that have never been added to the app (no entry in `apps.providers`) are **omitted** from the response.
* By default, statuses match production: **direct** providers read as `activated`, **registration** providers stay at `activation_requested` until an operator reviews them, and **contract** providers read as `not_activated`.
* When the activation was submitted with `demo: true` (see [Submit Activation](/api-reference/workspace/activation/submit-activation)), registration and contract providers read as `activation_processing`, then flip to `activated` about 1 second later.

## Errors

| Status | Body                 | When                                                 |
| ------ | -------------------- | ---------------------------------------------------- |
| `401`  | `INVALID_API_KEY`    | Missing or malformed `Authorization` header.         |
| `403`  | `RESOURCE_FORBIDDEN` | The API key's organization does not own `client_id`. |
| `404`  | `RESOURCE_NOT_FOUND` | No app matches `client_id`.                          |

<RequestExample>
  ```bash Plain catalog theme={null}
  curl -H "Authorization: Bearer sk_workspace_test_..." \
    "https://sandbox.api.hopae.com/connect/v1/apps/HqTRDIYH/providers"
  ```

  ```bash Include activation theme={null}
  curl -H "Authorization: Bearer sk_workspace_test_..." \
    "https://sandbox.api.hopae.com/connect/v1/apps/HqTRDIYH/providers?include=activation"
  ```
</RequestExample>

<ResponseExample>
  ```json include=activation theme={null}
  [
    {
      "id": "mitid",
      "name": "MitID",
      "description": "Danish national eID",
      "logoUrl": "https://static.hopae.com/providers/mitid.png",
      "countries": ["DK"],
      "flowTypes": ["redirect"],
      "scopes": ["openid", "profile"],
      "loa": [3],
      "defaultLoa": 3,
      "type": 1,
      "verificationModel": "disclosure",
      "isActive": true,
      "needAction": false,
      "status": "activated",
      "activation": {
        "status": "activated",
        "id": "act_01HXYZ2KQ8M0E3J1N9V0P5T8YR",
        "requirements": [
          {
            "id": "legalCompanyName",
            "type": "text",
            "label": "Legal Company Name",
            "description": "The registered legal name of the company, as shown on official incorporation documents.",
            "example": "Acme Corporation B.V.",
            "required": true,
            "currentValue": "Acme Corp",
            "submittedValue": "Acme Corp"
          },
          {
            "id": "registrationNumber",
            "type": "text",
            "label": "Registration Number",
            "description": "The company registration number from your country's business registry (e.g., RCS Luxembourg, HRB Germany, CVR Denmark).",
            "example": "HRB 123456",
            "required": true,
            "currentValue": "12345678",
            "submittedValue": "12345678"
          }
        ],
        "requestedAt": "2026-04-20T02:20:27.521Z",
        "activatedAt": "2026-04-20T02:20:32.521Z"
      }
    },
    {
      "id": "ftn",
      "name": "FTN",
      "description": "Finnish Trust Network",
      "logoUrl": "https://static.hopae.com/providers/ftn.png",
      "countries": ["FI"],
      "flowTypes": ["redirect"],
      "scopes": ["openid", "profile"],
      "loa": [3],
      "defaultLoa": 3,
      "type": 1,
      "isActive": false,
      "needAction": true,
      "status": "not_activated",
      "activation": {
        "status": "not_activated",
        "requirements": [
          {
            "id": "supportContact",
            "type": "info",
            "label": "Activation Support Contact",
            "description": "Contact Hopae support to initiate FTN activation. We will guide you through signing the Customer Agreement and (optionally) Appendix A.",
            "value": "support@hopae.com"
          }
        ]
      }
    }
  ]
  ```
</ResponseExample>
