> ## 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.

# Find a candidate and read their full profile

> Look up one of your CRM candidates, then read their profile, preferences, work history, and submissions.

This takes two calls. The first finds the candidate and returns their `candidateId`. The second returns everything your CRM holds on them. You need a personal key with `candidates:read` and `submissions:read`.

## Find the candidate

[`GET /recruiter/candidates`](/recruiter/api-reference/list-recruiter-candidates) returns the candidates in your own CRM, newest first. Filter it down to one person, for example by LinkedIn profile link or email:

```bash theme={null}
curl -G "https://external-api.paraform.com/api/external/v1/recruiter/candidates" \
  -H "Authorization: Bearer $PARAFORM_API_KEY" \
  --data-urlencode "linkedinUrl=https://www.linkedin.com/in/jane-doe"
```

Each row has a `candidateId`. Keep it for the next call. See [Find the candidate](/recruiter/guides/recommended-roles#find-the-candidate) for every filter.

## Read the full profile

[`GET /recruiter/candidates/{candidateId}`](/recruiter/api-reference/get-recruiter-candidate) returns the candidate in full.

```bash theme={null}
curl "https://external-api.paraform.com/api/external/v1/recruiter/candidates/$CANDIDATE_ID" \
  -H "Authorization: Bearer $PARAFORM_API_KEY"
```

| Field | What it tells you |
| - | - |
| `name`, `oneLiner`, `location`, `linkedinUrl`, `personalUrl`, `githubUrl` | Who the candidate is and where to find them |
| `relationshipStatus`, `tags`, `note` | Your working relationship, your tags, and your own CRM note |
| `preferences` | What the candidate wants: locations, salary range and OTE, workplace, role types, funding rounds, visa, excluded industries, and company sizes. `null` when nothing is saved. |
| `experiences`, `education` | Work history and education. `isCurrent` is `true` for a role with no end date. |
| `resume.onFile` | Whether the candidate has a profile resume. The file itself isn't returned. |
| `applications` | Your submissions of this candidate, newest first, with each role, `status`, and interview stages. A withdrawn submission has `status` `WITHDRAWN`. |

## What you can read

* **Only your own CRM.** A candidate held only by an agency teammate returns `404`, even if your agency shares candidates in the app.
* **Only your own submissions.** `applications` never lists a teammate's submission of the same candidate.
* **Hidden and archived candidates** return `404`, the same as in `GET /recruiter/candidates`.

## Errors

See [Errors](/errors) for the envelope.

| Status | `type` | What to do |
| - | - | - |
| `403` | `permission_error` | The key is missing `candidates:read` or `submissions:read`. Create a key with both. |
| `404` | `not_found` | The candidate isn't in your CRM, or is hidden or archived. Get a `candidateId` from `GET /recruiter/candidates`. |


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