Skip to content

List contacts

GET
https://api.getsitecontrol.com/v1/sites/{site_id}/contacts
curl --request GET \
--url 'https://api.getsitecontrol.com/v1/sites/1/contacts?limit=50&order=oldest' \
--header 'Authorization: Bearer <token>'

Contacts of the site in ascending order of id (order=newest for the latest first), each with its e-mail, status, names, custom fields, tags, source and email_stats. Call it to find contacts by filters, to export them or to keep a copy in sync. One contact by id is get_contact; counts without the contacts are get_contacts_stats. Filters combine: every one given must match. Deleted contacts are not listed.

A page holds up to limit contacts; while next_cursor is set, pass it as cursor for the next page.

created_at is the date the contact was added at its source: imports and Shopify keep the original date, so created_at does not grow with the id.

To keep a copy in sync, walk the whole list with the cursor and no filters once. After that, pass updated_since set to the start of the previous walk minus a margin of a few minutes, and merge by id. The margin is required: a change may be stamped slightly earlier than it becomes visible. Deletions are not visible: a deleted contact simply disappears, so repeat the full walk now and then to notice them.

updated_since covers changes of the contact itself: its fields, status, tags or e-mail, and a restore. It misses the rest. A deletion is not listed, the contact disappears. Sending and opening e-mails, the e-mail quality check and segment tracking do not move updated_at, so email_stats changes without it. A contact not changed since changes began to be recorded, created in the admin, or the account owner’s contact added with the site has updated_at equal to created_at and is not found by updated_since, even when its created_at is newer; the full walk lists such contacts.

segment_id applies the conditions of the segment as they are now.

FieldDescription
site_id
required
Site Id
integer
FieldDescription
cursor
Cursor

next_cursor of the previous page, sent with the same order; omit for the first

string

next_cursor of the previous page, sent with the same order; omit for the first

limit
Limit

Items per page

integer
default: 50 >= 1 <= 100

Items per page

fields
Fields

Comma-separated fields to keep in each item, for example id,name; each item then carries only those fields and id. Omit for every field

string

Comma-separated fields to keep in each item, for example id,name; each item then carries only those fields and id. Omit for every field

order

Order of the items: oldest first (default) or newest first; asc and desc mean the same

string
Allowed values: oldest newest

Order of the items: oldest first (default) or newest first; asc and desc mean the same

status
Status

Any of these statuses; repeat for several. subscribed: subscribed, with double opt-in confirmed or not needed; unsubscribed: unsubscribed, never subscribed or awaiting double opt-in; bounced: the address bounced or failed the e-mail check

Array<string>
Allowed values: subscribed unsubscribed bounced

Any of these statuses; repeat for several. subscribed: subscribed, with double opt-in confirmed or not needed; unsubscribed: unsubscribed, never subscribed or awaiting double opt-in; bounced: the address bounced or failed the e-mail check

tag_ids
Tag Ids

Tagged with any of these tag ids from list_tags; repeat for several

Array<integer>
<= 50 items

Tagged with any of these tag ids from list_tags; repeat for several

country
Country

In any of these countries, ISO 3166-1 alpha-2 codes such as US; repeat for several

Array<string>
<= 50 items

In any of these countries, ISO 3166-1 alpha-2 codes such as US; repeat for several

email
Email

With any of these whole addresses, without case; repeat for several

Array<string>
<= 50 items

With any of these whole addresses, without case; repeat for several

search
Search

Part of the e-mail, phone, first or last name, without case; % and _ are plain characters. Digits also match the id. To find a contact by its address, use email

string
>= 1 characters <= 255 characters

Part of the e-mail, phone, first or last name, without case; % and _ are plain characters. Digits also match the id. To find a contact by its address, use email

created_since
Created Since

created_at at or after this moment; without an offset, taken as UTC; a plain date means its start

string format: date-time

created_at at or after this moment; without an offset, taken as UTC; a plain date means its start

created_before
Created Before

created_at before this moment; without an offset, taken as UTC; a plain date means its start

string format: date-time

created_at before this moment; without an offset, taken as UTC; a plain date means its start

updated_since
Updated Since

updated_at at or after this moment; without an offset, taken as UTC; a plain date means its start. Only contacts with a recorded change match

string format: date-time

updated_at at or after this moment; without an offset, taken as UTC; a plain date means its start. Only contacts with a recorded change match

segment_id
Segment Id

Matching the conditions of this segment, a segment id from list_segments

integer

Matching the conditions of this segment, a segment id from list_segments

conditions
Conditions

Matching a tree of conditions, as JSON: the language of create_segment conditions, without saving a segment; for example contacts without a first name: {“op”: “and”, “args”: [{“op”: “undefined”, “args”: [”{{$contact.firstName}}”]}]}

string
<= 4000 characters

Matching a tree of conditions, as JSON: the language of create_segment conditions, without saving a segment; for example contacts without a first name: {“op”: “and”, “args”: [{“op”: “undefined”, “args”: [”{{$contact.firstName}}”]}]}

Successful Response

Media typeapplication/json
ContactPage

One page of a list; next_cursor is null on the last page.

object
FieldDescription
items
required
Items
Array<object>
Contact
object
FieldDescription
id
required
Id
integer
email
required
Email
string
status
required
Status

Subscribed: subscribed to e-mails. unsubscribed: opted out, never subscribed, or has not confirmed the subscription yet. bounced: e-mails to the address bounced, or it was cleaned from the list.

string
Allowed values: subscribed unsubscribed bounced
first_name
First Name
string
nullable
last_name
Last Name
string
nullable
phone
Phone
string
nullable
country
Country

ISO 3166-1 alpha-2

string
nullable
timezone
Timezone

IANA time zone name

string
nullable
language
Language

ISO 639-1 code

string
nullable
fields
required
Fields

Set values of custom fields by field id, typed by the field: a date as YYYY-MM-DD, a datetime in ISO 8601

object
tags
required
Tags
Array<object>
ContactTag
object
FieldDescription
id
required
Id
integer
name
required
Name
string
source
required
ContactSource
object
FieldDescription
type
required
Type

Where the contact came from; widget, automation, import, shopify, mailchimp, klaviyo name the source. api: added through the public API or an AI assistant (MCP). manual: added by hand in the admin. other: a source not listed here.

string
Allowed values: widget automation manual import shopify mailchimp klaviyo api other
id
Id

Depends on the type: the widget, the automation, the admin user, the import task, the Shopify customer, the Mailchimp id; for api the API key, or the user whose access added it when there is no key

integer
nullable
email_stats
required
ContactEmailStats

E-mails to the contact, the keys of EmailMetrics; send includes e-mails rejected on sending, also counted in bounce.

object
FieldDescription
send
required
Send
integer
deliver
required
Deliver
integer
bounce
required
Bounce
integer
open
required
Open
integer
click
required
Click
integer
unsubscribe
required
Unsubscribe
integer
complaint
required
Complaint
integer
created_at
required
Created At

When the contact was added at its source; imports keep the original date

string format: date-time
updated_at
required
Updated At

Last change; equals created_at when none was recorded

string format: date-time
warnings
required
Warnings

Empty unless the contact could not be read in full; wording is not stable, do not parse

Array<string>
next_cursor
Next Cursor
string
nullable

Example

{
"items": [
{
"status": "subscribed",
"source": {
"type": "widget"
}
}
]
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Unsupported GSC-Version

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Missing or invalid API key or access token

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

WWW-Authenticate
string

Authentication scheme: Bearer

Access denied

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

segment_not_found: no segment segment_id on the site

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Media typeapplication/problem+json

segment_conditions_invalid: the conditions cannot be applied, the ones in conditions or the saved ones of the segment, which are fixed in the admin. validation_failed: a parameter is invalid. invalid_cursor: cursor was not issued here or was issued for another order

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Media typeapplication/problem+json

rate_limited: a request limit is spent; a request with search or segment_id also spends the heavy request limit

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Retry-After
integer

Seconds until the bucket refills

Media typeapplication/problem+json

temporarily_unavailable: the request took too long, or limits or idempotency keys cannot be enforced; narrow the filters or retry later

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds