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

# List participants

> Returns a program's participants, a page at a time, oldest first. The key's owner must be an admin of the company who manages the program.


* **Paging.** Send the last `id` of a page as `startingAfter` to get the next page. There's no "has more" flag: you've reached the end when a page has fewer than `limit` participants.
* **Backwards.** `endingBefore` returns the participants added before that id, newest first.
* **Order.** Participants come back in the order they were added, so paging never skips or repeats anyone.
* **No invite links.** Lists don't include `inviteUrl` or `publicInviteUrl`. You get those when you [add someone](https://docs.hoppier.com/api-reference/participants/add.md).


## OpenAPI

````yaml /openapi.yaml get /participants
openapi: 3.1.0
info:
  title: Hoppier API
  version: 1.0.0-beta
  summary: Create and read your Hoppier programs, and add and list the people in them.
  description: >
    The Hoppier API is in **closed beta**. Everything in this reference runs in
    production today.


    - A full-access admin creates company API keys in the dashboard, under
    **Developers › API keys**. For a personal key, email
    [support@hoppier.com](mailto:support@hoppier.com).

    - There is no sandbox. Every key works against your live account.

    - We add fields and error codes without notice, so ignore anything you don't
    recognise. We don't rename or remove a documented field without announcing
    it on the [changelog](https://docs.hoppier.com/changelog) first.
  termsOfService: https://www.hoppier.com/terms
  contact:
    name: Hoppier support
    email: support@hoppier.com
servers:
  - url: https://app.hoppier.com/api/v1
    description: Production
security:
  - apiKey: []
tags:
  - name: Account
    description: Check an API key and see which account it belongs to.
  - name: Addresses
    description: Save and list your company's addresses, for new programs.
  - name: Merchants
    description: Look up the merchants and gift-card brands a program can allow.
  - name: Programs
    description: Read and create the reward programs in your account.
  - name: Participants
    description: Add people to a program and list them.
paths:
  /participants:
    get:
      tags:
        - Participants
      summary: List participants
      description: >
        Returns a program's participants, a page at a time, oldest first. The
        key's owner must be an admin of the company who manages the program.
      operationId: listParticipants
      parameters:
        - name: program
          in: query
          required: true
          description: The program's id. Starts with `prg_`.
          schema:
            type: string
          example: prg_Z8q3NnW2xK
        - name: filter
          in: query
          required: false
          description: >
            `all`: `pending`, `active` and `inactive` participants. `onboarded`:
            people who have claimed their reward. `pending`: people who haven't
            claimed it yet.
          schema:
            type: string
            enum:
              - all
              - onboarded
              - pending
            default: all
        - name: limit
          in: query
          required: false
          description: How many participants to return, from 1 to 100.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 10
        - name: startingAfter
          in: query
          required: false
          description: >-
            A participant id (`pcpt_…`). Returns the participants added after
            it, oldest first. Not with `endingBefore`.
          schema:
            type: string
          example: pcpt_R4k1LmQ8vB
        - name: endingBefore
          in: query
          required: false
          description: >-
            A participant id (`pcpt_…`). Returns the participants added before
            it, newest first. Not with `startingAfter`.
          schema:
            type: string
      responses:
        '200':
          description: A page of participants. Fewer than `limit` means it's the last page.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Participant'
              example:
                - id: pcpt_R4k1LmQ8vB
                  object: participant
                  email: ada@example.com
                  firstName: Ada
                  lastName: Lovelace
                  program: prg_Z8q3NnW2xK
                  status: active
                - id: pcpt_9Lq2XmV7cD
                  object: participant
                  email: grace@example.com
                  firstName: Grace
                  lastName: Hopper
                  program: prg_Z8q3NnW2xK
                  status: pending
        '400':
          description: >
            `invalid_request`: `program` is missing or given twice, `filter` or
            `limit` isn't allowed, a cursor isn't a participant id, or both
            cursors were sent. On a cursor error, `parameter` names it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                limitTooHigh:
                  summary: limit over 100
                  value:
                    error: invalid_request
                    message: '"limit" must be less than or equal to 100'
                badCursor:
                  summary: A cursor that isn't a participant id
                  value:
                    error: invalid_request
                    message: startingAfter must be a participant id.
                    parameter: startingAfter
                bothCursors:
                  summary: Both cursors
                  value:
                    error: invalid_request
                    message: Give startingAfter or endingBefore, not both.
                missingProgram:
                  summary: No program
                  value:
                    error: invalid_request
                    message: program is required.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/NotAdminOrProgramManager'
        '404':
          $ref: '#/components/responses/ProgramNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    Participant:
      type: object
      description: A person in a program.
      required:
        - id
        - object
        - email
        - program
        - status
      properties:
        id:
          type: string
          description: The participant's id. Starts with `pcpt_`.
          examples:
            - pcpt_R4k1LmQ8vB
        object:
          type: string
          const: participant
        email:
          type: string
          format: email
          examples:
            - ada@example.com
        firstName:
          type: string
          description: First word of the person's name. Left out when no name was given.
          examples:
            - Ada
        lastName:
          type: string
          description: Second word of the person's name. Left out when there isn't one.
          examples:
            - Lovelace
        program:
          type: string
          description: Id of the program. Starts with `prg_`.
          examples:
            - prg_Z8q3NnW2xK
        status:
          type: string
          enum:
            - pending
            - active
            - inactive
          description: >
            `pending`: invited, hasn't claimed yet. `active`: claimed.
            `inactive`: no longer active in the program.
        inviteUrl:
          type: string
          format: uri
          description: >
            The link the person opens to claim their reward: Hoppier's sign-up
            page, or the sign-in page if they already have an account. Valid for
            30 days. Anyone who has it can use it, so send it only to that
            person. Only in the response to adding someone, not in lists.
        publicInviteUrl:
          type: string
          format: uri
          description: >
            Only for accounts with public program links turned on: the program's
            public join link. It's the same for everyone in the program, and
            anyone who has it can join. Valid for 90 days. Only in the response
            to adding someone, not in lists.
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: >
            A machine-readable code, such as `unauthorized` or
            `program_not_found`. Act on it and the HTTP status. New codes can
            appear, so handle one you don't recognise by its status. [Every
            code](/guides/errors-and-rate-limits#error-codes).
          examples:
            - program_not_found
        message:
          type: string
          description: What went wrong, in plain words. Don't parse it; it can change.
          examples:
            - Program not found.
        parameter:
          type: string
          description: On some `invalid_request` errors, the field that was refused.
          examples:
            - email
  responses:
    Unauthorized:
      description: >
        `unauthorized`: the API key is missing or malformed, or it's wrong,
        unknown or switched off.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missingKey:
              summary: No API key
              value:
                error: unauthorized
                message: 'API key is missing. Send it as "Authorization: Bearer <key>".'
            invalidKey:
              summary: Malformed, wrong or unknown key
              value:
                error: unauthorized
                message: API key is not valid.
            inactiveKey:
              summary: Key switched off
              value:
                error: unauthorized
                message: API key is inactive.
    NotAdminOrProgramManager:
      description: >
        `insufficient_permission`: the key's owner isn't an admin of the
        company, or doesn't manage this program.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            notAdmin:
              summary: The key's owner isn't an admin
              value:
                error: insufficient_permission
                message: This API key's user is not an admin of this account.
            notManager:
              summary: The key's owner doesn't manage this program
              value:
                error: insufficient_permission
                message: This API key's user does not manage this program.
    ProgramNotFound:
      description: >
        `program_not_found`: no program with this id in the key's company. A
        malformed id, an id that doesn't exist and a program in another company
        all get the same answer.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: program_not_found
            message: Program not found.
    RateLimited:
      description: >
        `rate_limited`: too many requests. Wait the number of seconds in
        `Retry-After`, then retry. See [Errors and rate
        limits](/guides/errors-and-rate-limits#rate-limits).
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            perAccount:
              summary: Per-account limit
              value:
                error: rate_limited
                message: >-
                  Too many requests for this account. Retry after the number of
                  seconds in Retry-After.
            perAddress:
              summary: Per-address limit
              value:
                error: rate_limited
                message: Too Many Requests
    ServerError:
      description: >
        `internal_error`: something went wrong on Hoppier's side. The message
        never contains internal details. Retry with backoff; if it keeps
        happening, email support@hoppier.com.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: internal_error
            message: An unexpected error occurred.
  headers:
    RetryAfter:
      description: Whole seconds to wait before retrying.
      schema:
        type: string
      example: '30'
    RateLimitRemaining:
      description: >-
        Per-address limit only. Requests left in the current 10-second window,
        so `0` on a 429.
      schema:
        type: string
      example: '0'
    RateLimitReset:
      description: >-
        Per-address limit only. When the window refills, as a Unix timestamp in
        seconds.
      schema:
        type: string
      example: '1793491210'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: hk_live.<prefix>.<secret>
      description: >
        Send your key in the `Authorization` header: `Authorization: Bearer
        hk_live.…`. The word `Bearer` is case-sensitive.


        Keys are shown once. Treat them like passwords and never put one in code
        that runs in a browser or an app.

````

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