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

# Consent and sign in

> Send the pilot to the consent screen, exchange the code for a grant and sign him in.

A pilot connects your application on MyPilotIndex. You never see his password, and he can end the connection at any time.

## Send the pilot to the consent screen

Redirect his browser to:

```text theme={null}
https://mypilotindex.com/connect/{slug}
  ?client_id=...
  &redirect_uri=...
  &scope=...
  &state=...
  &code_challenge=...
  &code_challenge_method=S256
```

| Parameter | Rule |
| - | - |
| `client_id` | Your Cognito app client id. It identifies you; the slug in the path is only your name in the link. |
| `redirect_uri` | Must match, exactly, a redirect URI that MyPilotIndex registered for you. Anything else is refused and the pilot is not sent anywhere. |
| `scope` | One or more scope names separated by spaces, without the `partner/` prefix, for example `profile hours.write`. Each must be one your partner is allowed to ask for. |
| `state` | Your own value, returned unchanged. At most 512 bytes, with no control characters. Use it against forgery. |
| `code_challenge` | The PKCE challenge: the unpadded base64url SHA-256 of your `code_verifier`. |
| `code_challenge_method` | Must be `S256`. |

The pilot signs in to MyPilotIndex if he is not signed in, reads which of his data you ask for, and allows or denies.

## The return

* **Allowed:** his browser goes to your `redirect_uri` with `code` and `state` added.
* **Denied:** his browser goes to your `redirect_uri` with `error=access_denied` and `state`.
* **A request MyPilotIndex refuses** (an unknown partner, a redirect URI that is not registered, a scope that is not allowed) shows an error on MyPilotIndex and does not redirect.

## The code

The code is valid for 10 minutes and works once. A code that is expired, used, issued to another partner, or paired with a wrong verifier or redirect URI is refused the same way: restart the consent.

## The exchange

Call `POST /v1/partner/grants/exchange` with your bearer token and a JSON body of exactly `code`, `code_verifier` (43 to 128 characters) and `redirect_uri`. The answer holds:

* `grant_id`, which every later call names;
* `pilot.id`, the pilot's pairwise id;
* `scopes`, what the pilot granted, sorted;
* with the `profile` scope also his `name`, `username` and `avatar_url`, each null when he has none.

A code that does not open a grant for you (unknown, expired or used, another partner's, a wrong verifier or redirect URI, or a grant the pilot revoked since) is refused as `400 invalid_request` with reason `invalid_grant`, whatever was wrong. A malformed body (an unknown or repeated member, or a value that is not a string) is also `400 invalid_request`, with no reason.

## Sign in with MyPilotIndex

The pairwise id is stable across reconnects of the same pilot to your application, different at every partner, and never the MyPilotIndex account id. You can use it to sign the pilot in to your own product ("Sign in with MyPilotIndex") and to name him on later calls.

## Revocation

The pilot can disconnect you in Settings, Privacy, Connected apps. MyPilotIndex can also revoke a grant. From then on every call naming the grant answers `404 not_found`, and, when a webhook URL is on record for you, you receive a `grant.revoked` webhook. If the pilot deletes his account the grant is removed with it. Delete what you hold for that pilot.

## What is never shared

The Partner API never carries a pilot's e-mail, phone, address, date of birth, certificate numbers, documents, background answers, salary, messages or recruiter signals, and his pairwise id, not his account id, is what names him to you. A block of data the grant does not hold is absent from the answer.


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