List contacts

GET/api/v1/contacts
Requires anorganization API keywith the scopecontacts:read

Your contacts, newest first.

For a sync, use since_last_changed. It answers the only question an integration keeping its own copy actually has — what moved — and turns a nightly full-list crawl into a request that usually returns nothing. The value is an ISO 8601 timestamp; remember to URL-encode it, because the + in +00:00 means a space in a query string.

A since_last_changed we cannot parse is IGNORED and you get everything, rather than nothing. The two failures are not symmetrical: a sync handed zero rows concludes it is up to date and stops, and silently misses every change from then on.

Filter on state, not status. status is what the contact row says; state is what the product will actually do, and reconciles that row against your organization's suppression list. A contact whose row says subscribed but whose address you suppressed answers state: "suppressed" and will never be mailed, even though ?status=subscribed returns it.

Parameters

NameInTypeDescription
since_last_changedquerystringISO 8601. Returns only contacts modified strictly after this moment. URL-encode it.
statequerystringOne of subscribed, unsubscribed, bounced, complained, suppressed. What the product will do, suppression list included.
statusquerystringThe stored row value. Kept because it is published; prefer state.
searchquerystringMatches email or name.
list_idquerystringOnly contacts on this list.
fieldquerystringFilter by one custom field, by its key from GET /contact-fields, like country. Use with field_op and field_value: ?field=country&field_value=nigeria.
field_opquerystringHow field is matched: contains (the default), equals, is_set (has any value) or is_not_set (empty). Case does not matter, the same as in a segment.
field_valuequerystringWhat field is compared with. Not needed for is_set and is_not_set.
tagquerystringOnly contacts carrying this tag, matched by NAME and case-insensitively — tags are written by name everywhere, never by id.
interest_idquerystringOnly contacts who chose this interest, matched by ID. An interest's name is form copy; rewording it must not change who matches.
email_statusquerystringFilter by address check: one value or a comma list of valid, risky, invalid, unknown, pending, not_checked and never_checked. never_checked means from before Bounce protection launched; for everything not checked yet, use not_checked,never_checked. inbox_full selects contacts on a full-inbox hold (they also read risky).
created_viaquerystringFilter by how the contact was added: one value or a comma list of dashboard, api (POST /contacts), upsert (PUT /contacts), import and event. api,upsert means added by your app.
per_pagequeryintegerPage size.

Request

GET/api/v1/contacts
curl -X GET 'https://app.mailyte.com/api/v1/contacts' \
  -H 'Authorization: Bearer mk_live_YOUR_API_KEY'
The key names its own organization, so no X-Organization-ID header is needed.

Response

Success.

  • dataobject
    • dataarray<object>
      • objectstringcontact
      • idstring

        Unique identifier for the contact.

      • emailstring

        Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent.

      • namestring

        The contact's name. Null when none was given; {{ name }} is then empty unless your template gives a fallback.

      • statestringsubscribed | unsubscribed | bounced | complained | suppressed

        Whether this contact will be emailed. subscribed means yes; any other value is the reason not. It combines the contact's status with your suppression list, so a subscribed contact whose address is suppressed reads suppressed. Read-only: you set status (subscribed, unsubscribed, bounced or complained) instead. Note that ?status= filters on status, not on this.

      • email_statusstringpending | valid | risky | invalid | unknown | not_checked

        The result of checking whether the mailbox exists. valid: it exists. invalid: it does not. risky: it may not take mail (a catch-all domain, a role address such as info@, a throwaway address or a full inbox). unknown: the check could not tell. pending: being checked. not_checked: added after Bounce protection launched and not checked. Null: never checked, from before Bounce protection launched. Read-only; filter with ?email_status=.

      • email_full_untilstring

        Until when marketing to this contact is held because their inbox is full. When a check finds the inbox full, marketing waits 7 days; near the end it is checked again for free and the hold either ends or runs another 7 days. App email is never held. Null means no hold. Read-only.

      • fieldsobject

        Custom field values, keyed by the field's key (the name {{ signup_date }} uses). Always an object, {} when empty. Values are strings as stored; field defaults are not filled in here. When writing, send these as attributes.

      • listsarray<object>

        The lists this contact is on, with their names. When writing, send list IDs as list_ids.

        • idstring
        • namestring
      • tagsarray<object>

        Your labels on this contact, with their names.

        • idstring
        • namestring
      • interestsarray<object>

        What this contact chose on a form, each with the question it answers. [] means they chose nothing.

        • idstring

          Match on this in a segment rule, never on the name.

        • namestring

          The answer, as the contact read it.

        • category_idstring

          The question this answers.

        • category_titlestring

          The question in words. null MEANS NOT INCLUDED — the category was not loaded, never that the question has no title.

      • consentobject

        How this contact agreed to be emailed. Each field is null when we have no record. Set it when you import from another service, so your proof of consent comes with your contacts.

        • atstring

          When they agreed. Null when unknown.

        • ipstring

          The IP address they agreed from. Null when unknown.

        • sourcestring

          Where they agreed, such as a form name, a URL or "imported from Mailchimp". Null when unknown.

      • sourcestring

        How this contact was added: manual, import_api, import_csv or your own text (up to 50 characters). Null when nothing was recorded.

      • created_atstring
      • updated_atstring
    • pagination_metaany

Returned inside the standard envelope.

Errors

StatusWhen
401The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist.
403The key is valid but may not do this: it lacks the required scope, its IP allowlist does not include you, or this endpoint does not accept API keys.
404No such resource in this organization.
422The request was understood but the values were not acceptable.
429Too many requests, or the organization has spent its sending allowance. `Retry-After` says how long to wait.

Every status, with what causes it and what to do, is on the error reference.