List contacts

Page through your audience with cursor pagination and filters. Reads the same million-row-safe indexes the dashboard uses, so it stays fast at any size.

Updated ·3 min read
GET/v1/contacts

Requires the contacts:read scope.

Returns your contacts, newest first, with cursor pagination.

Query parameters#

Parameter Type Description
project string Required, always. A prj_ handle
limit integer 1 to 100, default 25
starting_after string Page forward from this contact id
ending_before string Page backward
status enum pending (Not subscribed), subscribed, unsubscribed, bounced, blocked. verified, the old name of subscribed, is still accepted for now
stage string One of the project's configured pipeline stages
identifier string Exact match, canonicalized first
email string Exact match on the address, canonicalized first
external_id string Your own id for the contact
created[gte] ISO-8601 Signed up on or after
created[lte] ISO-8601 Signed up on or before

Filters combine with AND.

Paging#

The envelope is { object, url, has_more, data }. There is no cursor field: you page forward by passing the id of the last contact in data as starting_after, and backward with ending_before. Keep going while has_more is true.

curl "https://api.getlaunchlist.com/v1/contacts?project=prj_7Qk2mN4pR8&limit=25&starting_after=con_4mKp9Wq2Rx" \\
  -H "Authorization: Bearer llk_live_8xKq3Rp9Wm2Nz7Vt6yL1cG5dH0jA4sE8uNqB2fXk"

Passing both starting_after and ending_before, or a handle that resolves to nothing, returns 400 parameter_invalid. So does a limit outside 1 to 100; it is refused rather than clamped.

Notes#

  • Contacts held by the overflow lock appear with locked: true and their identifying fields emptied. They are counted but withheld until the plan is upgraded.
  • position is read live from the leaderboard, not stored, so it is correct at the moment you ask. It is null for a contact who is not on the board.
  • deliverability is null until that verdict has been revealed with a credit. trust_tier is one of verified, valid, unknown, risky, fake.
  • Ordering is by creation time, newest first, with the id as a tiebreaker. That is stable under concurrent writes, which is what makes the cursor reliable.

Next#

Was this page helpful?
curl "https://api.getlaunchlist.com/v1/contacts?project=prj_7Qk2mN4pR8&limit=25" \\
  -H "Authorization: Bearer llk_live_8xKq3Rp9Wm2Nz7Vt6yL1cG5dH0jA4sE8uNqB2fXk"
{
  "object": "list",
  "url": "/v1/contacts",
  "has_more": true,
  "data": [
    {
      "object": "contact",
      "id": "con_4mKp9Wq2Rx",
      "livemode": true,
      "project": "prj_7Qk2mN4pR8",
      "identifier": "ada@lovelace.dev",
      "identifier_type": "email",
      "email": "ada@lovelace.dev",
      "external_id": "user_9182",
      "attributes": { "role": "Founder" },
      "status": "subscribed",
      "stage": "waitlist",
      "deliverability": null,
      "trust_tier": "verified",
      "position": 1284,
      "referral": {
        "code": "ADA7X2",
        "url": "https://acme.launchlist.page?ref=ADA7X2",
        "count": 3,
        "referred_by": "con_2Bn8Vd5Lk",
        "state": "credited"
      },
      "unsubscribed": false,
      "locked": false,
      "verified_at": "2026-07-28T14:02:55+00:00",
      "opt_in_confirmed_at": "2026-07-28T14:02:55+00:00",
      "consent": "signup",
      "consented_at": "2026-07-28T13:59:10+00:00",
      "unsubscribed_by": null,
      "unsubscribed_at": null,
      "created_at": "2026-07-28T13:59:10+00:00",
      "url": "/v1/contacts/con_4mKp9Wq2Rx"
    }
  ]
}