{"openapi":"3.1.0","info":{"title":"InboxPro Stats API","version":"1.0.0","description":"## Getting started\n\nThe InboxPro Stats API gives you the delivery and engagement numbers for the email you send through InboxPro, so you can pull them into your own dashboards, reports, or tools.\n\n1. **Get an API key.** Go to [https://data.inboxpro.io/portal](https://data.inboxpro.io/portal) and sign in with GoHighLevel. Create a key and copy it right away; it is shown only once. You can limit a key to some of your domains.\n2. **Make your first request.** Check that the key works:\n\n```bash\ncurl https://data.inboxpro.io/v1/me \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\nThe response lists the sending domains your key can read.\n\n3. **Fetch your numbers.** For example, the last 7 days for one domain:\n\n```bash\ncurl \"https://data.inboxpro.io/v1/domains/example.com/summary\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\nYou can also try every endpoint from this page: click **Test Request** on any endpoint and paste your key.\n\n## Authentication\n\nSend your API key in the `Authorization` header of every request:\n\n```\nAuthorization: Bearer ipk_live_...\n```\n\n- Keep keys on your server. Do not put them in web pages or mobile apps.\n- Create one key per integration, so you can revoke one without breaking the others.\n- If a key leaks, revoke it in the portal. It stops working within a minute.\n\nEach key belongs to your account and can read only your sending domains. A key can also be limited to some of them, for example one brand for an agency or integration. `GET /v1/me` shows exactly which domains a key can read. Lists of individual recipients need a key with the **recipients:read** permission; ask your InboxPro contact to enable it.\n\n## Dates and data freshness\n\n- `from` and `to` are calendar days in `YYYY-MM-DD` format, in **UTC**, and both days are included.\n- Without them you get the last 7 days, ending today.\n- A single request can cover up to 90 days. Stats are kept for 90 days.\n- Numbers are only a few minutes behind real time, and responses may be reused for up to 5 minutes. Every response has a `data_as_of` time showing when it was computed. Today's numbers keep changing as emails go out and people open them, and a day's bounce count is final once that day has ended (UTC).\n- Opens, clicks, and unsubscribes are counted against the day the email was **sent**, so a campaign's numbers stay together even when people act days later.\n\n## Bot filtering\n\nMany mailboxes open emails and check links automatically, before a person ever sees them. Security scanners do this, and so do privacy features such as Apple Mail Privacy Protection. Counting those would make your open and click rates look higher than they are.\n\nBy default the API leaves these automated opens and clicks out (`exclude_bots=true`), so the numbers reflect real people. Pass `exclude_bots=false` to see every open and click we recorded. Unsubscribes are always counted.\n\n## Rate limits\n\nEach key can make **60 requests per minute** and **10,000 requests per day**. Every response tells you where you stand:\n\n| Header | Meaning |\n|---|---|\n| `X-RateLimit-Limit` | Requests allowed per minute |\n| `X-RateLimit-Remaining` | Requests left in the current minute |\n| `X-RateLimit-Reset` | Seconds until the minute resets |\n\n`GET /v1/me` shows how many requests you made today. If you go over either limit, you get HTTP `429`; wait the number of seconds in the `Retry-After` header and try again.\n\nNumbers change at most once an hour, so caching responses for a few minutes on your side is safe.\n\n## Errors\n\nErrors always have the same shape:\n\n```json\n{\n  \"error\": {\n    \"code\": \"invalid_parameter\",\n    \"message\": \"The query parameter \\\"from\\\" must be a date in YYYY-MM-DD format, for example 2026-10-01.\"\n  }\n}\n```\n\n| HTTP | `code` | What to do |\n|---|---|---|\n| 400 | `invalid_parameter` | Fix the parameter named in the message. |\n| 401 | `unauthorized` | Check that the key is correct and has not been revoked. |\n| 403 | `forbidden_scope` | This key lacks the permission the endpoint needs. |\n| 404 | `not_found` | The domain is not one of yours, or the path is wrong. |\n| 429 | `rate_limited`, `quota_exceeded` | Slow down, or wait until tomorrow (UTC) for the daily quota. |\n| 503 | `temporarily_unavailable` | Retry after a short wait. |\n| 500 | `internal_error` | Retry; if it keeps happening, contact support@inboxpro.io. |\n\n## Glossary\n\n| Term | Meaning |\n|---|---|\n| **Domain** | The domain in your From address, for example `example.com` in `news@example.com`. |\n| **Campaign** | All emails sent with the same subject line. |\n| **Sent** | Emails we attempted to deliver. |\n| **Delivered** | Emails the recipient's mail server accepted. Delivered is not the same as inboxed: the provider can still file it as spam. |\n| **Bounce** | The recipient's mail server refused the email. Each bounce has a reason (see `GET /v1/bounce-reasons`). Its kind tells you what to do: `permanent` means remove the address, `temporary` means it may be accepted later, and `not_sent` means it was refused before sending. |\n| **Rejection** | We did not send the email because of a policy check, such as a previously unsubscribed or suppressed address. |\n| **Open / Click** | A recipient opened the email or clicked a link. Each recipient counts once, however many times they act. |\n| **Spam complaints** | A recipient marked your email as spam. Gmail reports a daily rate (keep it below 0.3%); Yahoo reports each complaint. |\n| **Rates** | Percentages from 0 to 100. Open, click, and unsubscribe rates are measured against delivered emails. |","contact":{"name":"InboxPro support","email":"support@inboxpro.io"}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Your InboxPro API key, from the API keys page in the portal."}},"schemas":{}},"paths":{"/v1/me":{"get":{"operationId":"getMe","summary":"Check your API key","tags":["Account"],"description":"Returns the account this key belongs to, the sending domains it can read, and its limits. A good first call to confirm your key works.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string","description":"Your InboxPro account id.","examples":["acme"]},"name":{"type":"string","description":"Your account name.","examples":["Acme Inc."]}},"required":["id","name"]},"domains":{"type":"array","items":{"type":"string"},"description":"Sending domains this key can read stats for.","examples":[["acme.com","news.acme.com"]]},"key":{"type":"object","properties":{"name":{"type":"string","description":"The label you gave this key.","examples":["Reporting dashboard"]},"prefix":{"type":"string","description":"First characters of the key, to tell keys apart.","examples":["ipk_live_3fQ"]},"permissions":{"type":"array","items":{"type":"string","enum":["stats:read","recipients:read"]},"description":"`stats:read`: totals and rates. `recipients:read`: lists of individual recipients."},"all_domains":{"type":"boolean","description":"True when the key covers every sending domain of your account, including ones added later. False when it is limited to the domains listed above."},"created_at":{"type":"string","format":"date-time"}},"required":["name","prefix","permissions","all_domains","created_at"]},"limits":{"type":"object","properties":{"requests_per_minute":{"type":"integer","examples":[60]},"requests_per_day":{"type":"integer","examples":[10000]},"requests_today":{"type":"integer","description":"Requests made with this key since 00:00 UTC, including this one.","examples":[42]}},"required":["requests_per_minute","requests_per_day","requests_today"]}},"required":["account","domains","key","limits"]}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}}}}},"/v1/domains/{domain}/summary":{"get":{"operationId":"getDomainSummary","summary":"Domain summary","tags":["Overview"],"description":"Totals and rates for everything sent from one domain over a period: deliveries, bounces, opens, clicks, and unsubscribes.","parameters":[{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","examples":["example.com"]},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean","description":"Whether automated opens and clicks were left out."},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"first_sent_at":{"type":["null","string"],"format":"date-time","description":"First email sent in the period."},"last_sent_at":{"type":["null","string"],"format":"date-time","description":"Last email sent in the period."},"totals":{"type":"object","properties":{"sent":{"type":"integer","description":"Emails handed to recipients' mail servers: delivered plus bounced. Rejections are not included."},"delivered":{"type":"integer","description":"Emails accepted by the recipient's mail server."},"bounces":{"type":"integer","description":"Emails the recipient's mail server refused, for example because the address does not exist."},"rejections":{"type":"integer","description":"Emails our servers refused to accept from your sending system, for example because they failed a sending policy check. These were never sent."},"opens":{"type":"integer","description":"Recipients who opened the email at least once."},"clicks":{"type":"integer","description":"Recipients who clicked at least one link."},"unsubscribes":{"type":"integer","description":"Recipients who unsubscribed."}},"required":["sent","delivered","bounces","rejections","opens","clicks","unsubscribes"]},"rates":{"type":"object","properties":{"delivery_rate":{"type":["null","number"],"description":"Delivered ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"bounce_rate":{"type":["null","number"],"description":"Bounces ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"open_rate":{"type":["null","number"],"description":"Opens ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_rate":{"type":["null","number"],"description":"Clicks ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_to_open_rate":{"type":["null","number"],"description":"Clicks ÷ opens. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"unsubscribe_rate":{"type":["null","number"],"description":"Unsubscribes ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."}},"required":["delivery_rate","bounce_rate","open_rate","click_rate","click_to_open_rate","unsubscribe_rate"]}},"required":["domain","period","bots_excluded","data_as_of","totals","rates"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/daily":{"get":{"operationId":"getDomainDaily","summary":"Daily breakdown","tags":["Overview"],"description":"The same numbers as the summary, split per day. Use it to chart trends.","parameters":[{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","examples":["example.com"]},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"days":{"type":"array","description":"One row per day, oldest first. Every day in the period is present, with zeros when nothing was sent. Opens, clicks, and unsubscribes are counted on the day the email was sent, not the day the recipient acted.","items":{"type":"object","properties":{"date":{"type":"string","format":"date","examples":["2026-10-01"]},"sent":{"type":"integer","description":"Emails handed to recipients' mail servers: delivered plus bounced. Rejections are not included."},"delivered":{"type":"integer","description":"Emails accepted by the recipient's mail server."},"bounces":{"type":"integer","description":"Emails the recipient's mail server refused, for example because the address does not exist."},"rejections":{"type":"integer","description":"Emails our servers refused to accept from your sending system, for example because they failed a sending policy check. These were never sent."},"opens":{"type":"integer","description":"Recipients who opened the email at least once."},"clicks":{"type":"integer","description":"Recipients who clicked at least one link."},"unsubscribes":{"type":"integer","description":"Recipients who unsubscribed."},"delivery_rate":{"type":["null","number"],"description":"Delivered ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"bounce_rate":{"type":["null","number"],"description":"Bounces ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"open_rate":{"type":["null","number"],"description":"Opens ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_rate":{"type":["null","number"],"description":"Clicks ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_to_open_rate":{"type":["null","number"],"description":"Clicks ÷ opens. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"unsubscribe_rate":{"type":["null","number"],"description":"Unsubscribes ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."}},"required":["date","sent","delivered","bounces","rejections","opens","clicks","unsubscribes","delivery_rate","bounce_rate","open_rate","click_rate","click_to_open_rate","unsubscribe_rate"]}}},"required":["domain","period","bots_excluded","data_as_of","days"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns":{"get":{"operationId":"listCampaigns","summary":"List campaigns","tags":["Campaigns"],"description":"One row per campaign sent from the domain in the period. A campaign is every email that shared the same subject line.","parameters":[{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number, starting at 1."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"page_size","required":false,"description":"Rows per page (max 100)."},{"schema":{"type":"string","enum":["last_sent_at","sent","open_rate","click_rate","bounce_rate","unsubscribe_rate"],"default":"last_sent_at"},"in":"query","name":"sort","required":false,"description":"Order campaigns by this column, highest or most recent first."},{"schema":{"type":"string","maxLength":200},"in":"query","name":"search","required":false,"description":"Only campaigns whose subject contains this text (not case-sensitive)."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","examples":["example.com"]},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"pagination":{"type":"object","description":"Where this page sits in the full result.","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer","description":"Total rows across all pages."}},"required":["page","page_size","total"]},"campaigns":{"type":"array","items":{"type":"object","properties":{"subject":{"type":"string","description":"The campaign subject line.","examples":["October newsletter"]},"first_sent_at":{"type":["null","string"],"format":"date-time","description":"First email of this campaign delivered in the period."},"last_sent_at":{"type":["null","string"],"format":"date-time","description":"Last email of this campaign delivered in the period."},"sent":{"type":"integer","description":"Emails handed to recipients' mail servers: delivered plus bounced. Rejections are not included."},"delivered":{"type":"integer","description":"Emails accepted by the recipient's mail server."},"bounces":{"type":"integer","description":"Emails the recipient's mail server refused, for example because the address does not exist."},"rejections":{"type":"integer","description":"Emails our servers refused to accept from your sending system, for example because they failed a sending policy check. These were never sent."},"opens":{"type":"integer","description":"Recipients who opened the email at least once."},"clicks":{"type":"integer","description":"Recipients who clicked at least one link."},"unsubscribes":{"type":"integer","description":"Recipients who unsubscribed."},"delivery_rate":{"type":["null","number"],"description":"Delivered ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"bounce_rate":{"type":["null","number"],"description":"Bounces ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"open_rate":{"type":["null","number"],"description":"Opens ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_rate":{"type":["null","number"],"description":"Clicks ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_to_open_rate":{"type":["null","number"],"description":"Clicks ÷ opens. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"unsubscribe_rate":{"type":["null","number"],"description":"Unsubscribes ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."}},"required":["subject","first_sent_at","last_sent_at","sent","delivered","bounces","rejections","opens","clicks","unsubscribes","delivery_rate","bounce_rate","open_rate","click_rate","click_to_open_rate","unsubscribe_rate"]}}},"required":["domain","period","bots_excluded","data_as_of","pagination","campaigns"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns/detail":{"get":{"operationId":"getCampaign","summary":"Campaign detail","tags":["Campaigns"],"description":"Totals for one campaign, plus why emails bounced and which links were clicked. Pass the subject line exactly as the campaign list returns it.","parameters":[{"schema":{"type":"string"},"example":"October newsletter","in":"query","name":"subject","required":true,"description":"The exact subject line of the campaign, as returned by the campaigns list."},{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","examples":["example.com"]},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"campaign":{"type":"object","properties":{"subject":{"type":"string","description":"The campaign subject line.","examples":["October newsletter"]},"first_sent_at":{"type":["null","string"],"format":"date-time","description":"First email of this campaign delivered in the period."},"last_sent_at":{"type":["null","string"],"format":"date-time","description":"Last email of this campaign delivered in the period."},"sent":{"type":"integer","description":"Emails handed to recipients' mail servers: delivered plus bounced. Rejections are not included."},"delivered":{"type":"integer","description":"Emails accepted by the recipient's mail server."},"bounces":{"type":"integer","description":"Emails the recipient's mail server refused, for example because the address does not exist."},"rejections":{"type":"integer","description":"Emails our servers refused to accept from your sending system, for example because they failed a sending policy check. These were never sent."},"opens":{"type":"integer","description":"Recipients who opened the email at least once."},"clicks":{"type":"integer","description":"Recipients who clicked at least one link."},"unsubscribes":{"type":"integer","description":"Recipients who unsubscribed."},"delivery_rate":{"type":["null","number"],"description":"Delivered ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"bounce_rate":{"type":["null","number"],"description":"Bounces ÷ sent. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"open_rate":{"type":["null","number"],"description":"Opens ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_rate":{"type":["null","number"],"description":"Clicks ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"click_to_open_rate":{"type":["null","number"],"description":"Clicks ÷ opens. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."},"unsubscribe_rate":{"type":["null","number"],"description":"Unsubscribes ÷ delivered. Percentage, 0–100, rounded to 2 decimals. Null when there is nothing to divide by."}},"required":["subject","first_sent_at","last_sent_at","sent","delivered","bounces","rejections","opens","clicks","unsubscribes","delivery_rate","bounce_rate","open_rate","click_rate","click_to_open_rate","unsubscribe_rate"]},"bounce_reasons":{"type":"array","description":"Why emails bounced, most common first. See \"Bounce reasons\" for what each reason means and what to do.","items":{"type":"object","properties":{"reason":{"type":"string","description":"Reason id.","examples":["invalid_recipient"]},"label":{"type":"string","description":"Short explanation.","examples":["Mailbox does not exist"]},"kind":{"type":"string","enum":["permanent","temporary","not_sent","mixed"],"description":"`permanent`: remove the address. `temporary`: the receiving server may accept it later. `not_sent`: refused before sending. `mixed`: depends on the case."},"count":{"type":"integer","examples":[12]}},"required":["reason","label","kind","count"]}},"links":{"type":["null","array"],"description":"Each link in the email, most clicked first. Null when per-link data is not available for this period.","items":{"type":"object","properties":{"url":{"type":"string","description":"Link address without its query string.","examples":["https://example.com/offer"]},"label":{"type":["null","string"],"description":"Link text, when known.","examples":["Shop now"]},"clicks":{"type":"integer","description":"Total clicks on this link.","examples":[104]},"recipients":{"type":"integer","description":"Recipients who clicked this link.","examples":[87]}},"required":["url","label","clicks","recipients"]}}},"required":["domain","period","bots_excluded","data_as_of","campaign","bounce_reasons","links"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"404":{"description":"The domain is not one of yours, or no campaign with this subject was sent in the period.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of yours, or no campaign with this subject was sent in the period."},"example":{"error":{"code":"not_found","message":"No campaign with this subject was sent from example.com in this period."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/reputation":{"get":{"operationId":"getDomainReputation","summary":"Spam complaints","tags":["Reputation"],"description":"Daily spam complaint signals reported by Gmail and Yahoo for the domain. Mailbox providers use these to decide whether your email reaches the inbox.","parameters":[{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","examples":["example.com"]},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"summary":{"type":"object","properties":{"gmail_spam_rate_latest":{"type":["null","number"],"description":"Share of Gmail recipients who marked your email as spam, as a percentage (Gmail asks senders to stay below 0.3). Gmail publishes it with a delay of one to two days. The most recent value in the period; null when Gmail reported none, which is normal for low volume.","examples":[0.08]},"yahoo_complaints":{"type":"integer","description":"Yahoo and AOL spam complaints in the period.","examples":[3]}},"required":["gmail_spam_rate_latest","yahoo_complaints"]},"days":{"type":"array","description":"One row per day, oldest first.","items":{"type":"object","properties":{"date":{"type":"string","format":"date","examples":["2026-10-01"]},"gmail_spam_rate":{"type":["null","number"],"description":"Share of Gmail recipients who marked your email as spam, as a percentage (Gmail asks senders to stay below 0.3). Gmail publishes it with a delay of one to two days. The latest value Gmail had reported at the start of this day; null when none was available.","examples":[0.08]},"yahoo_complaints":{"type":"integer","description":"Yahoo and AOL recipients who marked your email as spam that day.","examples":[1]}},"required":["date","gmail_spam_rate","yahoo_complaints"]}}},"required":["domain","period","data_as_of","summary","days"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns/opens":{"get":{"operationId":"listCampaignOpens","summary":"Who opened","tags":["Recipients"],"description":"Recipients who opened the campaign, those who opened most often first.\n\nAn unknown subject returns an empty list. Requires an API key with the **recipients:read** permission.","parameters":[{"schema":{"type":"string"},"example":"October newsletter","in":"query","name":"subject","required":true,"description":"The exact subject line of the campaign, as returned by the campaigns list."},{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number, starting at 1."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"page_size","required":false,"description":"Rows per page (max 100)."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"subject":{"type":"string"},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"pagination":{"type":"object","description":"Where this page sits in the full result.","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer","description":"Total rows across all pages."}},"required":["page","page_size","total"]},"recipients":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","description":"Recipient email address.","examples":["jane@example.org"]},"opens":{"type":"integer","description":"How many times they opened it.","examples":[3]}},"required":["email","opens"]}}},"required":["domain","subject","period","bots_excluded","data_as_of","pagination","recipients"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"403":{"description":"This API key does not have access to recipient-level data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"This API key does not have access to recipient-level data."},"example":{"error":{"code":"forbidden_scope","message":"This API key is not allowed to read recipient-level data."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns/clicks":{"get":{"operationId":"listCampaignClicks","summary":"Who clicked","tags":["Recipients"],"description":"Recipients who clicked a link in the campaign, those who clicked most often first.\n\nAn unknown subject returns an empty list. Requires an API key with the **recipients:read** permission.","parameters":[{"schema":{"type":"string"},"example":"October newsletter","in":"query","name":"subject","required":true,"description":"The exact subject line of the campaign, as returned by the campaigns list."},{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"boolean","default":true},"in":"query","name":"exclude_bots","required":false,"description":"Leave out opens and clicks made automatically by security scanners and mail privacy features, so engagement reflects real people. Set to `false` to count every open and click."},{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number, starting at 1."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"page_size","required":false,"description":"Rows per page (max 100)."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"subject":{"type":"string"},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"pagination":{"type":"object","description":"Where this page sits in the full result.","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer","description":"Total rows across all pages."}},"required":["page","page_size","total"]},"recipients":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","description":"Recipient email address.","examples":["jane@example.org"]},"clicks":{"type":"integer","description":"How many times they clicked.","examples":[2]},"links":{"type":["null","array"],"description":"Which links they clicked. Null when per-link data is not available for this period.","items":{"type":"object","properties":{"url":{"type":"string","examples":["https://example.com/offer"]},"label":{"type":["null","string"],"examples":["Shop now"]},"clicks":{"type":"integer","examples":[1]}},"required":["url","label","clicks"]}}},"required":["email","clicks","links"]}}},"required":["domain","subject","period","bots_excluded","data_as_of","pagination","recipients"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"403":{"description":"This API key does not have access to recipient-level data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"This API key does not have access to recipient-level data."},"example":{"error":{"code":"forbidden_scope","message":"This API key is not allowed to read recipient-level data."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns/bounces":{"get":{"operationId":"listCampaignBounces","summary":"Who bounced","tags":["Recipients"],"description":"Recipients whose mail server refused the campaign, with the reason, most bounces first. An address can appear once per reason. Remove addresses whose kind is `permanent` from your list.\n\nAn unknown subject returns an empty list. Requires an API key with the **recipients:read** permission.","parameters":[{"schema":{"type":"string"},"example":"October newsletter","in":"query","name":"subject","required":true,"description":"The exact subject line of the campaign, as returned by the campaigns list."},{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number, starting at 1."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"page_size","required":false,"description":"Rows per page (max 100)."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"subject":{"type":"string"},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"pagination":{"type":"object","description":"Where this page sits in the full result.","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer","description":"Total rows across all pages."}},"required":["page","page_size","total"]},"recipients":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","description":"Recipient email address.","examples":["jane@example.org"]},"reason":{"type":"string","description":"Reason id; see \"Bounce reasons\".","examples":["invalid_recipient"]},"label":{"type":"string","examples":["Mailbox does not exist"]},"kind":{"type":"string","enum":["permanent","temporary","not_sent","mixed"],"description":"`permanent` means remove the address."},"bounces":{"type":"integer","description":"Bounces for this address and reason.","examples":[1]}},"required":["email","reason","label","kind","bounces"]}}},"required":["domain","subject","period","bots_excluded","data_as_of","pagination","recipients"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"403":{"description":"This API key does not have access to recipient-level data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"This API key does not have access to recipient-level data."},"example":{"error":{"code":"forbidden_scope","message":"This API key is not allowed to read recipient-level data."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/domains/{domain}/campaigns/unsubscribes":{"get":{"operationId":"listCampaignUnsubscribes","summary":"Who unsubscribed","tags":["Recipients"],"description":"Recipients who unsubscribed from the campaign, in alphabetical order.\n\nAn unknown subject returns an empty list. Requires an API key with the **recipients:read** permission.","parameters":[{"schema":{"type":"string"},"example":"October newsletter","in":"query","name":"subject","required":true,"description":"The exact subject line of the campaign, as returned by the campaigns list."},{"schema":{"type":"string","format":"date"},"example":"2026-10-01","in":"query","name":"from","required":false,"description":"First day to include, YYYY-MM-DD (UTC). Defaults to 6 days before `to`."},{"schema":{"type":"string","format":"date"},"example":"2026-10-07","in":"query","name":"to","required":false,"description":"Last day to include, YYYY-MM-DD (UTC). Defaults to today. The range can span at most 90 days."},{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number, starting at 1."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"in":"query","name":"page_size","required":false,"description":"Rows per page (max 100)."},{"schema":{"type":"string"},"example":"example.com","in":"path","name":"domain","required":true,"description":"One of your sending domains (the part after @ in your From address)."}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"subject":{"type":"string"},"period":{"type":"object","description":"The days these numbers cover (UTC, both inclusive).","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bots_excluded":{"type":"boolean"},"data_as_of":{"type":"string","format":"date-time","description":"Numbers include activity up to this moment. Recent hours may still change slightly."},"pagination":{"type":"object","description":"Where this page sits in the full result.","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer","description":"Total rows across all pages."}},"required":["page","page_size","total"]},"recipients":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","description":"Recipient email address.","examples":["jane@example.org"]}},"required":["email"]}}},"required":["domain","subject","period","bots_excluded","data_as_of","pagination","recipients"]}}}},"400":{"description":"A parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"A parameter is missing or invalid."},"example":{"error":{"code":"invalid_parameter","message":"The query parameter \"from\" must be a date in YYYY-MM-DD format, for example 2026-10-01."}}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"403":{"description":"This API key does not have access to recipient-level data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"This API key does not have access to recipient-level data."},"example":{"error":{"code":"forbidden_scope","message":"This API key is not allowed to read recipient-level data."}}}}},"404":{"description":"The domain is not one of your sending domains.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The domain is not one of your sending domains."},"example":{"error":{"code":"not_found","message":"example.com is not one of your sending domains."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}},"503":{"description":"Stats are briefly unavailable. Retry after a short wait.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Stats are briefly unavailable. Retry after a short wait."},"example":{"error":{"code":"temporarily_unavailable","message":"Stats are temporarily unavailable. Please try again in a few minutes."}}}}}}}},"/v1/bounce-reasons":{"get":{"operationId":"listBounceReasons","summary":"Bounce reasons","tags":["Reference"],"description":"Every bounce reason the API can return, what it means, and what to do about it.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"bounce_reasons":{"type":"array","items":{"type":"object","properties":{"reason":{"type":"string","description":"Reason id, as used in campaign details.","examples":["invalid_recipient"]},"label":{"type":"string","examples":["Mailbox does not exist"]},"description":{"type":"string","description":"What happened."},"action":{"type":"string","description":"What we recommend you do."},"kind":{"type":"string","enum":["permanent","temporary","not_sent","mixed"],"description":"`permanent`: remove the address. `temporary`: the receiving server may accept it later. `not_sent`: refused before sending. `mixed`: depends on the case."}},"required":["reason","label","description","action","kind"]}}},"required":["bounce_reasons"]}}}},"401":{"description":"The API key is missing, invalid, or revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"The API key is missing, invalid, or revoked."},"example":{"error":{"code":"unauthorized","message":"Missing or invalid API key."}}}}},"429":{"description":"Too many requests in a short time, or the daily request quota is used up.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden_scope","invalid_parameter","not_found","rate_limited","quota_exceeded","temporarily_unavailable","internal_error"],"description":"Stable code you can branch on."},"message":{"type":"string","description":"What went wrong, in plain language."}},"required":["code","message"]}},"required":["error"],"description":"Too many requests in a short time, or the daily request quota is used up."},"example":{"error":{"code":"rate_limited","message":"Too many requests. Please wait a moment and try again."}}}}}}}}},"servers":[{"url":"https://data.inboxpro.io"}],"tags":[{"name":"Account","description":"Check your key and see which domains it can read."},{"name":"Overview","description":"Totals, rates, and daily trends for a sending domain."},{"name":"Campaigns","description":"Performance of each campaign (subject line)."},{"name":"Reputation","description":"Spam complaints reported by Gmail and Yahoo."},{"name":"Recipients","description":"Lists of individual recipients. Needs the recipients:read permission."},{"name":"Reference","description":"Lookup lists used in other responses."}]}