Recipients a campaign
/api/v1/campaigns/{campaign}/recipientsParameters
| Name | In | Type | Description |
|---|---|---|---|
campaignrequired | path | string | The campaign identifier. |
Request
/api/v1/campaigns/{campaign}/recipientscurl -X GET 'https://app.mailyte.com/api/v1/campaigns/01JBT8XQ2M9WYC3K4F6R7S8T9V/recipients' \
-H 'Authorization: Bearer mk_live_YOUR_API_KEY'const response = await fetch('https://app.mailyte.com/api/v1/campaigns/01JBT8XQ2M9WYC3K4F6R7S8T9V/recipients', {
method: 'GET',
headers: {
Authorization: 'Bearer mk_live_YOUR_API_KEY',
},
});
const { data } = await response.json();import requests
response = requests.get(
"https://app.mailyte.com/api/v1/campaigns/01JBT8XQ2M9WYC3K4F6R7S8T9V/recipients",
headers={"Authorization": "Bearer mk_live_YOUR_API_KEY"},
)
data = response.json()["data"]<?php
$response = Http::withToken('mk_live_YOUR_API_KEY')
->get('https://app.mailyte.com/api/v1/campaigns/01JBT8XQ2M9WYC3K4F6R7S8T9V/recipients');
$data = $response->json('data');require "net/http"
require "json"
uri = URI("https://app.mailyte.com/api/v1/campaigns/01JBT8XQ2M9WYC3K4F6R7S8T9V/recipients")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer mk_live_YOUR_API_KEY"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }Response
Success.
dataobjectdataarray<object>objectstringcampaign_recipientidstringUnique identifier for the recipient row.
emailstringcontact_idstringNull for an address that reached the campaign without a contact row behind it.
statusstringpending | sent | failed | skipped_suppressed | skipped_unsubscribed | unknown`pending` is materialised but not yet attempted; `sent` was handed to the mail server; `failed` threw, see `error`; `skipped_suppressed` is on the organization's suppression list; `skipped_unsubscribed` opted out. `unknown` means we did not recognise the stored value and should never be seen.
errorstringThe failure reason, VERBATIM from the send attempt — today that is whatever the transport threw, PHP function names included. Do not parse it or branch on it: it is unstructured, it is not a closed set, and it will change. It is published because `status: "failed"` on its own leaves you unable to tell a bad address from a broken TLS handshake. `null` means NONE — nothing went wrong on this row — and it is cleared back to null when a resend resets the recipient to `pending`. It is never "we did not look": `status` is the field that tells you whether to expect one.
sent_atstringWhen the message was submitted to the mail server. NOT a delivery confirmation — that is `engagement.delivered` on the campaign's stats. Stamped only on `status: "sent"`, so `null` means NONE — nothing was submitted for this row — which covers `pending`, `failed` and both `skipped_*` statuses. It is never "we did not look". One wrinkle: a resend resets the row to `pending` and clears `error` but LEAVES this timestamp, so a `pending` row on a resent campaign can carry the previous attempt's time. Read `status` first.
opened_atstringFIRST correlated open — a recipient who opens five times has one `opened_at`. Not a stored column: it is correlated from the delivery-event ledger and exists only on this endpoint. Null means none was observed, which for a campaign that has not started means nothing has been measured at all.
clicked_atstringFirst correlated click, on the same terms as `opened_at`: not a stored column, correlated from the delivery-event ledger, and available only on this endpoint. `null` means NONE was observed — no click has been correlated to this recipient — which for a campaign that has not started means nothing has been measured at all. It is correlated from `tracking.click` events, so it also reads null for a message whose links the tracking pipeline never produced an event for.
pagination_metaany
Returned inside the standard envelope.
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist. |
403 | The 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. |
404 | No such resource in this organization. |
422 | The request was understood but the values were not acceptable. |
429 | Too 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.