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

# List leads

> Scoped to company_id; the handler does not restrict this read to the session school assignments. Returns paginated lead rows, or paginated LeadStages objects when view=stages.

Normal lookup precedence is ids, then query, then the filtered school collection. ids is limited to 200 UUIDs and missing IDs are omitted. query performs a name search with optional max_results. status, date_from/date_to and age_min/age_max are validated before these branches but only filter the normal school collection; ids and query bypass those filters. Negative ages are accepted for expected children. The age interval defaults to -12 through 180 months. date_to cannot precede date_from, and age_max cannot be smaller than age_min.

view=stages requires the school in the session assignments and accepts only company_id, school_id, view, page and per_page. Any other parameter in this view returns 400.



## OpenAPI

````yaml /openapi.yaml get /leads
openapi: 3.1.0
info:
  title: Primula Tracker API V3
  version: 3.0.0
  description: >-
    Reference for the 66 operations registered under `/primula/api/v3` in the V3
    release baseline.


    ## Authentication

    Create a session with `POST /sessions`, then send `Authorization: Bearer
    <access_token>` on protected operations. Tokens must remain associated with
    a valid server-side session. The returned refresh token has no refresh
    endpoint in V3. Session company and school restrictions are documented per
    operation; company_id is not inferred from the token.


    ## Responses and errors

    Collections generally return bare JSON arrays and items return bare JSON
    objects. Report objects, nested maps, and update summaries are explicitly
    described below. List metadata travels in response headers rather than an
    envelope. Empty lists written by collection helpers are `[]`; fields backed
    by nullable values may be `null`, and omitted properties are distinguished
    from null properties in schemas. Handlers generally return `{ "error":
    "message" }`; authentication middleware and activity proxy errors use plain
    text. Unsupported methods on a registered path return 405 with Allow after
    any applicable authentication checks.


    ## Pagination and projections

    Only operations documenting page/per_page support pagination. Defaults are
    page=1 and per_page=100. Values exceeding the documented effective cap are
    clamped, not rejected. X-Total-Count describes the full matching set. Link
    contains applicable navigation links and is omitted for a single page.
    Aggregates use limit (default 50, effective cap 200) instead of pagination
    and send X-Truncated only when rows were omitted. The fields parameter,
    where available, selects the exact response properties; unsupported fields
    return 400.


    ## Query encoding

    Multi-value parameters documented as arrays accept repeated keys or
    comma-separated values. Prefer repeated keys for long UUID lists. Except for
    the two activity proxy operations, query parsing drops the entire query
    string above 8192 bytes and truncates each decoded query value to 128 bytes.
    Parameter combinations and interpretation differ by resource and
    representation; consult each operation. Unknown parameters are rejected only
    where explicitly documented.


    ## Dates and writes

    Calendar dates use YYYY-MM-DD, monthly periods use YYYY-MM, and timestamp
    formats are described in the corresponding schema. Defaults such as today
    depend on the server clock. PATCH operations change only the documented
    properties and reject unknown body properties. Clearing values,
    authorization, and partial-write behavior vary by resource and are described
    per operation.


    Examples use synthetic identifiers and placeholder tokens. Replace the
    server host before using an interactive API client.
servers:
  - url: https://{host}/primula/api/v3
    description: V3 API deployment. Replace the placeholder hostname.
    variables:
      host:
        default: api.example.com
security:
  - bearerAuth: []
tags:
  - name: sessions
    description: Sessions.
  - name: schools
    description: Schools.
  - name: companies
    description: Companies.
  - name: rooms
    description: Rooms.
  - name: users
    description: Users.
  - name: gusto_companies
    description: Gusto companies.
  - name: gusto_employees
    description: Gusto employees.
  - name: gusto_contractors
    description: Gusto contractors.
  - name: gusto_payrolls
    description: Gusto payrolls.
  - name: procare_staff
    description: Procare staff.
  - name: efficiency_ratios
    description: Efficiency ratios.
  - name: enrollment_tracker
    description: Enrollment tracker.
  - name: classroom_attendance
    description: Classroom attendance.
  - name: absences
    description: Absences.
  - name: billing_attendance_audits
    description: Billing attendance audits.
  - name: data_refresh
    description: Data refresh.
  - name: waitlist
    description: Waitlist.
  - name: sibling_discounts
    description: Sibling discounts.
  - name: new_start_tracker
    description: New start tracker.
  - name: withdrawal_tracker
    description: Withdrawal tracker.
  - name: transition_tracker
    description: Transition tracker.
  - name: enrollments
    description: Enrollments.
  - name: pre_registration_fallout
    description: Pre registration fallout.
  - name: procare_messages
    description: Procare messages.
  - name: activities_summary
    description: Activities summary.
  - name: activity_details
    description: Activity details.
  - name: leads
    description: Leads.
  - name: students
    description: Students.
  - name: payments
    description: Payments.
  - name: family_balances
    description: Family balances.
  - name: attendances
    description: Attendances.
  - name: billing_plans
    description: Billing plans.
  - name: spaces
    description: Spaces.
paths:
  /leads:
    get:
      tags:
        - leads
      summary: List leads
      description: >-
        Scoped to company_id; the handler does not restrict this read to the
        session school assignments. Returns paginated lead rows, or paginated
        LeadStages objects when view=stages.


        Normal lookup precedence is ids, then query, then the filtered school
        collection. ids is limited to 200 UUIDs and missing IDs are omitted.
        query performs a name search with optional max_results. status,
        date_from/date_to and age_min/age_max are validated before these
        branches but only filter the normal school collection; ids and query
        bypass those filters. Negative ages are accepted for expected children.
        The age interval defaults to -12 through 180 months. date_to cannot
        precede date_from, and age_max cannot be smaller than age_min.


        view=stages requires the school in the session assignments and accepts
        only company_id, school_id, view, page and per_page. Any other parameter
        in this view returns 400.
      operationId: GetLeadsV3
      parameters:
        - $ref: '#/components/parameters/CompanyId'
        - name: school_id
          in: query
          required: true
          description: School UUID.
          schema:
            type: string
            format: uuid
          example: 22222222-2222-4222-8222-222222222222
        - name: view
          in: query
          required: false
          description: Omit for lead rows; stages includes per-stage timestamps.
          schema:
            type: string
            enum:
              - stages
        - name: fields
          in: query
          required: false
          description: >-
            Select response properties. Unknown names return 400. Normal lead
            representation only; names are case-sensitive. Accepts repeated
            query parameters or comma-separated values; empty entries are
            dropped and surrounding whitespace is trimmed.
          schema:
            type: array
            items:
              type: string
              enum:
                - lead_id
                - monday_item_id
                - first_name
                - last_name
                - school_id
                - school_name
                - status
                - date_of_birth
                - current_age
                - intended_start_date
                - periods_lead_room_available
                - parent1_name
                - parent1_email
                - parent1_mobile
                - created_at
                - updated_at
                - available_space
                - source
                - intellikid_status
                - intellikid_children_status
                - intellikid_lead_status
                - intellikid_source
                - notes
                - student_status
                - onboarding_status
                - ems_status
                - start_date
                - withdrawal_date
                - lineleader_child_id
                - lineleader_family_id
                - lineleader_center_id
                - lineleader_center_name
                - lineleader_status
                - lineleader_classroom
                - stage_inquiry_call_completed
                - stage_tour_completed
                - stage_not_viable
                - stage_not_interested
                - stage_no_response
                - stage_no_response_timed_out
                - is_crm_intended_start_date
                - lead_to_enrollment_date
                - age_at_start_date_months
                - age_at_lead_created_at_months
                - alerts
          style: form
          explode: true
        - name: ids
          in: query
          required: false
          description: >-
            Read at most 200 lead UUIDs; takes precedence over query. Accepts
            repeated query parameters or comma-separated values; empty entries
            are dropped and surrounding whitespace is trimmed.
          schema:
            type: array
            items:
              type: string
              format: uuid
            maxItems: 200
          style: form
          explode: true
        - name: query
          in: query
          required: false
          description: Name search; used only when ids is omitted.
          schema:
            type: string
        - name: max_results
          in: query
          required: false
          description: Maximum name-search results; 0 keeps the backend default.
          schema:
            type: integer
            minimum: 0
            default: 0
        - name: status
          in: query
          required: false
          description: >-
            Procare lead status; exact case required. Applies only to normal
            school collection.
          schema:
            type: string
            enum:
              - New
              - Contacted
              - Tour Scheduled
              - Tour Completed
              - Tour No Show
              - Discovery Day Scheduled
              - Discovery Day Completed
              - Discovery Day No Show
              - Waitlisted
              - Enrolled
              - Lost
              - No Status
        - name: date_from
          in: query
          required: false
          description: >-
            Inclusive start date in YYYY-MM-DD. Optional created-date window for
            the normal school collection.
          schema:
            type: string
            format: date
          example: '2026-01-01'
        - name: date_to
          in: query
          required: false
          description: >-
            Inclusive end date in YYYY-MM-DD. Optional created-date window for
            the normal school collection.
          schema:
            type: string
            format: date
          example: '2026-01-31'
        - name: age_min
          in: query
          required: false
          description: Minimum child age in months; normal school collection only.
          schema:
            type: number
            default: -12
        - name: age_max
          in: query
          required: false
          description: Maximum child age in months; normal school collection only.
          schema:
            type: number
            default: 180
        - name: page
          in: query
          required: false
          description: 'One-based page number. '
          schema:
            type: integer
            minimum: 1
            default: 1
          example: 1
        - name: per_page
          in: query
          required: false
          description: 'Items per page; values greater than 500 are clamped to 500. '
          schema:
            type: integer
            minimum: 1
            default: 100
          example: 100
      responses:
        '200':
          description: Successful response.
          content:
            application/json:
              schema:
                anyOf:
                  - type: array
                    items:
                      $ref: '#/components/schemas/Lead'
                  - type: array
                    items:
                      $ref: '#/components/schemas/LeadProjection'
                  - type: array
                    items:
                      $ref: '#/components/schemas/LeadStages'
              examples:
                projection:
                  summary: fields=lead_id,first_name,last_name
                  value:
                    - lead_id: 44444444-4444-4444-8444-444444444444
                      first_name: Example
                      last_name: Lead
                stages:
                  summary: view=stages
                  value:
                    - lead_id: 44444444-4444-4444-8444-444444444444
                      stages:
                        - stage: stage_tour_completed
                          value: 'Yes'
                          updated_at: '2026-01-15T09:30:00Z'
          headers:
            X-Total-Count:
              $ref: '#/components/headers/TotalCount'
            Link:
              $ref: '#/components/headers/Link'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '405':
          $ref: '#/components/responses/405'
        '500':
          $ref: '#/components/responses/500'
components:
  parameters:
    CompanyId:
      name: company_id
      in: query
      required: true
      description: >-
        Company UUID. Must equal the authenticated session company when that
        session has a company assigned; the equality check is skipped for
        sessions without one.
      schema:
        type: string
        format: uuid
      example: 11111111-1111-4111-8111-111111111111
  schemas:
    Lead:
      type: object
      properties:
        lead_id:
          type: string
          description: Lead id.
        monday_item_id:
          type: string
          description: Monday item id.
        first_name:
          type: string
        last_name:
          type: string
        school_id:
          type: string
          description: School id.
        school_name:
          type: string
        status:
          type: string
        date_of_birth:
          type: string
        current_age:
          type:
            - number
            - 'null'
          format: double
          description: Child age in months.
        intended_start_date:
          type: string
        periods_lead_room_available:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/AvailableSpace'
        parent1_name:
          type: string
        parent1_email:
          type: string
        parent1_mobile:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        available_space:
          type: string
        available_space_match:
          type: string
        available_space_match_persisted:
          type:
            - string
            - 'null'
          format: date-time
        source:
          type: string
        intellikid_status:
          type: string
        intellikid_children_status:
          type: string
        intellikid_lead_status:
          type: string
        intellikid_source:
          type: string
        notes:
          type: string
        student_status:
          type: string
        procare_desktop_enrollment_status:
          type: string
        onboarding_status:
          type: string
        ems_status:
          type: string
        start_date:
          type: string
        withdrawal_date:
          type: string
        lineleader_child_id:
          type:
            - integer
            - 'null'
        lineleader_family_id:
          type:
            - integer
            - 'null'
        lineleader_center_id:
          type:
            - integer
            - 'null'
        lineleader_center_name:
          type:
            - string
            - 'null'
        lineleader_status:
          type:
            - string
            - 'null'
        lineleader_classroom:
          type:
            - string
            - 'null'
        lineleader_child_flagged_as_duplicated:
          type: boolean
        stage_inquiry_call_completed:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_tour_completed:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_not_viable:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_not_interested:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_no_response:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_no_response_timed_out:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        is_crm_intended_start_date:
          type: boolean
        lead_to_enrollment_date:
          type:
            - number
            - 'null'
          format: double
        age_at_start_date_months:
          type:
            - number
            - 'null'
          format: double
        age_at_lead_created_at_months:
          type:
            - number
            - 'null'
          format: double
        alerts:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Alert'
      required:
        - lead_id
        - monday_item_id
        - first_name
        - last_name
        - school_id
        - school_name
        - status
        - date_of_birth
        - current_age
        - intended_start_date
        - periods_lead_room_available
        - parent1_name
        - parent1_email
        - parent1_mobile
        - created_at
        - updated_at
        - available_space
        - available_space_match
        - available_space_match_persisted
        - source
        - intellikid_status
        - intellikid_children_status
        - intellikid_lead_status
        - intellikid_source
        - notes
        - student_status
        - procare_desktop_enrollment_status
        - onboarding_status
        - ems_status
        - start_date
        - withdrawal_date
        - lineleader_child_id
        - lineleader_family_id
        - lineleader_center_id
        - lineleader_center_name
        - lineleader_status
        - lineleader_classroom
        - lineleader_child_flagged_as_duplicated
        - stage_inquiry_call_completed
        - stage_tour_completed
        - stage_not_viable
        - stage_not_interested
        - stage_no_response
        - stage_no_response_timed_out
        - is_crm_intended_start_date
        - lead_to_enrollment_date
        - age_at_start_date_months
        - age_at_lead_created_at_months
        - alerts
      description: Lead.
    LeadProjection:
      type: object
      properties:
        lead_id:
          type: string
          description: Lead id.
        monday_item_id:
          type: string
          description: Monday item id.
        first_name:
          type: string
        last_name:
          type: string
        school_id:
          type: string
          description: School id.
        school_name:
          type: string
        status:
          type: string
        date_of_birth:
          type: string
        current_age:
          type:
            - number
            - 'null'
          format: double
        intended_start_date:
          type: string
        periods_lead_room_available:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/AvailableSpace'
        parent1_name:
          type: string
        parent1_email:
          type: string
        parent1_mobile:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        available_space:
          type: string
        source:
          type: string
        intellikid_status:
          type: string
        intellikid_children_status:
          type: string
        intellikid_lead_status:
          type: string
        intellikid_source:
          type: string
        notes:
          type: string
        student_status:
          type: string
        onboarding_status:
          type: string
        ems_status:
          type: string
        start_date:
          type: string
        withdrawal_date:
          type: string
        lineleader_child_id:
          type:
            - integer
            - 'null'
        lineleader_family_id:
          type:
            - integer
            - 'null'
        lineleader_center_id:
          type:
            - integer
            - 'null'
        lineleader_center_name:
          type:
            - string
            - 'null'
        lineleader_status:
          type:
            - string
            - 'null'
        lineleader_classroom:
          type:
            - string
            - 'null'
        stage_inquiry_call_completed:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_tour_completed:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_not_viable:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_not_interested:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_no_response:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        stage_no_response_timed_out:
          type: string
          description: >-
            Stage value as a string in the read representation; PATCH uses a
            boolean.
        is_crm_intended_start_date:
          type: boolean
        lead_to_enrollment_date:
          type:
            - number
            - 'null'
          format: double
        age_at_start_date_months:
          type:
            - number
            - 'null'
          format: double
        age_at_lead_created_at_months:
          type:
            - number
            - 'null'
          format: double
        alerts:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Alert'
      additionalProperties: false
      description: Lead Projection.
    LeadStages:
      type: object
      properties:
        lead_id:
          type: string
          description: Lead id.
        stages:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LeadStage'
      required:
        - lead_id
        - stages
      description: Lead Stages.
    AvailableSpace:
      type: object
      properties:
        room_name:
          type: string
        period:
          type: string
        spaces:
          type: integer
      required:
        - room_name
        - period
        - spaces
      description: Available Space.
    Alert:
      type: object
      properties:
        id:
          type: string
        level:
          type: integer
        description:
          type: string
      required:
        - id
        - level
        - description
      description: Alert.
    LeadStage:
      type: object
      properties:
        stage:
          type: string
          description: >-
            Stage name. The GET response can include source-specific stage
            names; PATCH accepts only its six documented stage properties.
        value:
          type:
            - string
            - 'null'
          description: >-
            Source stage state as a string or null, rather than the boolean used
            by PATCH.
        updated_at:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - stage
        - value
        - updated_at
      description: Lead Stage.
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message.
      required:
        - error
      description: Error.
  headers:
    TotalCount:
      description: >-
        Total matching rows before pagination, or matching groups before the
        aggregate limit. For unpaginated arrays, the number of returned rows.
      schema:
        type: integer
        minimum: 0
      example: 125
    Link:
      description: >-
        Pagination links using rel="next", "last", "prev", and "first". Only
        applicable links are sent; absent when all results fit on one page.
        Links preserve the original query parameters.
      schema:
        type: string
      example: >-
        </primula/api/v3/students?company_id=11111111-1111-4111-8111-111111111111&page=2>;
        rel="next"
  responses:
    '400':
      description: Invalid or missing parameters or request body.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Invalid or missing parameters or request body.
    '401':
      description: >-
        Missing or invalid Bearer token, or an absent, invalid or expired
        server-side session. The authentication middleware returns plain text
        with a trailing newline.
      content:
        text/plain:
          schema:
            type: string
          examples:
            missing:
              value: |
                missing authorization header
            invalid:
              value: |
                Unauthorized
            expired:
              value: |
                Session expired
    '403':
      description: The authenticated session is not allowed to perform this operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: >-
              The authenticated session is not allowed to perform this
              operation.
    '405':
      description: The path exists but does not support this HTTP method.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: The path exists but does not support this HTTP method.
      headers:
        Allow:
          description: Comma-separated HTTP methods accepted by this path.
          schema:
            type: string
    '500':
      description: The operation could not be completed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: The operation could not be completed.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Access token issued by POST /sessions and associated with a valid
        server-side session.

````

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