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

# Read the pilot summary

> The blocks of the pilot data that his grant allows, and only those: profile (name, username, avatar_url), score (the exact stored MPI Score with one decimal, its phase and when it was computed; exact even if the pilot hides his score publicly, because he agreed to it on the consent screen), hours (hours.read: flight, helicopter and simulator figures in separate blocks so simulator time is never added to flight time; columns at zero are omitted; one decimal) and licenses (licenses with their class ratings, and type ratings). A block the grant lacks is absent. The grant must hold at least one of profile, score, hours.read and licenses, and the partner token must still carry it, otherwise 403 forbidden with reason scope_missing. The answer names the pilot by his pairwise id and never carries e-mail, phone, address, date of birth, certificate numbers, documents, background answers, salary, messages or recruiter signals. A grant that is revoked, unknown or another partner grant answers 404 not_found.



## OpenAPI

````yaml /api-reference/partner.yaml get /v1/partner/grants/{grant_id}/summary
openapi: 3.1.0
info:
  title: MyPilotIndex Partner API
  version: 1.0.0
  description: >-
    The API of approved partner applications, such as logbooks, that act for a
    pilot who has granted them access on the MyPilotIndex consent screen. It is
    a separate document from the member API (openapi.yaml): partner routes live
    under /v1/partner/ and are never served to browsers. Authenticate with an
    access token from the identity provider's token endpoint
    (grant_type=client_credentials, scopes partner/<scope>) in the Authorization
    header. Every authenticated answer carries X-RateLimit-Limit and
    X-RateLimit-Remaining, the partner's daily allowance and what is left of it
    (a 401, and a path or method outside this document, carry neither); past the
    allowance the API answers 429 rate_limited with Retry-After. Errors use the
    shared envelope below. The API is additive within v1: new fields and routes
    may appear, existing ones do not change meaning.
servers:
  - url: https://{devApiHost}
    description: >-
      Sandbox on the AWS dev environment, with synthetic pilots. The host is
      issued to the partner with its sandbox credential.
    variables:
      devApiHost:
        default: dev-api.mypilotindex.com
        description: The dev API host given to the partner with the sandbox credential.
security: []
tags:
  - name: Grants
    description: >-
      A pilot connects on MyPilotIndex: the partner sends his browser to the
      consent page
      (https://mypilotindex.com/connect/{slug}?client_id&redirect_uri&scope&state&code_challenge&code_challenge_method=S256),
      the pilot signs in and allows, and the browser returns to the registered
      redirect_uri with code and state (or error=access_denied and state when he
      denies). The partner exchanges the code here for a grant and the pilot's
      pairwise id, which signs the pilot in ("Sign in with MyPilotIndex") and
      names him on every later call. A grant that is revoked, unknown or another
      partner's answers 404 on every route, identically.
  - name: Certificates
    description: >-
      Check a certificate a pilot shows you, such as his MPI Report, by its
      public id. The answer is the public verification's, and the call needs no
      grant.
  - name: Webhooks
    description: >-
      MyPilotIndex tells a partner about its grants by webhook: grant.revoked
      when a grant ends, and ping when the partner asks for a test. The webhook
      URL (https only) and its signing secret are set by MyPilotIndex when the
      partner is approved; the secret is shown once. Each event is a POST of the
      event as JSON (Content-Type application/json) signed in the Standard
      Webhooks scheme: webhook-id (the event id), webhook-timestamp and
      webhook-signature, "v1," and the base64 HMAC-SHA256 of
      "<webhook-id>.<webhook-timestamp>.<body>" under the key the secret carries
      in base64 after its whsec_ prefix, over the exact bytes received. Verify
      the signature, refuse a timestamp more than five minutes from your clock,
      dedupe on webhook-id, and answer any 2xx within 10 seconds. A 5xx, a 408,
      a 429, a redirect (never followed), a timeout or a connection failure is
      retried with growing gaps for about a day (twelve attempts), with the same
      webhook-id and a fresh timestamp and signature. A 4xx other than 408 and
      429 is taken as a refusal and not retried, except for a grant.revoked
      event with reason account_deleted: its grant leaves every list with the
      account, so it cannot be reconciled later, and it is retried within the
      same window on any answer but a 2xx, a 4xx included. A partner that missed
      other events reconciles with GET
      /v1/partner/grants?status=revoked&changed_since=.
paths:
  /v1/partner/grants/{grant_id}/summary:
    get:
      tags:
        - Grants
      summary: Read the pilot summary
      description: >-
        The blocks of the pilot data that his grant allows, and only those:
        profile (name, username, avatar_url), score (the exact stored MPI Score
        with one decimal, its phase and when it was computed; exact even if the
        pilot hides his score publicly, because he agreed to it on the consent
        screen), hours (hours.read: flight, helicopter and simulator figures in
        separate blocks so simulator time is never added to flight time; columns
        at zero are omitted; one decimal) and licenses (licenses with their
        class ratings, and type ratings). A block the grant lacks is absent. The
        grant must hold at least one of profile, score, hours.read and licenses,
        and the partner token must still carry it, otherwise 403 forbidden with
        reason scope_missing. The answer names the pilot by his pairwise id and
        never carries e-mail, phone, address, date of birth, certificate
        numbers, documents, background answers, salary, messages or recruiter
        signals. A grant that is revoked, unknown or another partner grant
        answers 404 not_found.
      operationId: partners.pilot_summary.v1
      parameters:
        - name: grant_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: The granted blocks.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PilotSummary'
              example:
                pilot_id: 2d9b7c1e-8f4a-4e3b-a6d5-91c0f2e7b844
                profile:
                  name: Ana Souza
                  username: anasouza
                  avatar_url: https://cdn.mypilotindex.com/avatars/2d9b.jpg
                score:
                  value: 512.4
                  phase: positioning
                  computed_at: '2026-11-03T21:14:09Z'
                hours:
                  flight:
                    total_hours: 1530.2
                    pic_hours: 640
                    night_hours: 210.5
                  helicopter:
                    helicopter_total_hours: 85
                  simulator:
                    simulator_hours: 120
                    simulator_ffs_hours: 80
                licenses:
                  licenses:
                    - authority: FAA
                      type: CPL
                      category: airplane
                      status: completed
                      classes:
                        - class: AMEL
                          status: completed
                  type_ratings:
                    - designator: B738
                      name: Boeing 737 NG
                      current: true
                as_of: '2026-11-04T12:00:00Z'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          description: >-
            forbidden with reason scope_missing; the grant or the token holds
            none of the scopes this route serves.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScopeMissingError'
        '404':
          $ref: '#/components/responses/Error'
        '405':
          $ref: '#/components/responses/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
        '504':
          $ref: '#/components/responses/Error'
      security:
        - partnerOAuth: []
components:
  headers:
    RateLimitLimit:
      description: >-
        The partner's daily allowance of calls (1,000 unless agreed otherwise),
        per UTC day.
      schema:
        type: integer
    RateLimitRemaining:
      description: What is left of the allowance after this call.
      schema:
        type: integer
    RetryAfter:
      description: >-
        The HTTP date, in UTC, when the allowance renews (the next UTC
        midnight).
      schema:
        type: string
        example: Thu, 05 Nov 2026 00:00:00 GMT
  schemas:
    PilotSummary:
      type: object
      additionalProperties: false
      required:
        - pilot_id
        - as_of
      description: Only the blocks the grant holds the scope for appear.
      properties:
        pilot_id:
          type: string
          format: uuid
          description: The pilot pairwise id at this partner.
        profile:
          type: object
          additionalProperties: false
          properties:
            name:
              type:
                - string
                - 'null'
            username:
              type:
                - string
                - 'null'
            avatar_url:
              type:
                - string
                - 'null'
        score:
          type: object
          additionalProperties: false
          properties:
            value:
              type:
                - number
                - 'null'
              description: The exact stored score with one decimal.
            phase:
              type:
                - string
                - 'null'
            computed_at:
              type:
                - string
                - 'null'
              format: date-time
        hours:
          type: object
          additionalProperties: false
          description: >-
            Columns at zero are omitted, and so is a block with none left. One
            decimal.
          properties:
            flight:
              type: object
              additionalProperties:
                type: number
            helicopter:
              type: object
              additionalProperties:
                type: number
            simulator:
              type: object
              additionalProperties:
                type: number
        licenses:
          type: object
          additionalProperties: false
          required:
            - licenses
            - type_ratings
          properties:
            licenses:
              type: array
              items:
                type: object
                additionalProperties: false
                required:
                  - authority
                  - type
                  - category
                  - status
                  - classes
                properties:
                  authority:
                    type: string
                  type:
                    type: string
                  category:
                    type: string
                  status:
                    type: string
                  classes:
                    type: array
                    items:
                      type: object
                      additionalProperties: false
                      required:
                        - class
                        - status
                      properties:
                        class:
                          type: string
                        status:
                          type: string
            type_ratings:
              type: array
              items:
                type: object
                additionalProperties: false
                required:
                  - designator
                  - name
                  - current
                properties:
                  designator:
                    type: string
                  name:
                    type: string
                  current:
                    type: boolean
        as_of:
          type: string
          format: date-time
          description: When the summary was read.
    ScopeMissingError:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          properties:
            error:
              type: object
              properties:
                reason:
                  type: string
                  enum:
                    - scope_missing
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - correlation_id
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - request_too_large
                - unauthenticated
                - not_found
                - conflict
                - unprocessable
                - operation_disabled
                - rate_limited
                - forbidden
                - dependency_unavailable
                - internal
                - deadline_exceeded
                - method_not_allowed
            message:
              type: string
              description: Stable safe English message, never the underlying error text.
            correlation_id:
              type: string
              pattern: ^[a-f0-9]{32}$
            reason:
              type: string
              description: Optional refusal reason from the operation's closed vocabulary.
    RateLimitedError:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          properties:
            error:
              type: object
              properties:
                reason:
                  type: string
                  enum:
                    - rate_limited
  responses:
    Error:
      description: The shared error envelope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >-
        rate_limited with reason rate_limited, past the partner's daily
        allowance; nothing was done.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitedError'
  securitySchemes:
    partnerOAuth:
      type: oauth2
      description: >-
        OAuth 2.0 client credentials. Request a token from the token endpoint of
        the identity provider's domain (https://{cognito-domain}/oauth2/token,
        with HTTP Basic client authentication) and send it as a Bearer token.
        Production uses auth.mypilotindex.com. The sandbox uses the dev
        environment's Cognito domain, which is given to the partner with its
        sandbox credential. A token carries only the scopes the partner was
        approved for.
      flows:
        clientCredentials:
          tokenUrl: https://auth.mypilotindex.com/oauth2/token
          scopes:
            partner/profile: Read the pilot's name, photo and username.
            partner/score: Read the pilot's MPI Score and phase.
            partner/hours.read: Read the pilot's flight hours.
            partner/hours.write: Update the pilot's flight hours with the logbook's totals.
            partner/licenses: Read the pilot's licenses, ratings and type ratings.
            partner/applications: Read the pilot's applications to jobs from the partner's company.

````

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