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

# List leads

> Leads in the organization, newest first, a page at a time. Filter by stage, source, owner, time of last change, or any field. Archived leads are left out.

Scope: `leads.read`.



## OpenAPI

````yaml GET /api/v1/leads
openapi: 3.1.0
info:
  title: Marro API
  version: 1.0.0
  description: >-
    Server-to-server access to one organization’s data in Marro. Each key
    belongs to an organization and can use only the scopes it was given for
    modules the organization subscribes to. Keys go only in the Authorization
    header, over HTTPS, from a server: never in browser code or a URL. A key
    that was ever sent over plain HTTP or in a URL must be treated as leaked:
    revoke it and create a new one. The API sends no CORS headers.


    Every response carries `X-Request-Id`, to quote to support. Once the key is
    checked, responses also carry `RateLimit-Limit`, `RateLimit-Remaining` and
    `RateLimit-Reset` (seconds until the window resets) for whichever limit is
    closer to running out. An address that is not an endpoint answers 404
    `NOT_FOUND` in the same error shape.
servers:
  - url: https://app.marro.si
security: []
tags:
  - name: Leads
  - name: Reference
    description: 'How this organization is set up: fields, stages, sources and people.'
paths:
  /api/v1/leads:
    get:
      tags:
        - Leads
      summary: List leads
      description: >-
        Leads in the organization, newest first, a page at a time. Filter by
        stage, source, owner, time of last change, or any field. Archived leads
        are left out.


        Scope: `leads.read`.
      operationId: list-leads
      parameters:
        - name: limit
          in: query
          required: false
          description: How many leads to return, 1–100.
          schema:
            default: 25
            type: integer
            minimum: 1
            maximum: 100
        - name: cursor
          in: query
          required: false
          description: The `nextCursor` from the previous page.
          schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 2147483647
        - name: updated_since
          in: query
          required: false
          description: Only leads changed at or after this time, for syncing.
          schema:
            type: string
            format: date-time
            pattern: >-
              ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
        - name: stage_id
          in: query
          required: false
          description: Only leads in this stage (IDs from GET /api/v1/lead-stages).
          schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 2147483647
        - name: pipeline_id
          in: query
          required: false
          description: Only leads in this pipeline (IDs from GET /api/v1/pipelines).
          schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 2147483647
        - name: source_id
          in: query
          required: false
          description: Only leads from this source (IDs from GET /api/v1/lead-sources).
          schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 2147483647
        - name: owner_id
          in: query
          required: false
          description: Only leads owned by this person (IDs from GET /api/v1/users).
          schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 2147483647
        - name: filter
          in: query
          required: false
          description: >-
            A JSON array of field filters:
            `[{"field":"city","operator":"contains","value":"Hyd"}]`. All
            filters must match. The operators each field type takes are in this
            parameter’s `x-filter-operators`.
          schema:
            type: string
            maxLength: 8000
          x-filter-operators:
            maxFilters: 10
            byType:
              - types:
                  - text
                  - textarea
                  - phone
                  - email
                  - url
                operators:
                  - id: contains
                    label: contains
                    takes: '`value`'
                  - id: equals
                    label: is
                    takes: '`value`'
                  - id: is_empty
                    label: is empty
                    takes: No value
                  - id: is_not_empty
                    label: is not empty
                    takes: No value
              - types:
                  - number
                operators:
                  - id: equals
                    label: is
                    takes: '`value`'
                  - id: gt
                    label: is more than
                    takes: '`value`'
                  - id: lt
                    label: is less than
                    takes: '`value`'
                  - id: between
                    label: is between
                    takes: '`values` with two items'
                  - id: is_empty
                    label: is empty
                    takes: No value
                  - id: is_not_empty
                    label: is not empty
                    takes: No value
              - types:
                  - date
                operators:
                  - id: 'on'
                    label: is on
                    takes: '`value`'
                  - id: before
                    label: is before
                    takes: '`value`'
                  - id: after
                    label: is after
                    takes: '`value`'
                  - id: between
                    label: is between
                    takes: '`values` with two items'
                  - id: is_empty
                    label: is empty
                    takes: No value
                  - id: is_not_empty
                    label: is not empty
                    takes: No value
              - types:
                  - select
                  - lead_source
                  - user
                operators:
                  - id: is_any_of
                    label: is any of
                    takes: '`values` with one or more items'
                  - id: is_empty
                    label: is empty
                    takes: No value
                  - id: is_not_empty
                    label: is not empty
                    takes: No value
              - types:
                  - multiselect
                operators:
                  - id: has_any_of
                    label: includes any of
                    takes: '`values` with one or more items'
                  - id: is_empty
                    label: is empty
                    takes: No value
                  - id: is_not_empty
                    label: is not empty
                    takes: No value
              - types:
                  - checkbox
                operators:
                  - id: is_true
                    label: is yes
                    takes: No value
                  - id: is_false
                    label: is no
                    takes: No value
      responses:
        '200':
          description: A page of leads.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Lead'
                  nextCursor:
                    anyOf:
                      - type: integer
                        exclusiveMinimum: 0
                        maximum: 2147483647
                      - type: 'null'
                    description: Pass as `cursor` for the next page; null on the last page.
                required:
                  - items
                  - nextCursor
                additionalProperties: false
              example:
                items:
                  - id: 1842
                    name: Priya Sharma
                    phone: '+919812345678'
                    email: priya@example.com
                    leadType: student
                    stageId: 7
                    pipelineId: 2
                    sourceId: 3
                    assignedTo: 21
                    stage:
                      id: 7
                      name: Follow Up
                      meaning: open
                    pipeline:
                      id: 2
                      name: Main pipeline
                    source:
                      id: 3
                      name: Website
                    owner:
                      id: 21
                      name: Ravi Kumar
                    fields:
                      city: Hyderabad
                      interest: Premium plan
                      preferred_time: evening
                    createdAt: '2026-09-20T04:45:00Z'
                    updatedAt: '2026-09-24T03:32:11Z'
                nextCursor: 1841
        '400':
          description: >-
            INVALID_QUERY: A parameter is out of range, `filter` is not valid
            JSON, or a filter cannot apply (unknown field key, an operator the
            field does not take, a bad value, more than 10). `details.filters`
            lists the positions of those filters (0-based); nothing is listed
            rather than ignoring them.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'UNAUTHORIZED: The key is missing, wrong, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            FORBIDDEN: The key lacks the scope, or the organization’s plan does
            not include it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            RATE_LIMITED: More than 600 requests in an hour with this key, or
            3000 with all of the organization’s keys together. `Retry-After`
            says how many seconds to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: >-
            INTERNAL: Something failed on our side. Retry; if it persists,
            contact support quoting the `X-Request-Id` response header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - ApiKey:
            - leads.read
components:
  schemas:
    Lead:
      type: object
      properties:
        id:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
        name:
          type: string
        phone:
          type: string
        email:
          anyOf:
            - type: string
            - type: 'null'
        leadType:
          type: string
          enum:
            - student
            - consultant
        stageId:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
              maximum: 2147483647
            - type: 'null'
        pipelineId:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
          description: >-
            The pipeline the lead is in (see GET /api/v1/pipelines). Its stage
            is always one of this pipeline’s stages.
        sourceId:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
              maximum: 2147483647
            - type: 'null'
        assignedTo:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
              maximum: 2147483647
            - type: 'null'
          description: The owner’s user ID.
        stage:
          anyOf:
            - $ref: '#/components/schemas/StageRef'
            - type: 'null'
        pipeline:
          anyOf:
            - $ref: '#/components/schemas/NamedRef'
            - type: 'null'
        source:
          anyOf:
            - $ref: '#/components/schemas/NamedRef'
            - type: 'null'
        owner:
          anyOf:
            - $ref: '#/components/schemas/NamedRef'
            - type: 'null'
        fields:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
              - type: array
                items:
                  type: string
              - type: 'null'
          description: >-
            Every other active field, by field key (see GET
            /api/v1/lead-fields), including the organization’s own custom
            fields. Empty fields are omitted.
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
        updatedAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
      required:
        - id
        - name
        - phone
        - email
        - leadType
        - stageId
        - pipelineId
        - sourceId
        - assignedTo
        - stage
        - pipeline
        - source
        - owner
        - fields
        - createdAt
        - updatedAt
      additionalProperties: false
      id: Lead
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Stable, machine-readable: UNAUTHORIZED, FORBIDDEN, NOT_FOUND,
                VALIDATION_FAILED, DUPLICATE_LEAD, RATE_LIMITED…
            message:
              type: string
              description: A sentence for people.
            details:
              description: >-
                For VALIDATION_FAILED, `fields` maps each field key to its
                problem.
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
      id: Error
    StageRef:
      type: object
      properties:
        id:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
        name:
          type: string
        meaning:
          type: string
          enum:
            - open
            - won
            - lost
          description: What reaching the stage means in this organization.
      required:
        - id
        - name
        - meaning
      additionalProperties: false
      id: StageRef
    NamedRef:
      type: object
      properties:
        id:
          type: integer
          exclusiveMinimum: 0
          maximum: 2147483647
        name:
          type: string
      required:
        - id
        - name
      additionalProperties: false
      id: NamedRef
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      description: >-
        An organization API key, created in Settings → Connections → API keys.
        Keys start with `mk_live_`. Marro stores only a hash of a key, so it is
        shown once, when it is created: copy it then. Revoking a key ends its
        access at once. To replace a key without downtime, create the new one,
        switch your server to it, then revoke the old one. Changes made with a
        key appear on the lead’s timeline as made by the person who created the
        key, via the API. Scopes: `leads.read` (Read leads), `leads.write`
        (Create and update leads), `leads.capture` (Capture leads).
      x-scopes:
        leads.read:
          label: Read leads
          description: >-
            Leads with every field, and the lists that describe them: fields,
            stages, sources and people.
          module: crm
        leads.write:
          label: Create and update leads
          description: >-
            Create leads, change their fields, stage and owner, and add notes.
            Needs leads.read.
          module: crm
        leads.capture:
          label: Capture leads
          description: >-
            Capture leads from a website or form: add a lead or update the
            existing one with the same phone or email. Cannot read, list or
            change anything else.
          module: crm
      x-key-types:
        - name: Website form
          scopes:
            - leads.capture
          lifetimeDays: 730
          description: >-
            A website or landing-page form that sends enquiries in as leads. Can
            do nothing else.
        - name: Another application
          lifetimeDays: 90
          description: >-
            Any other integration. Choose the scopes it needs when you create
            it.

````