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

# Authentication

> Agency and personal API keys, bearer authentication, and scopes.

Every endpoint except `GET /health` and `GET /docs` requires an API key, sent as a bearer token:

```bash theme={null}
curl "https://external-api.paraform.com/api/external/v1/identity" \
  -H "Authorization: Bearer pf_live_…"
```

Keys start with `pf_` followed by the key's environment (for example `pf_live_`). The full key is shown **exactly once**, when you create it, and can't be retrieved again. Store it in a secrets manager and only use it from your servers. Never put it in browser or mobile code.

## Key types

<Tabs>
  <Tab title="Agency keys">
    An agency key acts as your agency's API integration, not as any one person.

    * **Who can create one:** agency owners, on the **API Keys** tab of the agency settings (`/agency/api-keys`).
    * **Availability:** Paraform enables API access per agency. If you don't see the **API Keys** tab, ask your Paraform contact.
    * **Scopes:** chosen when you create the key (see [Scopes](#scopes)). The `talent_network:*` scopes are offered only when your agency has Talent Network access.
    * **Limits:** up to 50 active keys per agency. A key can have an optional expiry date and can be revoked at any time.
  </Tab>

  <Tab title="Personal keys">
    A personal key acts as you, the recruiter who created it, with the same access you have in the app.

    * **Who can create one:** any recruiter whose account has personal API keys enabled, on the **API keys** tab of the account settings (`/manage/api-keys`).
    * **Availability:** the **API keys** tab only appears for accounts that have access. If you don't see it, ask your Paraform contact.
    * **Scopes:** chosen when you create the key (see [Scopes](#scopes)).
    * **Limits:** up to 5 active keys per recruiter. A key can have an optional expiry date and can be revoked at any time. Only you can see or revoke your personal keys.
    * A personal key stops working if your account can no longer recruit on Paraform.
  </Tab>
</Tabs>

## Scopes

Each endpoint requires one or more scopes, listed on its reference page. A key can call an endpoint only if it holds every scope the endpoint requires.

| Scope | Key type | Grants |
| - | - | - |
| `identity:read` | Agency, personal | `GET /identity` |
| `talent_network:read` | Agency | Read your agency's Talent Network data, for example members, submission batches, and candidate preferences |
| `talent_network:write` | Agency | Change your agency's Talent Network data, for example upload resumes, submit candidates, and update preferences or market status |
| `agency_roles:read` | Agency | Read roles on behalf of an approved agency member |
| `roles:read` | Personal | Read role data, for example role listings, role briefs, and your saved preferences |
| `candidates:read` | Personal | Read your candidate data, for example CRM candidates, recommendations, and call transcripts |

Agency keys also carry `talent_network:read` automatically, whatever scopes you picked, so `GET /identity` lists it. Personal keys can't hold agency scopes, so agency-only endpoints, such as the Talent Network endpoints, answer `403` for them.

## Endpoints by scope

Use this list when choosing scopes for a new key. An endpoint that needs more than one scope appears under each, and the key needs all of them.

### Agency keys

| Scope | Endpoints it unlocks |
| - | - |
| `identity:read` | [`GET /identity`](/agency/api-reference/get-identity) |
| `talent_network:read` | [`GET /talent-network/batches/{batchId}`](/agency/api-reference/get-talent-network-batch)<br />[`GET /talent-network/candidates`](/agency/api-reference/list-talent-network-candidates)<br />[`POST /talent-network/candidates/lookup`](/agency/api-reference/lookup-talent-network-candidates)<br />[`GET /talent-network/candidates/{candidateUserId}/preferences`](/agency/api-reference/get-talent-network-candidate-preferences)<br />[`POST /talent-network/candidates/preferences/lookup`](/agency/api-reference/lookup-talent-network-candidate-preferences)<br />[`GET /talent-network/candidates/{candidateUserId}/fast-track`](/agency/api-reference/get-talent-network-candidate-fast-track) |
| `talent_network:write` | [`POST /resumes`](/agency/api-reference/upload-resume)<br />[`POST /talent-network/candidates/submit`](/agency/api-reference/submit-talent-network-candidate)<br />[`POST /talent-network/candidates/submit-bulk`](/agency/api-reference/submit-talent-network-candidates-bulk)<br />[`PUT /talent-network/candidates/{candidateUserId}/preferences`](/agency/api-reference/replace-talent-network-candidate-preferences)<br />[`PUT /talent-network/candidates/{candidateUserId}/fast-track`](/agency/api-reference/set-talent-network-candidate-fast-track)<br />[`POST /talent-network/candidates/off-market`](/agency/api-reference/set-talent-network-candidates-off-market)<br />[`POST /talent-network/candidates/re-enable`](/agency/api-reference/re-enable-talent-network-candidates) |
| `agency_roles:read` | [`GET /agency/roles`](/agency/api-reference/list-agency-roles)<br />[`GET /agency/roles/search`](/agency/api-reference/search-agency-roles)<br />[`GET /agency/roles/{roleId}`](/agency/api-reference/get-agency-role) |

### Personal keys

| Scope | Endpoints it unlocks |
| - | - |
| `identity:read` | [`GET /identity`](/recruiter/api-reference/get-identity) |
| `roles:read` | [`GET /recruiter/roles`](/recruiter/api-reference/list-recruiter-roles)<br />[`GET /recruiter/roles/{roleId}`](/recruiter/api-reference/get-recruiter-role)<br />[`GET /recruiter/preferences`](/recruiter/api-reference/get-recruiter-preferences)<br />[`GET /recruiter/candidates/{candidateId}/recommended-roles`](/recruiter/api-reference/list-recommended-roles-for-candidate) (also needs `candidates:read`)<br />[`GET /recruiter/recommendations`](/recruiter/api-reference/list-recruiter-recommendations) (also needs `candidates:read`) |
| `candidates:read` | [`GET /recruiter/candidates`](/recruiter/api-reference/list-recruiter-candidates)<br />[`GET /recruiter/candidates/{candidateId}/recommended-roles`](/recruiter/api-reference/list-recommended-roles-for-candidate) (also needs `roles:read`)<br />[`GET /recruiter/recommendations`](/recruiter/api-reference/list-recruiter-recommendations) (also needs `roles:read`)<br />[`GET /recruiter/parascribe-calls`](/recruiter/api-reference/list-parascribe-calls)<br />[`GET /recruiter/parascribe-calls/{callId}`](/recruiter/api-reference/get-parascribe-call) |

## Authentication errors

| Status | `type` | When |
| - | - | - |
| `401` | `authentication_error` | The `Authorization` header is missing, or the key is invalid, expired, or revoked |
| `403` | `permission_error` | The key is valid but lacks a required scope, or the action isn't permitted for this key (the message says why) |

See [Errors](/errors) for the full error format.

## Check your key

`GET /identity` returns who your key acts as (`principal` is `agency` or `recruiter`) and its effective `scopes`. Use it as a connectivity and configuration check before anything else.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.