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

# Pull or re-download leads

> Leads you've already exported. Reading them never buys anything; to get new people, start an export with `POST /api/v1/exports`.

**`since=last` (default): pull what's new.** Returns the leads this `consumer` hasn't pulled yet, oldest first, and moves its server-side cursor past them, so a daily job never sees the same lead twice. If `has_more` is true, call again straight away. Each `consumer` has its own cursor, and so does each consumer and `lane` pair: pulling with `lane=L1` doesn't move the all-lanes cursor (or the other way round), so a job that uses both gets L1's leads twice.

**`since=YYYY-MM-DD`: re-download.** Every lead exported on or after that date (UTC), oldest first, without touching any cursor. Narrow it with `to`, `lane`, `delivery`, `strength` and `keyword`, and page with `next_page` (`X-Next-Page` for CSV).

**Good to know**
- The cursor moves as soon as the response is built. If your job fails after the call, recover that batch with `since=YYYY-MM-DD`.
- `to`, `delivery`, `strength`, `keyword` and `page` only apply with a date `since`; with `since=last` they're ignored. Values that don't parse are ignored too.
- Suppressed people come back with `suppressed: true` and empty contact fields.

**CSV:** add `format=csv` for a file, with the headers `X-Lead-Count`, `X-Has-More` and (date mode) `X-Next-Page`. The CSV has one header row and these columns, in this order: `First Name`, `Last Name`, `Job Title`, `Seniority`, `Company`, `Website`, `Industry`, `Employees`, `City`, `State`, `Business Email`, `Email Status`, `Mobile`, `Mobile on DNC`, `Direct Phone`, `Company Phone`, `LinkedIn`, `Company LinkedIn`, `Intent Topics`, `Intent Score`, `Last Active`, `Lane`, `Keywords Matched`, `Intent Strength`, `First Seen`, `Exported`, `Seen Before`, `Suppressed`, `Lead ID`. `Exported` is `delivered_at`. Lists (`Keywords Matched`) are joined with `; `, booleans are `Yes` or `No`, empty values are empty cells, and lines end with CRLF. Cells that start with `=`, `+`, `-`, `@` or a tab are prefixed with `'` so spreadsheets don't run them as formulas (phone numbers like `+1 612 555 0142` are left as they are).

**Free.** This doesn't use any contacts from your plan.



## OpenAPI

````yaml /api-reference/openapi.json get /api/v1/leads
openapi: 3.1.0
info:
  title: Intent Leads API
  version: '1.0'
  description: >-
    The Intent Leads API finds B2B people actively researching the topics you
    sell into, and exports them with contact details into your own tools.


    **Authentication.** Send an API key as a bearer token: `Authorization:
    Bearer il_live_…`. Keys belong to one organization. Standard keys work with
    everything except billing, team and key management, which need an admin key.


    **What costs contacts.** Only `POST /api/v1/exports` with `"dry_run": false`
    uses contacts from your plan. Quotes, counts, checks, samples and
    re-downloads are free.


    **Errors.** Every error is JSON: `{"error": "code", "message":
    "Plain-English explanation"}`. Codes are stable; messages may change.


    **Conventions.** JSON by default. Dates are `YYYY-MM-DD` and timestamps ISO
    8601, all in UTC. Lane codes (`L1`) are case-insensitive.
servers:
  - url: https://intentleads.si
security:
  - bearerAuth: []
tags:
  - name: Exports
    description: Quote (free) and buy new people from your lanes, then download them.
  - name: Leads
    description: Pull and re-download the leads you've exported, and list deliveries.
  - name: Lanes
    description: >-
      Create, inspect and tune lanes: keywords plus the companies and roles you
      want.
  - name: Keywords
    description: Add and remove a lane's keywords; each one is approved as its own topic.
  - name: Checks
    description: >-
      Free lane checks that size every filter step over 14 days, plus quick
      topic signals.
  - name: Company list
    description: >-
      The target-company list your lanes can narrow to or use instead of
      industries.
  - name: Suppressions
    description: People you exported who later asked to be removed.
  - name: Usage
    description: Contacts used and left this billing period.
  - name: Billing
    description: Plan, invoices and plan changes. Admin keys only.
  - name: Team
    description: Members and invite links. Admin keys only.
  - name: API keys
    description: Create, rename, rotate and revoke API keys. Admin keys only.
  - name: Account
    description: Check which organization a key belongs to and its role.
  - name: Reference
    description: Valid values for lane filters.
  - name: Activity
    description: A feed of changes and events in your organization.
paths:
  /api/v1/leads:
    get:
      tags:
        - Leads
      summary: Pull or re-download leads
      description: >-
        Leads you've already exported. Reading them never buys anything; to get
        new people, start an export with `POST /api/v1/exports`.


        **`since=last` (default): pull what's new.** Returns the leads this
        `consumer` hasn't pulled yet, oldest first, and moves its server-side
        cursor past them, so a daily job never sees the same lead twice. If
        `has_more` is true, call again straight away. Each `consumer` has its
        own cursor, and so does each consumer and `lane` pair: pulling with
        `lane=L1` doesn't move the all-lanes cursor (or the other way round), so
        a job that uses both gets L1's leads twice.


        **`since=YYYY-MM-DD`: re-download.** Every lead exported on or after
        that date (UTC), oldest first, without touching any cursor. Narrow it
        with `to`, `lane`, `delivery`, `strength` and `keyword`, and page with
        `next_page` (`X-Next-Page` for CSV).


        **Good to know**

        - The cursor moves as soon as the response is built. If your job fails
        after the call, recover that batch with `since=YYYY-MM-DD`.

        - `to`, `delivery`, `strength`, `keyword` and `page` only apply with a
        date `since`; with `since=last` they're ignored. Values that don't parse
        are ignored too.

        - Suppressed people come back with `suppressed: true` and empty contact
        fields.


        **CSV:** add `format=csv` for a file, with the headers `X-Lead-Count`,
        `X-Has-More` and (date mode) `X-Next-Page`. The CSV has one header row
        and these columns, in this order: `First Name`, `Last Name`, `Job
        Title`, `Seniority`, `Company`, `Website`, `Industry`, `Employees`,
        `City`, `State`, `Business Email`, `Email Status`, `Mobile`, `Mobile on
        DNC`, `Direct Phone`, `Company Phone`, `LinkedIn`, `Company LinkedIn`,
        `Intent Topics`, `Intent Score`, `Last Active`, `Lane`, `Keywords
        Matched`, `Intent Strength`, `First Seen`, `Exported`, `Seen Before`,
        `Suppressed`, `Lead ID`. `Exported` is `delivered_at`. Lists (`Keywords
        Matched`) are joined with `; `, booleans are `Yes` or `No`, empty values
        are empty cells, and lines end with CRLF. Cells that start with `=`,
        `+`, `-`, `@` or a tab are prefixed with `'` so spreadsheets don't run
        them as formulas (phone numbers like `+1 612 555 0142` are left as they
        are).


        **Free.** This doesn't use any contacts from your plan.
      operationId: listLeads
      parameters:
        - name: since
          in: query
          required: false
          description: >-
            `last` (default): new leads since this consumer's last pull, moving
            its cursor. Or a date `YYYY-MM-DD`: everything exported since then
            (UTC), no cursor change.
          schema:
            type: string
            default: last
          example: last
        - name: lane
          in: query
          required: false
          description: >-
            Only this lane's leads (case-insensitive). With `since=last` the
            lane has its own cursor.
          schema:
            type: string
          example: L1
        - name: consumer
          in: query
          required: false
          description: >-
            Names the cursor for `since=last`, so separate jobs each get every
            lead. Letters, digits, `.`, `-` or `_`, up to 40.
          schema:
            type: string
            default: default
            pattern: ^[A-Za-z0-9_.-]{1,40}$
          example: crm-sync
        - name: limit
          in: query
          required: false
          description: Leads per response, 1 to 5,000. Out-of-range values are clamped.
          schema:
            type: integer
            minimum: 1
            maximum: 5000
            default: 1000
          example: 1000
        - name: format
          in: query
          required: false
          description: '`json` (default) or `csv`.'
          schema:
            type: string
            enum:
              - json
              - csv
            default: json
          example: json
        - name: page
          in: query
          required: false
          description: 'Date mode only: the `next_page` value from the previous response.'
          schema:
            type: string
        - name: to
          in: query
          required: false
          description: >-
            Date mode only: last export date to include (`YYYY-MM-DD`, UTC,
            inclusive).
          schema:
            type: string
            format: date
          example: '2026-10-14'
        - name: delivery
          in: query
          required: false
          description: >-
            Date mode only: only leads from this delivery id (see `GET
            /api/v1/deliveries`).
          schema:
            type: integer
            minimum: 1
          example: 412
        - name: strength
          in: query
          required: false
          description: >-
            Date mode only: `medium` (medium and high) or `high` (high only).
            Other values are ignored.
          schema:
            type: string
            enum:
              - medium
              - high
          example: high
        - name: keyword
          in: query
          required: false
          description: >-
            Date mode only: only leads that matched this exact keyword
            (case-sensitive).
          schema:
            type: string
          example: selling to group purchasing organizations
      responses:
        '200':
          description: A page of leads, as JSON or (with `format=csv`) a CSV file.
          headers:
            X-Lead-Count:
              description: 'CSV only: leads in this response.'
              schema:
                type: integer
            X-Has-More:
              description: >-
                CSV only: `true` when the response is full and there may be
                more.
              schema:
                type: string
                enum:
                  - 'true'
                  - 'false'
            X-Next-Page:
              description: >-
                CSV only, date mode: the `page` value for the next page. Absent
                on the last page.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LeadsPage'
              examples:
                pull:
                  summary: since=last
                  value:
                    since: last
                    lane: null
                    count: 2
                    has_more: false
                    next_page: null
                    leads:
                      - lead_id: 0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3d
                        lane: L1
                        keywords_matched:
                          - selling to group purchasing organizations
                        intent_strength: high
                        first_seen: '2026-10-03T00:00:00+00:00'
                        delivered_at: '2026-10-14T09:31:07.482913+00:00'
                        seen_before: false
                        suppressed: false
                        first_name: Jordan
                        last_name: Lee
                        job_title: VP of Sales
                        seniority: VP
                        company: Acme Medical Supply
                        website: example.com
                        industry: Medical Equipment Manufacturing
                        employees: 140
                        city: Minneapolis
                        state: MN
                        business_email: jordan.lee@example.com
                        email_status: valid
                        mobile: +1 612 555 0142
                        mobile_on_dnc: false
                        direct_phone: +1 612 555 0187
                        company_phone: +1 612 555 0100
                        linkedin: linkedin.com/in/example-jordan-lee
                        company_linkedin: linkedin.com/company/example-acme-medical
                        intent_topics: selling to group purchasing organizations
                        intent_score: 81
                        last_active: '2026-10-12'
                      - lead_id: 0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3e
                        lane: L1
                        keywords_matched:
                          - finding medical device distributors
                        intent_strength: medium
                        first_seen: '2026-10-06T00:00:00+00:00'
                        delivered_at: '2026-10-14T09:31:07.482913+00:00'
                        seen_before: true
                        suppressed: false
                        first_name: Sam
                        last_name: Rivera
                        job_title: Director of Business Development
                        seniority: Director
                        company: Globex Surgical
                        website: example.org
                        industry: Medical Device
                        employees: 85
                        city: Columbus
                        state: OH
                        business_email: sam.rivera@example.org
                        email_status: valid
                        mobile: null
                        mobile_on_dnc: null
                        direct_phone: +1 614 555 0133
                        company_phone: +1 614 555 0100
                        linkedin: linkedin.com/in/example-sam-rivera
                        company_linkedin: linkedin.com/company/example-globex-surgical
                        intent_topics: finding medical device distributors
                        intent_score: 54
                        last_active: '2026-10-11'
                by_date:
                  summary: since=2026-10-01&limit=2
                  value:
                    since: '2026-10-01'
                    lane: L1
                    count: 2
                    has_more: true
                    next_page: MTg0MjI
                    leads:
                      - lead_id: 0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3d
                        lane: L1
                        keywords_matched:
                          - selling to group purchasing organizations
                        intent_strength: high
                        first_seen: '2026-10-03T00:00:00+00:00'
                        delivered_at: '2026-10-14T09:31:07.482913+00:00'
                        seen_before: false
                        suppressed: false
                        first_name: Jordan
                        last_name: Lee
                        job_title: VP of Sales
                        seniority: VP
                        company: Acme Medical Supply
                        website: example.com
                        industry: Medical Equipment Manufacturing
                        employees: 140
                        city: Minneapolis
                        state: MN
                        business_email: jordan.lee@example.com
                        email_status: valid
                        mobile: +1 612 555 0142
                        mobile_on_dnc: false
                        direct_phone: +1 612 555 0187
                        company_phone: +1 612 555 0100
                        linkedin: linkedin.com/in/example-jordan-lee
                        company_linkedin: linkedin.com/company/example-acme-medical
                        intent_topics: selling to group purchasing organizations
                        intent_score: 81
                        last_active: '2026-10-12'
                      - lead_id: 0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3e
                        lane: L1
                        keywords_matched:
                          - finding medical device distributors
                        intent_strength: medium
                        first_seen: '2026-10-06T00:00:00+00:00'
                        delivered_at: '2026-10-14T09:31:07.482913+00:00'
                        seen_before: true
                        suppressed: false
                        first_name: Sam
                        last_name: Rivera
                        job_title: Director of Business Development
                        seniority: Director
                        company: Globex Surgical
                        website: example.org
                        industry: Medical Device
                        employees: 85
                        city: Columbus
                        state: OH
                        business_email: sam.rivera@example.org
                        email_status: valid
                        mobile: null
                        mobile_on_dnc: null
                        direct_phone: +1 614 555 0133
                        company_phone: +1 614 555 0100
                        linkedin: linkedin.com/in/example-sam-rivera
                        company_linkedin: linkedin.com/company/example-globex-surgical
                        intent_topics: finding medical device distributors
                        intent_score: 54
                        last_active: '2026-10-11'
            text/csv:
              schema:
                type: string
              example: "First Name,Last Name,Job Title,Seniority,Company,Website,Industry,Employees,City,State,Business Email,Email Status,Mobile,Mobile on DNC,Direct Phone,Company Phone,LinkedIn,Company LinkedIn,Intent Topics,Intent Score,Last Active,Lane,Keywords Matched,Intent Strength,First Seen,Exported,Seen Before,Suppressed,Lead ID\r\nJordan,Lee,VP of Sales,VP,Acme Medical Supply,example.com,Medical Equipment Manufacturing,140,Minneapolis,MN,jordan.lee@example.com,valid,+1 612 555 0142,No,+1 612 555 0187,+1 612 555 0100,linkedin.com/in/example-jordan-lee,linkedin.com/company/example-acme-medical,selling to group purchasing organizations,81,2026-10-12,L1,selling to group purchasing organizations,high,2026-10-03T00:00:00+00:00,2026-10-14T09:31:07.482913+00:00,No,No,0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3d\r\nSam,Rivera,Director of Business Development,Director,Globex Surgical,example.org,Medical Device,85,Columbus,OH,sam.rivera@example.org,valid,,,+1 614 555 0133,+1 614 555 0100,linkedin.com/in/example-sam-rivera,linkedin.com/company/example-globex-surgical,finding medical device distributors,54,2026-10-11,L1,finding medical device distributors,medium,2026-10-06T00:00:00+00:00,2026-10-14T09:31:07.482913+00:00,Yes,No,0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3e\r\n"
        '400':
          description: A parameter isn't valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_since:
                  value:
                    error: invalid_since
                    message: since must be 'last' or a date like 2026-10-01.
                invalid_consumer:
                  value:
                    error: invalid_consumer
                    message: >-
                      consumer: letters, digits, dot, dash or underscore, up to
                      40.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/LaneNotFound'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    LeadsPage:
      type: object
      properties:
        since:
          type: string
          example: last
          description: 'The `since` you sent: `last` or a date.'
        lane:
          type:
            - string
            - 'null'
          description: Lane filter, or null for every lane.
        count:
          type: integer
          description: Leads in this response.
        has_more:
          type: boolean
          description: >-
            True when this response is full (`count` equals `limit`): call again
            for more.
        next_page:
          type:
            - string
            - 'null'
          description: >-
            Only with `since=YYYY-MM-DD`: pass as `page` to get the next page.
            Null when there are no more, and always null with `since=last`.
        leads:
          type: array
          items:
            $ref: '#/components/schemas/Lead'
      required:
        - since
        - lane
        - count
        - has_more
        - next_page
        - leads
    Error:
      type: object
      properties:
        error:
          type: string
          example: lane_not_found
          description: Stable machine-readable code, e.g. `lane_not_found`.
        message:
          type: string
          example: No lane L9.
          description: Plain-English explanation you can show to a person.
      required:
        - error
        - message
      description: Every error has this shape.
    Lead:
      type: object
      properties:
        lead_id:
          type: string
          format: uuid
          description: Stable id for this lead. Use it to dedupe and to match suppressions.
        lane:
          type:
            - string
            - 'null'
          description: >-
            Code of the lane that found this person, or null if that lane no
            longer exists.
        keywords_matched:
          type: array
          items:
            type: string
          description: The lane keywords this person was researching.
        intent_strength:
          type:
            - string
            - 'null'
          enum:
            - low
            - medium
            - high
            - null
          description: How strongly this person is researching.
        first_seen:
          type:
            - string
            - 'null'
          format: date-time
          description: When this person was first seen researching the topic.
        delivered_at:
          type: string
          format: date-time
          description: When the lead was exported to you. The CSV column is `Exported`.
        seen_before:
          type: boolean
          description: >-
            True when this person was also exported to you in an earlier billing
            period. They count again in this one.
        suppressed:
          type: boolean
          description: >-
            True when this person asked to be removed. All contact fields are
            null; delete them from your systems (see Suppressions).
        first_name:
          type:
            - string
            - 'null'
        last_name:
          type:
            - string
            - 'null'
        job_title:
          type:
            - string
            - 'null'
        seniority:
          type:
            - string
            - 'null'
          description: Seniority level, e.g. `CXO`, `VP`, `Director`, `Manager`.
        company:
          type:
            - string
            - 'null'
          description: Company name.
        website:
          type:
            - string
            - 'null'
          description: Company domain.
        industry:
          type:
            - string
            - 'null'
          description: Company industry.
        employees:
          type:
            - integer
            - 'null'
          description: Company headcount.
        city:
          type:
            - string
            - 'null'
          description: Company city.
        state:
          type:
            - string
            - 'null'
          description: Company state (US two-letter code or name).
        business_email:
          type:
            - string
            - 'null'
          format: email
        email_status:
          type:
            - string
            - 'null'
          description: >-
            Validation status of `business_email`, lowercase (e.g. `valid`).
            Null when there's no email.
        mobile:
          type:
            - string
            - 'null'
          description: >-
            A mobile number. The first one not on the do-not-call list is picked
            when that's known.
        mobile_on_dnc:
          type:
            - boolean
            - 'null'
          description: >-
            Whether `mobile` is on the do-not-call list. Null when there's no
            mobile or it isn't known.
        direct_phone:
          type:
            - string
            - 'null'
          description: Direct dial.
        company_phone:
          type:
            - string
            - 'null'
          description: Company switchboard.
        linkedin:
          type:
            - string
            - 'null'
          description: Personal LinkedIn profile URL.
        company_linkedin:
          type:
            - string
            - 'null'
          description: Company LinkedIn page URL.
        intent_topics:
          type:
            - string
            - 'null'
          description: 'The topic this person matched: normally the lane keyword.'
        intent_score:
          type:
            - number
            - 'null'
          description: >-
            Intent score for the matched topic. Higher means more research
            activity. Not a percentile.
        last_active:
          type:
            - string
            - 'null'
          description: Day the person was last seen researching (`YYYY-MM-DD`).
      required:
        - lead_id
        - lane
        - keywords_matched
        - intent_strength
        - first_seen
        - delivered_at
        - seen_before
        - suppressed
        - first_name
        - last_name
        - job_title
        - seniority
        - company
        - website
        - industry
        - employees
        - city
        - state
        - business_email
        - email_status
        - mobile
        - mobile_on_dnc
        - direct_phone
        - company_phone
        - linkedin
        - company_linkedin
        - intent_topics
        - intent_score
        - last_active
      description: >-
        One exported person. Every field is always present; unknown values are
        null. Names, titles, companies and places are title-cased; emails, URLs
        and domains are left as they are.
      example:
        lead_id: 0199e3b2-5a7c-7e21-b4d3-8c9f0a1b2c3d
        lane: L1
        keywords_matched:
          - selling to group purchasing organizations
        intent_strength: high
        first_seen: '2026-10-03T00:00:00+00:00'
        delivered_at: '2026-10-14T09:31:07.482913+00:00'
        seen_before: false
        suppressed: false
        first_name: Jordan
        last_name: Lee
        job_title: VP of Sales
        seniority: VP
        company: Acme Medical Supply
        website: example.com
        industry: Medical Equipment Manufacturing
        employees: 140
        city: Minneapolis
        state: MN
        business_email: jordan.lee@example.com
        email_status: valid
        mobile: +1 612 555 0142
        mobile_on_dnc: false
        direct_phone: +1 612 555 0187
        company_phone: +1 612 555 0100
        linkedin: linkedin.com/in/example-jordan-lee
        company_linkedin: linkedin.com/company/example-acme-medical
        intent_topics: selling to group purchasing organizations
        intent_score: 81
        last_active: '2026-10-12'
  responses:
    Unauthorized:
      description: Missing, malformed, unknown or revoked API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthorized:
              value:
                error: unauthorized
                message: 'Send a valid API key as: Authorization: Bearer il_live_…'
    LaneNotFound:
      description: No lane with that code.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            lane_not_found:
              value:
                error: lane_not_found
                message: No lane L9.
    InternalError:
      description: >-
        Unexpected server error. Safe to retry reads; retry an export only with
        the same `idempotency_key`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            internal_error:
              value:
                error: internal_error
                message: Something went wrong. Try again.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: il_live_…
      description: >-
        An Intent Leads API key, e.g. `il_live_` followed by 32 letters and
        digits. Create one on the API and CLI page of the dashboard.

````

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