# AgentiSend — every API reference page as Markdown Generated from the route manifest: 195 reference pages, each identical to the Markdown twin served at `.md` and to the HTML served at the same path. Everything else on this site is https://agentisend.com/llms-full.txt. The index is https://agentisend.com/llms.txt. # https://agentisend.com/docs/api/get-account # GET /account This account: lifecycle status, the reason it is in that state, and when it was created. Sandboxed accounts may only send to their own verified domains. ## Request ```bash curl -sS -X GET https://api.agentisend.com/account \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "approval_reason": "example", "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "is_review_account": false, "name": "example", "onboarding": { "checklist_dismissed_at": "2026-09-04T09:14:00.000Z", "company": "example", "completed_at": "2026-09-04T09:14:00.000Z", "connect_agent_moment_due": false, "contact_name": "example", "expected_volume": "under_30k", "use_cases": [], "website": "example", "website_domain": "example" }, "onboarding_sender": { "from": "example" }, "postal_address": "example", "status": "sandboxed" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/account', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/account' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: accounts. Generated from `openapi.json`; the anchor `get-account` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `approval_reason` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `is_review_account` | `boolean` | yes | | | `name` | `string` | yes | | | `onboarding` | `object` | yes | | | `onboarding.checklist_dismissed_at` | `string \| null` | yes | | | `onboarding.company` | `string` | yes | | | `onboarding.completed_at` | `string \| null` | yes | | | `onboarding.connect_agent_moment_due` | `boolean` | yes | | | `onboarding.contact_name` | `string \| null` | yes | | | `onboarding.expected_volume` | `"under_30k" \| "30k_100k" \| "100k_1m" \| "over_1m" \| null` | yes | | | `onboarding.use_cases` | `array<"transactional" \| "product_lifecycle" \| "ai_agents">` | yes | | | `onboarding.website` | `string \| null` | yes | | | `onboarding.website_domain` | `string \| null` | yes | | | `onboarding_sender` | `object \| null` | yes | | | `postal_address` | `string \| null` | yes | | | `status` | `"sandboxed" \| "approved" \| "suspended"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. --- Source: https://agentisend.com/docs/api/get-account — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-account # PATCH /account Change account settings. postal_address is the sender address printed in every broadcast footer; a broadcast is not sent until it is set. null clears it. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/account \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"postal_address":"example"}' ``` ```json Response 200 { "approval_reason": "example", "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "is_review_account": false, "name": "example", "onboarding": { "checklist_dismissed_at": "2026-09-04T09:14:00.000Z", "company": "example", "completed_at": "2026-09-04T09:14:00.000Z", "connect_agent_moment_due": false, "contact_name": "example", "expected_volume": "under_30k", "use_cases": [], "website": "example", "website_domain": "example" }, "onboarding_sender": { "from": "example" }, "postal_address": "example", "status": "sandboxed" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/account', body: { "postal_address": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/account' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"postal_address":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: accounts. Generated from `openapi.json`; the anchor `patch-account` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `postal_address` | `string \| null` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `approval_reason` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `is_review_account` | `boolean` | yes | | | `name` | `string` | yes | | | `onboarding` | `object` | yes | | | `onboarding.checklist_dismissed_at` | `string \| null` | yes | | | `onboarding.company` | `string` | yes | | | `onboarding.completed_at` | `string \| null` | yes | | | `onboarding.connect_agent_moment_due` | `boolean` | yes | | | `onboarding.contact_name` | `string \| null` | yes | | | `onboarding.expected_volume` | `"under_30k" \| "30k_100k" \| "100k_1m" \| "over_1m" \| null` | yes | | | `onboarding.use_cases` | `array<"transactional" \| "product_lifecycle" \| "ai_agents">` | yes | | | `onboarding.website` | `string \| null` | yes | | | `onboarding.website_domain` | `string \| null` | yes | | | `onboarding_sender` | `object \| null` | yes | | | `postal_address` | `string \| null` | yes | | | `status` | `"sandboxed" \| "approved" \| "suspended"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-account — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-account # DELETE /account Close this account: keys stop now. Everything on the account is deleted after the retention window. Unused prepaid time is refunded. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/account \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "closed_at": "2026-09-04T09:14:00.000Z", "data_removed_after": "2026-09-04T09:14:00.000Z", "keys_revoked": -9007199254740991, "retention_days": -9007199254740991, "status": "suspended" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/account', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/account' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: accounts. Generated from `openapi.json`; the anchor `delete-account` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `closed_at` | `string` | yes | | | `data_removed_after` | `string` | yes | | | `keys_revoked` | `integer` | yes | | | `retention_days` | `integer` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-account — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-account-export # GET /account/export Everything this account owns, as a zip: emails.csv (inside your retention window), suppressions.csv, domains.json and contacts.csv. No job, no wait. ## Request ```bash curl -sS -X GET https://api.agentisend.com/account/export \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/account/export', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/account/export' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: accounts. Generated from `openapi.json`; the anchor `get-account-export` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. --- Source: https://agentisend.com/docs/api/get-account-export — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-account-onboarding # PATCH /account/onboarding Console: the onboarding answers — your name, the company (which becomes the account name), the website, what you will send and roughly how much. Send completed: true to finish; only your name is required. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/account/onboarding \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "approval_reason": "example", "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "is_review_account": false, "name": "example", "onboarding": { "checklist_dismissed_at": "2026-09-04T09:14:00.000Z", "company": "example", "completed_at": "2026-09-04T09:14:00.000Z", "connect_agent_moment_due": false, "contact_name": "example", "expected_volume": "under_30k", "use_cases": [], "website": "example", "website_domain": "example" }, "onboarding_sender": { "from": "example" }, "postal_address": "example", "status": "sandboxed" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/account/onboarding', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/account/onboarding' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: accounts. Generated from `openapi.json`; the anchor `patch-account-onboarding` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `company` | `string` | no | | | `completed` | `boolean` | no | | | `contact_name` | `string` | no | | | `dismiss_checklist` | `boolean` | no | | | `dismiss_connect_agent_moment` | `boolean` | no | | | `expected_volume` | `"under_30k" \| "30k_100k" \| "100k_1m" \| "over_1m" \| null` | no | | | `use_cases` | `array<"transactional" \| "product_lifecycle" \| "ai_agents">` | no | | | `website` | `string \| null` | no | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `approval_reason` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `is_review_account` | `boolean` | yes | | | `name` | `string` | yes | | | `onboarding` | `object` | yes | | | `onboarding.checklist_dismissed_at` | `string \| null` | yes | | | `onboarding.company` | `string` | yes | | | `onboarding.completed_at` | `string \| null` | yes | | | `onboarding.connect_agent_moment_due` | `boolean` | yes | | | `onboarding.contact_name` | `string \| null` | yes | | | `onboarding.expected_volume` | `"under_30k" \| "30k_100k" \| "100k_1m" \| "over_1m" \| null` | yes | | | `onboarding.use_cases` | `array<"transactional" \| "product_lifecycle" \| "ai_agents">` | yes | | | `onboarding.website` | `string \| null` | yes | | | `onboarding.website_domain` | `string \| null` | yes | | | `onboarding_sender` | `object \| null` | yes | | | `postal_address` | `string \| null` | yes | | | `status` | `"sandboxed" \| "approved" \| "suspended"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-account-onboarding — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-agent-actions # GET /agent-actions Every held agent action, newest first — nothing waits invisibly. Filter by state to read the inbox or the audit trail. ## Request ```bash curl -sS -X GET https://api.agentisend.com/agent-actions \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/agent-actions', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/agent-actions' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: agent-actions. Generated from `openapi.json`; the anchor `get-agent-actions` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `state` query · `"pending" | "approved" | "rejected" | "killed"` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].decided_at` | `string \| null` | yes | | | `data[].decided_by` | `string \| null` | yes | | | `data[].decision_reason` | `string \| null` | yes | | | `data[].expires_at` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].kind` | `string` | yes | | | `data[].payload` | `object` | yes | | | `data[].preview` | `object` | yes | | | `data[].state` | `"pending" \| "approved" \| "rejected" \| "killed"` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-agent-actions — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-agent-actions-id-approve # POST /agent-actions/{id}/approve Execute the held send through the normal accept path. A person signed in to the console decides; the action row records who and when. ## Request ```bash curl -sS -X POST https://api.agentisend.com/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/approve \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "action": { "created_at": "2026-09-04T09:14:00.000Z", "decided_at": "2026-09-04T09:14:00.000Z", "decided_by": "example", "decision_reason": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "kind": "example", "payload": {}, "preview": { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "first_recipients": [], "held_reason": "example", "html": "example", "subject": "example", "text": "example", "to_count": 0 }, "state": "pending" }, "message_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "status": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/approve', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/approve' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: agent-actions. Generated from `openapi.json`; the anchor `post-agent-actions-id-approve` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `402` — A budget, quota or plan limit would be exceeded. Codes: overage_cap_reached, daily_limit_reached, agent_budget_exceeded, plan_limit_reached. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `action` | `object` | yes | | | `action.created_at` | `string` | yes | | | `action.decided_at` | `string \| null` | yes | | | `action.decided_by` | `string \| null` | yes | | | `action.decision_reason` | `string \| null` | yes | | | `action.expires_at` | `string \| null` | yes | | | `action.id` | `string` | yes | | | `action.kind` | `string` | yes | | | `action.payload` | `object` | yes | | | `action.preview` | `object` | yes | | | `action.state` | `"pending" \| "approved" \| "rejected" \| "killed"` | yes | | | `message_id` | `string` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`account_sandboxed`](https://agentisend.com/docs/errors#account_sandboxed) (403) — This account is in the sandbox and may only send to its own verified domains. **Fix:** Verify the recipient domain with POST /domains + POST /domains/:id/verify, or file POST /trust/appeal for a person to review this account. - [`account_suspended`](https://agentisend.com/docs/errors#account_suspended) (403) — This account is suspended. **Fix:** Read the enforcement policy at https://agentisend.com/policy/enforcement, then contact hello@agentisend.com to appeal. - [`agent_budget_exceeded`](https://agentisend.com/docs/errors#agent_budget_exceeded) (402) — Key budget for the current period is exhausted. **Fix:** Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own. - [`approval_expired`](https://agentisend.com/docs/errors#approval_expired) (409) — This hold has expired, so it cannot be approved. **Fix:** Send the message again if it should still go out. A hold lasts 24 hours unless the send named an earlier time. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`daily_limit_reached`](https://agentisend.com/docs/errors#daily_limit_reached) (402) — This account has sent its daily allowance of emails; sending resumes at 00:00 UTC. **Fix:** Wait for 00:00 UTC, or upgrade in Settings → Billing — every paid plan has no daily cap. - [`domain_not_verified`](https://agentisend.com/docs/errors#domain_not_verified) (403) — This sending domain is not verified. **Fix:** If it is pending, publish the required records from GET /domains/:id; checks continue for 72 hours. Test now by sending to an address ending in @simulator.agentisend.com. If it is not registered, POST /domains first. If it is failed, GET /domains/:id names the record to fix, then POST /domains/:id/verify to reopen the window. - [`domain_scope_violation`](https://agentisend.com/docs/errors#domain_scope_violation) (403) — This API key may only send from its scoped domain. **Fix:** Send from the scoped domain, or create a key without a domain scope via POST /api-keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_attachment`](https://agentisend.com/docs/errors#invalid_attachment) (422, invalid_attachment) — Each attachment needs content (base64) or path. **Fix:** Provide attachment.content or attachment.path in POST /emails. - [`invalid_from_address`](https://agentisend.com/docs/errors#invalid_from_address) (422, invalid_from_address) — The from field is not a valid address. **Fix:** Use a plain address or "Name " format in POST /emails. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`kill_switch_active`](https://agentisend.com/docs/errors#kill_switch_active) (403) — This API key has been paused with the kill switch. **Fix:** Read GET /trust/standing for why it was paused. Only a person signed in to the console can resume it; the paused key cannot resume itself. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`onboarding_daily_cap_reached`](https://agentisend.com/docs/errors#onboarding_daily_cap_reached) (429) — This account has used its 20 onboarding emails for today. **Fix:** Wait until tomorrow (UTC), or verify a domain with POST /domains and send from that domain. - [`onboarding_recipient_not_a_member`](https://agentisend.com/docs/errors#onboarding_recipient_not_a_member) (403) — The onboarding sender can only mail this account's own members — the addresses they sign in with. **Fix:** Send to a member sign-in address, or verify a domain with POST /domains and send from that domain. - [`onboarding_sender_unavailable`](https://agentisend.com/docs/errors#onboarding_sender_unavailable) (403) — The onboarding sender is not available. **Fix:** Send to an address ending in @simulator.agentisend.com, or verify a domain with POST /domains and send from that domain. - [`onboarding_shape_refused`](https://agentisend.com/docs/errors#onboarding_shape_refused) (422) — The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers. **Fix:** Omit those fields, or verify a domain with POST /domains and send from that domain. - [`overage_cap_reached`](https://agentisend.com/docs/errors#overage_cap_reached) (402) — This account has used every email in its plan and every extra email its owner allowed this period. **Fix:** Raise the overage ceiling or move up a plan in Settings → Billing, or wait until the reset date in this error. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_limit_reached`](https://agentisend.com/docs/errors#plan_limit_reached) (402) — This account has used every email included in its plan for the current period. **Fix:** Upgrade in Settings → Billing, or wait until the reset date in this error. - [`rate_ceiling_exceeded`](https://agentisend.com/docs/errors#rate_ceiling_exceeded) (429) — Per-minute rate ceiling for this key is exhausted. **Fix:** Wait the seconds below and send the same request again. Raising the ceiling is a person’s decision, made in the console; a key cannot raise its own. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`recipient_blocklisted`](https://agentisend.com/docs/errors#recipient_blocklisted) (422) — This recipient is blocked. **Fix:** Send to a different address. An address ending in @simulator.agentisend.com is never blocked. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_paused_everywhere`](https://agentisend.com/docs/errors#sending_paused_everywhere) (503) — Sending is paused for every account while AgentiSend handles an incident. Nothing was sent or charged. **Fix:** Retry the same request, with the same Idempotency-Key, after the seconds given in Retry-After. Scheduled sends wait and go out once sending resumes. - [`suppressed_recipient`](https://agentisend.com/docs/errors#suppressed_recipient) (422) — Recipient is on the account suppression list. **Fix:** GET /suppressions says which address and why. A hard bounce you have fixed can be cleared with DELETE /suppressions/:id; an unsubscribe or a spam complaint cannot — that address asked not to be contacted. - [`trust_paused`](https://agentisend.com/docs/errors#trust_paused) (403) — Sending is paused by the trust system. **Fix:** Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal. - [`trust_throttled`](https://agentisend.com/docs/errors#trust_throttled) (429) — This account is being throttled by the trust ladder. **Fix:** Send volume is temporarily capped because deliverability metrics crossed a published threshold. Check GET /trust/standing for the metric and value, file POST /trust/appeal if this is unexpected. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-agent-actions-id-approve — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-agent-actions-id-reject # POST /agent-actions/{id}/reject Refuse the held send. A person signed in to the console decides; the reason is preserved with the row. ## Request ```bash curl -sS -X POST https://api.agentisend.com/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reject \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "decided_at": "2026-09-04T09:14:00.000Z", "decided_by": "example", "decision_reason": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "kind": "example", "payload": {}, "preview": { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "first_recipients": [], "held_reason": "example", "html": "example", "subject": "example", "text": "example", "to_count": 0 }, "state": "pending" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reject', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/agent-actions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reject' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: agent-actions. Generated from `openapi.json`; the anchor `post-agent-actions-id-reject` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `reason` | `string` | no | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `decided_at` | `string \| null` | yes | | | `decided_by` | `string \| null` | yes | | | `decision_reason` | `string \| null` | yes | | | `expires_at` | `string \| null` | yes | | | `id` | `string` | yes | | | `kind` | `string` | yes | | | `payload` | `object` | yes | | | `preview` | `object` | yes | | | `preview.api_key_id` | `string \| null` | yes | | | `preview.first_recipients` | `array` | yes | | | `preview.held_reason` | `string \| null` | yes | | | `preview.html` | `string \| null` | yes | | | `preview.subject` | `string` | yes | | | `preview.text` | `string \| null` | yes | | | `preview.to_count` | `integer` | yes | | | `state` | `"pending" \| "approved" \| "rejected" \| "killed"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-agent-actions-id-reject — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-api-keys # GET /api-keys List API keys with 30-day request counts. Permission, domain scope and the key’s own budget ceiling are always returned; never the token. ## Request ```bash curl -sS -X GET https://api.agentisend.com/api-keys \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/api-keys', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/api-keys' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: api-keys. Generated from `openapi.json`; the anchor `get-api-keys` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].budget_per_period` | `integer \| null` | yes | | | `data[].created_at` | `string` | yes | | | `data[].domain_scope` | `string \| null` | yes | | | `data[].expires_at` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_used_at` | `string \| null` | yes | | | `data[].loop_guard` | `"off" \| "repetition-only" \| "full"` | yes | | | `data[].name` | `string` | yes | | | `data[].period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `data[].permission` | `"full_access" \| "sending_access"` | yes | | | `data[].previous_key_expires_at` | `string \| null` | yes | | | `data[].rate_ceiling_per_minute` | `integer \| null` | yes | | | `data[].request_count_30d` | `integer` | yes | | | `data[].rotated_at` | `string \| null` | yes | | | `data[].scopes` | `array` | yes | | | `data[].system` | `boolean` | yes | | | `data[].token_prefix` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-api-keys — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-api-keys # POST /api-keys Create an API key. The token is shown exactly once. ## Request ```bash curl -sS -X POST https://api.agentisend.com/api-keys \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"example","permission":"full_access"}' ``` ```json Response 201 { "budget_per_period": 1000, "created_at": "2026-09-04T09:14:00.000Z", "domain_scope": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_used_at": "2026-09-04T09:14:00.000Z", "loop_guard": "off", "name": "example", "period": "monthly", "permission": "full_access", "previous_key_expires_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": 600, "request_count_30d": -9007199254740991, "rotated_at": "2026-09-04T09:14:00.000Z", "scopes": [], "system": false, "token": "as_abababababababababababababababababababababababababababababababab", "token_prefix": "as_abababab" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/api-keys', body: { "name": "example", "permission": "full_access" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/api-keys' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"example","permission":"full_access"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: api-keys. Generated from `openapi.json`; the anchor `post-api-keys` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `domain_scope` | `string \| null` | no | Limit the key to one domain on this account. Omit it to allow every domain. | | `loop_guard` | `"off" \| "repetition-only" \| "full"` | no | off watches nothing. repetition-only watches near-identical sends. full also watches recipient collapse. Omit it and transactional sends use repetition-only; a marketing send on a key with no setting still uses full. | | `name` | `string` | yes | A name you will recognise in the key list. | | `permission` | `"full_access" \| "sending_access"` | yes | full_access can manage the account. sending_access can send. | | `scopes` | `array<"emails:send" \| "emails:read" \| "domains:read" \| "domains:write" \| "webhooks:read" \| "webhooks:write" \| "limits:read" \| "limits:write" \| "trust:read" \| "contacts:read" \| "contacts:write" \| "suppressions:read" \| "suppressions:write" \| "templates:read" \| "templates:write" \| "segments:read" \| …>` | no | Narrow what the key can call. Omit it and the permission decides. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `budget_per_period` | `integer \| null` | yes | | | `created_at` | `string` | yes | | | `domain_scope` | `string \| null` | yes | | | `expires_at` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_used_at` | `string \| null` | yes | | | `loop_guard` | `"off" \| "repetition-only" \| "full"` | yes | | | `name` | `string` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `permission` | `"full_access" \| "sending_access"` | yes | | | `previous_key_expires_at` | `string \| null` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `request_count_30d` | `integer` | yes | | | `rotated_at` | `string \| null` | yes | | | `scopes` | `array` | yes | | | `system` | `boolean` | yes | | | `token` | `string` | yes | | | `token_prefix` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-api-keys — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-api-keys-id # PATCH /api-keys/{id} Rename a key or change its domain scope and scopes. The token is unchanged — use POST /api-keys/:id/rotate for that. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"agent"}' ``` ```json Response 200 { "budget_per_period": -9007199254740991, "created_at": "2026-09-04T09:14:00.000Z", "domain_scope": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_used_at": "2026-09-04T09:14:00.000Z", "loop_guard": "off", "name": "example", "period": "hourly", "permission": "full_access", "previous_key_expires_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "request_count_30d": -9007199254740991, "rotated_at": "2026-09-04T09:14:00.000Z", "scopes": [], "system": false, "token_prefix": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "name": "agent" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"agent"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: api-keys. Generated from `openapi.json`; the anchor `patch-api-keys-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `domain_scope` | `string \| null` | no | Limit the key to one domain, or null to allow every domain. | | `loop_guard` | `"off" \| "repetition-only" \| "full"` | no | off watches nothing. repetition-only watches near-identical sends. full also watches recipient collapse. Omit it and transactional sends use repetition-only; a marketing send on a key with no setting still uses full. | | `name` | `string` | no | A new name. Omit it to keep the current one. | | `scopes` | `array<"emails:send" \| "emails:read" \| "domains:read" \| "domains:write" \| "webhooks:read" \| "webhooks:write" \| "limits:read" \| "limits:write" \| "trust:read" \| "contacts:read" \| "contacts:write" \| "suppressions:read" \| "suppressions:write" \| "templates:read" \| "templates:write" \| "segments:read" \| …>` | no | Replace the scope list. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `budget_per_period` | `integer \| null` | yes | | | `created_at` | `string` | yes | | | `domain_scope` | `string \| null` | yes | | | `expires_at` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_used_at` | `string \| null` | yes | | | `loop_guard` | `"off" \| "repetition-only" \| "full"` | yes | | | `name` | `string` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `permission` | `"full_access" \| "sending_access"` | yes | | | `previous_key_expires_at` | `string \| null` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `request_count_30d` | `integer` | yes | | | `rotated_at` | `string \| null` | yes | | | `scopes` | `array` | yes | | | `system` | `boolean` | yes | | | `token_prefix` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-api-keys-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-api-keys-id # DELETE /api-keys/{id} Revoke an API key immediately. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: api-keys. Generated from `openapi.json`; the anchor `delete-api-keys-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-api-keys-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-api-keys-id-rotate # POST /api-keys/{id}/rotate Rotate an API key. The new token is returned once; the token it replaces keeps working for grace_hours (0, 1 or 24). ## Request ```bash curl -sS -X POST https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"grace_hours":0}' ``` ```json Response 200 { "budget_per_period": -9007199254740991, "created_at": "2026-09-04T09:14:00.000Z", "domain_scope": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_used_at": "2026-09-04T09:14:00.000Z", "loop_guard": "off", "name": "example", "period": "hourly", "permission": "full_access", "previous_key_expires_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "request_count_30d": -9007199254740991, "rotated_at": "2026-09-04T09:14:00.000Z", "scopes": [], "system": false, "token": "example", "token_prefix": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate', body: { "grace_hours": 0 }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"grace_hours":0}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: api-keys. Generated from `openapi.json`; the anchor `post-api-keys-id-rotate` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `grace_hours` | `number \| number \| number` | yes | How long the previous token keeps working: 0, 1 or 24 hours. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `budget_per_period` | `integer \| null` | yes | | | `created_at` | `string` | yes | | | `domain_scope` | `string \| null` | yes | | | `expires_at` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_used_at` | `string \| null` | yes | | | `loop_guard` | `"off" \| "repetition-only" \| "full"` | yes | | | `name` | `string` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `permission` | `"full_access" \| "sending_access"` | yes | | | `previous_key_expires_at` | `string \| null` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `request_count_30d` | `integer` | yes | | | `rotated_at` | `string \| null` | yes | | | `scopes` | `array` | yes | | | `system` | `boolean` | yes | | | `token` | `string` | yes | | | `token_prefix` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-api-keys-id-rotate — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-audiences-audienceid-contacts # GET /audiences/{audienceId}/contacts Alias of GET /contacts. The audience id is accepted and does not select another list. ## Request ```bash curl -sS -X GET https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-audiences-audienceid-contacts` is the id the console's error `fix` links point at. ## Parameters - `audienceId` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `email` query · `string` · optional - `q` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].first_name` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_name` | `string \| null` | yes | | | `data[].object` | `string` | yes | | | `data[].properties` | `object` | yes | | | `data[].property_types` | `object` | yes | | | `data[].status` | `string` | yes | | | `data[].unsubscribed` | `boolean` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-audiences-audienceid-contacts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-audiences-audienceid-contacts # POST /audiences/{audienceId}/contacts Alias of POST /contacts. This account has one contact list, so the audience id does not select another. ## Request ```bash curl -sS -X POST https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"customer@example.com"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts', body: { "email": "customer@example.com" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"email":"customer@example.com"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-audiences-audienceid-contacts` is the id the console's error `fix` links point at. ## Parameters - `audienceId` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | yes | The contact address. An existing address is updated. | | `first_name` | `string \| null` | no | Given name. Null clears it. | | `last_name` | `string \| null` | no | Family name. Null clears it. | | `properties` | `object` | no | Named values stored on the contact. A new name is created. | | `status` | `"active" \| "unsubscribed"` | no | active, or unsubscribed to stop marketing mail. | | `unsubscribed` | `boolean` | no | true stops marketing mail to this address. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`contact_resubscribe_required`](https://agentisend.com/docs/errors#contact_resubscribe_required) (409) — This address asked not to be contacted, so marking the contact active leaves that in place. **Fix:** POST /contacts/:id/resubscribe with consent_source and consent_at after the person opts back in. The id can be the contact id or the email address. A spam report is not lifted by that call. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-audiences-audienceid-contacts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-audiences-audienceid-contacts-id # GET /audiences/{audienceId}/contacts/{id} Alias of GET /contacts/{id}. ## Request ```bash curl -sS -X GET https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-audiences-audienceid-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `audienceId` path · `string` · required - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-audiences-audienceid-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-audiences-audienceid-contacts-id # PATCH /audiences/{audienceId}/contacts/{id} Alias of PATCH /contacts/{id}. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"properties":{"plan":"starter"}}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "properties": { "plan": "starter" } }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"properties":{"plan":"starter"}}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `patch-audiences-audienceid-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `audienceId` path · `string` · required - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | no | A new address for this contact. | | `first_name` | `string \| null` | no | Given name. Null clears it. | | `last_name` | `string \| null` | no | Family name. Null clears it. | | `properties` | `object` | no | Values to merge. Null removes that property. | | `status` | `"active" \| "unsubscribed"` | no | active, or unsubscribed to stop marketing mail. | | `unsubscribed` | `boolean` | no | true stops marketing mail to this address. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`contact_resubscribe_required`](https://agentisend.com/docs/errors#contact_resubscribe_required) (409) — This address asked not to be contacted, so marking the contact active leaves that in place. **Fix:** POST /contacts/:id/resubscribe with consent_source and consent_at after the person opts back in. The id can be the contact id or the email address. A spam report is not lifted by that call. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-audiences-audienceid-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-audiences-audienceid-contacts-id # DELETE /audiences/{audienceId}/contacts/{id} Alias of DELETE /contacts/{id}. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "contact": "example", "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "object": "contact" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audiences/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `delete-audiences-audienceid-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `audienceId` path · `string` · required - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `contact` | `string` | yes | | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-audiences-audienceid-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-audit-log # GET /audit-log Every change anyone made on this account (keys, kill switch, domains, approvals, team, settings), with what it looked like before. Newest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/audit-log \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/audit-log', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/audit-log' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: audit. Generated from `openapi.json`; the anchor `get-audit-log` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `actor` query · `string` · optional - `action` query · `string` · optional - `from` query · `string` · optional - `to` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].account_id` | `string \| null` | yes | | | `data[].action` | `string` | yes | | | `data[].actor_email` | `string \| null` | yes | | | `data[].actor_id` | `string \| null` | yes | | | `data[].actor_type` | `string` | yes | | | `data[].actor_user_id` | `string \| null` | yes | | | `data[].after` | `object` | yes | | | `data[].before` | `object` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].reason` | `string \| null` | yes | | | `data[].target_id` | `string \| null` | yes | | | `data[].target_type` | `string \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-audit-log — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-automations # GET /automations Every automation on the account. ## Request ```bash curl -sS -X GET https://api.agentisend.com/automations \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/automations', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-automations` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].current_version` | `integer` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].status` | `string` | yes | | | `data[].steps` | `array` | yes | | | `data[].trigger` | `object` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-automations — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-automations # POST /automations Draft an automation: a trigger plus ordered steps (email, webhook, A/B split). ## Request ```bash curl -sS -X POST https://api.agentisend.com/automations \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"yourdomain.com","steps":[{"kind":"email","from_address":"billing@yourdomain.com","subject":"Your receipt","content":{"mode":"markdown","source":"Thanks — the details are attached."}}],"trigger":{"type":"contact.created"}}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "current_version": -9007199254740991, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "example", "steps": [], "trigger": { "event_name": "order.paid", "type": "custom_event" }, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/automations', body: { "name": "yourdomain.com", "steps": [ { "kind": "email", "from_address": "billing@yourdomain.com", "subject": "Your receipt", "content": { "mode": "markdown", "source": "Thanks — the details are attached." } } ], "trigger": { "type": "contact.created" } }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"yourdomain.com","steps":[{"kind":"email","from_address":"billing@yourdomain.com","subject":"Your receipt","content":{"mode":"markdown","source":"Thanks — the details are attached."}}],"trigger":{"type":"contact.created"}}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `post-automations` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version` | `integer` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-automations — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-automations-id # GET /automations/{id} One automation. ## Request ```bash curl -sS -X GET https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version": -9007199254740991, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "example", "steps": [], "trigger": { "event_name": "order.paid", "type": "custom_event" }, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-automations-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version` | `integer` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-automations-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-automations-id # PATCH /automations/{id} Edit a draft or disabled automation. Enabling snapshots a version — a running automation never executes a half-edited definition. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version": -9007199254740991, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "example", "steps": [], "trigger": { "event_name": "order.paid", "type": "custom_event" }, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `patch-automations-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | `string` | no | | | `steps` | `array` | no | | | `trigger` | `object` | no | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version` | `integer` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-automations-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-automations-id-disable # POST /automations/{id}/disable Stop firing. Versions stay for audit. ## Request ```bash curl -sS -X POST https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/disable \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version": -9007199254740991, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "example", "steps": [], "trigger": { "event_name": "order.paid", "type": "custom_event" }, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/disable', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/disable' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `post-automations-id-disable` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version` | `integer` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-automations-id-disable — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-automations-id-enable # POST /automations/{id}/enable Snapshot trigger+steps as an immutable version and start firing. ## Request ```bash curl -sS -X POST https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/enable \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version": -9007199254740991, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "example", "steps": [], "trigger": { "event_name": "order.paid", "type": "custom_event" }, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/enable', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/enable' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `post-automations-id-enable` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version` | `integer` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `string` | yes | | | `steps` | `array` | yes | | | `trigger` | `object` | yes | | | `trigger.event_name` | `string` | no | | | `trigger.interval_minutes` | `integer` | no | | | `trigger.segment_id` | `string` | no | | | `trigger.type` | `"custom_event" \| "contact.created" \| "contact.updated" \| "segment.joined" \| "segment.left" \| "scheduled"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-automations-id-enable — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-automations-id-runs # GET /automations/{id}/runs Every time this automation fired, newest first — the answer to "did it run?", which the engine used to throw away. ## Request ```bash curl -sS -X GET https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-automations-id-runs` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `status` query · `"running" | "succeeded" | "failed"` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].automation_id` | `string` | yes | | | `data[].contact_id` | `string \| null` | yes | | | `data[].event_name` | `string \| null` | yes | | | `data[].finished_at` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].started_at` | `string` | yes | | | `data[].status` | `"running" \| "succeeded" \| "failed"` | yes | | | `data[].steps` | `array` | no | | | `data[].trigger_type` | `string` | yes | | | `data[].version_number` | `integer \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-automations-id-runs — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-automations-id-runs-run-id # GET /automations/{id}/runs/{run_id} One run with every step: what it did, what it returned, and the sentence for the ones that failed. ## Request ```bash curl -sS -X GET https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "automation_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "contact_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "event_name": "example", "finished_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "started_at": "2026-09-04T09:14:00.000Z", "status": "running", "trigger_type": "example", "version_number": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/runs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-automations-id-runs-run-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `run_id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `automation_id` | `string` | yes | | | `contact_id` | `string \| null` | yes | | | `event_name` | `string \| null` | yes | | | `finished_at` | `string \| null` | yes | | | `id` | `string` | yes | | | `started_at` | `string` | yes | | | `status` | `"running" \| "succeeded" \| "failed"` | yes | | | `steps` | `array` | no | | | `steps[].error` | `string \| null` | yes | | | `steps[].finished_at` | `string \| null` | yes | | | `steps[].index` | `integer` | yes | | | `steps[].kind` | `string` | yes | | | `steps[].output` | `object \| null` | yes | | | `steps[].started_at` | `string` | yes | | | `steps[].status` | `"succeeded" \| "skipped" \| "failed" \| "waiting"` | yes | | | `trigger_type` | `string` | yes | | | `version_number` | `integer \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-automations-id-runs-run-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-automations-id-versions # GET /automations/{id}/versions Every immutable version, oldest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/automations/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-automations-id-versions` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].steps` | `array` | yes | | | `data[].trigger` | `object` | yes | | | `data[].version_number` | `integer` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-automations-id-versions — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-billing # GET /billing Plan, usage against each published limit, and what the next tier changes. ## Request ```bash curl -sS -X GET https://api.agentisend.com/billing \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "currency": "example", "limits": [], "next_tier": { "id": "example", "included_emails_per_month": -9007199254740991, "max_domains": -9007199254740991, "max_seats": -9007199254740991, "monthly_price_minor": -9007199254740991, "name": "example", "overage_minor_per_1000_emails": -9007199254740991, "retention_days": -9007199254740991 }, "overage": { "auto_charges": false, "available": false, "cap_emails": -9007199254740991, "consumed_this_period": -9007199254740991, "enabled": false, "policy": "pause", "rate_minor_per_1000": -9007199254740991, "text": "example" }, "payment": { "text": "example", "writes_enabled": false }, "period": { "days": -9007199254740991, "resets_at": "2026-09-04T09:14:00.000Z", "started_at": "2026-09-04T09:14:00.000Z" }, "plan": { "id": "example", "included_emails_per_month": -9007199254740991, "max_domains": -9007199254740991, "max_seats": -9007199254740991, "monthly_price_minor": -9007199254740991, "name": "example", "overage_minor_per_1000_emails": -9007199254740991, "retention_days": -9007199254740991 }, "pricing_document_version": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/billing', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: usage. Generated from `openapi.json`; the anchor `get-billing` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `currency` | `string` | yes | | | `limits` | `array` | yes | | | `limits[].at_limit` | `string` | yes | | | `limits[].label` | `string` | yes | | | `limits[].limit` | `integer \| null` | yes | | | `limits[].metric` | `"emails_per_month" \| "domains" \| "seats" \| "retention_days"` | yes | | | `limits[].unit` | `string` | yes | | | `limits[].used` | `integer` | yes | | | `next_tier` | `object \| null` | yes | | | `overage` | `object` | yes | | | `overage.auto_charges` | `boolean` | yes | | | `overage.available` | `boolean` | yes | | | `overage.cap_emails` | `integer \| null` | yes | | | `overage.consumed_this_period` | `integer` | yes | | | `overage.enabled` | `boolean` | yes | | | `overage.policy` | `"pause" \| "bill"` | yes | | | `overage.rate_minor_per_1000` | `integer \| null` | yes | | | `overage.text` | `string` | yes | | | `payment` | `object` | yes | | | `payment.text` | `string` | yes | | | `payment.writes_enabled` | `boolean` | yes | | | `period` | `object` | yes | | | `period.days` | `integer` | yes | | | `period.resets_at` | `string` | yes | | | `period.started_at` | `string` | yes | | | `plan` | `object` | yes | | | `plan.id` | `string` | yes | | | `plan.included_emails_per_month` | `integer` | yes | | | `plan.max_domains` | `integer \| null` | yes | | | `plan.max_seats` | `integer` | yes | | | `plan.monthly_price_minor` | `integer` | yes | | | `plan.name` | `string` | yes | | | `plan.overage_minor_per_1000_emails` | `integer \| null` | yes | | | `plan.retention_days` | `integer` | yes | | | `pricing_document_version` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. --- Source: https://agentisend.com/docs/api/get-billing — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-billing-checkout # POST /billing/checkout Console: start a Stripe Checkout for a tier, term and volume. ## Request ```bash curl -sS -X POST https://api.agentisend.com/billing/checkout \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"tier":"starter"}' ``` ```json Response 201 { "checkout_session_id": "example", "url": "https://yourapp.com/hooks/agentisend" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/billing/checkout', body: { "tier": "starter" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/checkout' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"tier":"starter"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `post-billing-checkout` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `included_emails_per_month` | `integer` | no | | | `term` | `"month" \| "year"` | no | | | `tier` | `"starter" \| "pro" \| "scale"` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `checkout_session_id` | `string` | yes | | | `url` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`billing_not_configured`](https://agentisend.com/docs/errors#billing_not_configured) (503) — Purchases are unavailable right now. **Fix:** GET /billing/plan still works, and the account stays on Free. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_not_purchasable`](https://agentisend.com/docs/errors#plan_not_purchasable) (400) — This tier cannot be bought through checkout. **Fix:** Pass one of the tier ids listed under `plans` by GET /billing/plan (starter, pro, scale) to POST /billing/checkout. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`subscription_active`](https://agentisend.com/docs/errors#subscription_active) (409) — This account already has a live subscription. **Fix:** Change plans with POST /billing/portal. The billing portal prorates the change and shows the amount before it is confirmed. Checkout is only for an account with no subscription. - [`term_not_on_sale`](https://agentisend.com/docs/errors#term_not_on_sale) (409) — That billing term is not available to buy yet. **Fix:** Pass one of the terms listed under `terms_on_sale` by GET /billing/plan (monthly and yearly) to POST /billing/checkout. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-billing-checkout — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/put-billing-overage # PUT /billing/overage Console: turn opt-in overage on (with a ceiling of extra emails per period) or off. Owner only; paid plans only. ## Request ```bash curl -sS -X PUT https://api.agentisend.com/billing/overage \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"enabled":false}' ``` ```json Response 200 { "auto_charges": false, "available": false, "cap_emails": -9007199254740991, "consumed_this_period": -9007199254740991, "enabled": false, "policy": "pause", "rate_minor_per_1000": -9007199254740991, "text": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PUT', path: '/billing/overage', body: { "enabled": false }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/overage' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"enabled":false}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PUT') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `put-billing-overage` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `cap_emails` | `integer` | no | | | `enabled` | `boolean` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `auto_charges` | `boolean` | yes | | | `available` | `boolean` | yes | | | `cap_emails` | `integer \| null` | yes | | | `consumed_this_period` | `integer` | yes | | | `enabled` | `boolean` | yes | | | `policy` | `"pause" \| "bill"` | yes | | | `rate_minor_per_1000` | `integer \| null` | yes | | | `text` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`billing_customer_missing`](https://agentisend.com/docs/errors#billing_customer_missing) (404) — This account has no billing customer yet. **Fix:** Start a subscription with POST /billing/checkout first; the customer portal only exists once a checkout has run. - [`billing_not_configured`](https://agentisend.com/docs/errors#billing_not_configured) (503) — Purchases are unavailable right now. **Fix:** GET /billing/plan still works, and the account stays on Free. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`overage_not_on_plan`](https://agentisend.com/docs/errors#overage_not_on_plan) (409) — Overage is available on Starter, Pro and Scale. This account is on Free, which pauses at its inclusion. **Fix:** Choose a paid plan in Settings → Billing, then turn overage on. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/put-billing-overage — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-billing-plan # GET /billing/plan The plan in force (Free until one is bought), the plans, volumes and terms on offer, and what the signed-in person may buy. ## Request ```bash curl -sS -X GET https://api.agentisend.com/billing/plan \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "billing_configured": false, "billing_term": "month", "entitlements": { "included_emails_per_month": -9007199254740991, "max_domains": -9007199254740991, "max_seats": -9007199254740991, "overage_minor_per_1000_emails": -9007199254740991, "retention_days": -9007199254740991, "tier": "free" }, "needs_plan_selection": false, "plan_source": "free", "plan_status": "none", "plans": [], "purchasable": [], "subscription": { "cancel_at_period_end": false, "current_period_end": "2026-09-04T09:14:00.000Z", "price_lookup_key": "example", "status": "example" }, "terms_on_sale": [], "tier": "free", "viewer": { "can_purchase": false, "role": "owner" } } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/billing/plan', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/plan' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `get-billing-plan` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `billing_configured` | `boolean` | yes | | | `billing_term` | `"month" \| "year" \| null` | yes | | | `entitlements` | `object` | yes | | | `entitlements.included_emails_per_month` | `integer` | yes | | | `entitlements.max_domains` | `integer \| null` | yes | | | `entitlements.max_seats` | `integer` | yes | | | `entitlements.overage_minor_per_1000_emails` | `integer \| null` | yes | | | `entitlements.retention_days` | `integer` | yes | | | `entitlements.tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `needs_plan_selection` | `boolean` | yes | | | `plan_source` | `"free" \| "subscription" \| "manual"` | yes | | | `plan_status` | `"none" \| "trialing" \| "active" \| "past_due" \| "canceled"` | yes | | | `plans` | `array` | yes | | | `plans[].featured` | `boolean` | yes | | | `plans[].included_emails_per_month` | `integer` | yes | | | `plans[].max_domains` | `integer \| null` | yes | | | `plans[].max_seats` | `integer` | yes | | | `plans[].name` | `string` | yes | | | `plans[].prices` | `object` | yes | | | `plans[].retention_days` | `integer` | yes | | | `plans[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `plans[].volume_rungs` | `array` | yes | | | `purchasable` | `array` | yes | | | `purchasable[].included_emails_per_month` | `integer` | yes | | | `purchasable[].monthly_price_minor` | `integer` | yes | | | `purchasable[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `subscription` | `object \| null` | yes | | | `terms_on_sale` | `array<"month" \| "year">` | yes | | | `tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `viewer` | `object` | yes | | | `viewer.can_purchase` | `boolean` | yes | | | `viewer.role` | `"owner" \| "admin" \| "viewer" \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. --- Source: https://agentisend.com/docs/api/get-billing-plan — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-billing-plan # POST /billing/plan Console: choose Free on the plan step. Paid plans go through POST /billing/checkout. Idempotent; owner only. ## Request ```bash curl -sS -X POST https://api.agentisend.com/billing/plan \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"tier":"free"}' ``` ```json Response 201 { "billing_configured": false, "billing_term": "month", "entitlements": { "included_emails_per_month": -9007199254740991, "max_domains": -9007199254740991, "max_seats": -9007199254740991, "overage_minor_per_1000_emails": -9007199254740991, "retention_days": -9007199254740991, "tier": "free" }, "needs_plan_selection": false, "plan_source": "free", "plan_status": "none", "plans": [], "purchasable": [], "subscription": { "cancel_at_period_end": false, "current_period_end": "2026-09-04T09:14:00.000Z", "price_lookup_key": "example", "status": "example" }, "terms_on_sale": [], "tier": "free", "viewer": { "can_purchase": false, "role": "owner" } } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/billing/plan', body: { "tier": "free" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/plan' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"tier":"free"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `post-billing-plan` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `tier` | `string` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `billing_configured` | `boolean` | yes | | | `billing_term` | `"month" \| "year" \| null` | yes | | | `entitlements` | `object` | yes | | | `entitlements.included_emails_per_month` | `integer` | yes | | | `entitlements.max_domains` | `integer \| null` | yes | | | `entitlements.max_seats` | `integer` | yes | | | `entitlements.overage_minor_per_1000_emails` | `integer \| null` | yes | | | `entitlements.retention_days` | `integer` | yes | | | `entitlements.tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `needs_plan_selection` | `boolean` | yes | | | `plan_source` | `"free" \| "subscription" \| "manual"` | yes | | | `plan_status` | `"none" \| "trialing" \| "active" \| "past_due" \| "canceled"` | yes | | | `plans` | `array` | yes | | | `plans[].featured` | `boolean` | yes | | | `plans[].included_emails_per_month` | `integer` | yes | | | `plans[].max_domains` | `integer \| null` | yes | | | `plans[].max_seats` | `integer` | yes | | | `plans[].name` | `string` | yes | | | `plans[].prices` | `object` | yes | | | `plans[].retention_days` | `integer` | yes | | | `plans[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `plans[].volume_rungs` | `array` | yes | | | `purchasable` | `array` | yes | | | `purchasable[].included_emails_per_month` | `integer` | yes | | | `purchasable[].monthly_price_minor` | `integer` | yes | | | `purchasable[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `subscription` | `object \| null` | yes | | | `terms_on_sale` | `array<"month" \| "year">` | yes | | | `tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `viewer` | `object` | yes | | | `viewer.can_purchase` | `boolean` | yes | | | `viewer.role` | `"owner" \| "admin" \| "viewer" \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-billing-plan — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-billing-portal # POST /billing/portal Console: open the Stripe customer portal (plan changes, card, invoices). ## Request ```bash curl -sS -X POST https://api.agentisend.com/billing/portal \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 201 { "url": "https://yourapp.com/hooks/agentisend" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/billing/portal', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/portal' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `post-billing-portal` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `url` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`billing_customer_missing`](https://agentisend.com/docs/errors#billing_customer_missing) (404) — This account has no billing customer yet. **Fix:** Start a subscription with POST /billing/checkout first; the customer portal only exists once a checkout has run. - [`billing_not_configured`](https://agentisend.com/docs/errors#billing_not_configured) (503) — Purchases are unavailable right now. **Fix:** GET /billing/plan still works, and the account stays on Free. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-billing-portal — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-billing-subscription # GET /billing/subscription Console: the signed-in account’s plan and subscription state. ## Request ```bash curl -sS -X GET https://api.agentisend.com/billing/subscription \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "billing_configured": false, "billing_term": "month", "entitlements": { "included_emails_per_month": -9007199254740991, "max_domains": -9007199254740991, "max_seats": -9007199254740991, "overage_minor_per_1000_emails": -9007199254740991, "retention_days": -9007199254740991, "tier": "free" }, "needs_plan_selection": false, "plan_source": "free", "plan_status": "none", "plans": [], "purchasable": [], "subscription": { "cancel_at_period_end": false, "current_period_end": "2026-09-04T09:14:00.000Z", "price_lookup_key": "example", "status": "example" }, "terms_on_sale": [], "tier": "free", "viewer": { "can_purchase": false, "role": "owner" } } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/billing/subscription', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/billing/subscription' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `get-billing-subscription` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `billing_configured` | `boolean` | yes | | | `billing_term` | `"month" \| "year" \| null` | yes | | | `entitlements` | `object` | yes | | | `entitlements.included_emails_per_month` | `integer` | yes | | | `entitlements.max_domains` | `integer \| null` | yes | | | `entitlements.max_seats` | `integer` | yes | | | `entitlements.overage_minor_per_1000_emails` | `integer \| null` | yes | | | `entitlements.retention_days` | `integer` | yes | | | `entitlements.tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `needs_plan_selection` | `boolean` | yes | | | `plan_source` | `"free" \| "subscription" \| "manual"` | yes | | | `plan_status` | `"none" \| "trialing" \| "active" \| "past_due" \| "canceled"` | yes | | | `plans` | `array` | yes | | | `plans[].featured` | `boolean` | yes | | | `plans[].included_emails_per_month` | `integer` | yes | | | `plans[].max_domains` | `integer \| null` | yes | | | `plans[].max_seats` | `integer` | yes | | | `plans[].name` | `string` | yes | | | `plans[].prices` | `object` | yes | | | `plans[].retention_days` | `integer` | yes | | | `plans[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `plans[].volume_rungs` | `array` | yes | | | `purchasable` | `array` | yes | | | `purchasable[].included_emails_per_month` | `integer` | yes | | | `purchasable[].monthly_price_minor` | `integer` | yes | | | `purchasable[].tier` | `"starter" \| "pro" \| "scale"` | yes | | | `subscription` | `object \| null` | yes | | | `terms_on_sale` | `array<"month" \| "year">` | yes | | | `tier` | `"free" \| "starter" \| "pro" \| "scale"` | yes | | | `viewer` | `object` | yes | | | `viewer.can_purchase` | `boolean` | yes | | | `viewer.role` | `"owner" \| "admin" \| "viewer" \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. --- Source: https://agentisend.com/docs/api/get-billing-subscription — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-broadcasts # GET /broadcasts Every broadcast, newest first — archived included. ## Request ```bash curl -sS -X GET https://api.agentisend.com/broadcasts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/broadcasts', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `get-broadcasts` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].archived_at` | `string \| null` | yes | | | `data[].content` | `object \| null` | yes | | | `data[].created_at` | `string` | yes | | | `data[].from_address` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].scheduled_at` | `string \| null` | yes | | | `data[].segment_id` | `string \| null` | yes | | | `data[].sent_at` | `string \| null` | yes | | | `data[].sent_count` | `integer` | yes | | | `data[].status` | `string` | yes | | | `data[].subject` | `string \| null` | yes | | | `data[].template_id` | `string \| null` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-broadcasts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-broadcasts # POST /broadcasts Draft a broadcast to a segment. Content comes from a template version or an inline body. ## Request ```bash curl -sS -X POST https://api.agentisend.com/broadcasts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Receipts","from_address":"billing@yourdomain.com","segment_id":"9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42","subject":"Your receipt","content":{"mode":"markdown","source":"Thanks — the details are attached."}}' ``` ```json Response 201 { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/broadcasts', body: { "name": "Receipts", "from_address": "billing@yourdomain.com", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "subject": "Your receipt", "content": { "mode": "markdown", "source": "Thanks — the details are attached." } }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"Receipts","from_address":"billing@yourdomain.com","segment_id":"9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42","subject":"Your receipt","content":{"mode":"markdown","source":"Thanks — the details are attached."}}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `post-broadcasts` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | no | | | `from_address` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string` | no | | | `segment_id` | `string` | yes | | | `subject` | `string` | no | | | `template_id` | `string` | no | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `archived_at` | `string \| null` | yes | | | `content` | `object \| null` | yes | | | `created_at` | `string` | yes | | | `from_address` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string \| null` | yes | | | `segment_id` | `string \| null` | yes | | | `sent_at` | `string \| null` | yes | | | `sent_count` | `integer` | yes | | | `status` | `string` | yes | | | `subject` | `string \| null` | yes | | | `template_id` | `string \| null` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-broadcasts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-broadcasts-id # GET /broadcasts/{id} One broadcast. ## Request ```bash curl -sS -X GET https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `get-broadcasts-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `archived_at` | `string \| null` | yes | | | `content` | `object \| null` | yes | | | `created_at` | `string` | yes | | | `from_address` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string \| null` | yes | | | `segment_id` | `string \| null` | yes | | | `sent_at` | `string \| null` | yes | | | `sent_count` | `integer` | yes | | | `status` | `string` | yes | | | `subject` | `string \| null` | yes | | | `template_id` | `string \| null` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-broadcasts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-broadcasts-id # PATCH /broadcasts/{id} Edit an unsent broadcast, or rename ANY one. Drafts and scheduled broadcasts are editable; a scheduled_at time schedules it and null returns it to draft. Sent content is immutable. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `patch-broadcasts-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | no | | | `name` | `string` | no | | | `scheduled_at` | `string \| null` | no | | | `segment_id` | `string` | no | | | `subject` | `string` | no | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `archived_at` | `string \| null` | yes | | | `content` | `object \| null` | yes | | | `created_at` | `string` | yes | | | `from_address` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string \| null` | yes | | | `segment_id` | `string \| null` | yes | | | `sent_at` | `string \| null` | yes | | | `sent_count` | `integer` | yes | | | `status` | `string` | yes | | | `subject` | `string \| null` | yes | | | `template_id` | `string \| null` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-broadcasts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-broadcasts-id-archive # POST /broadcasts/{id}/archive Archive — reversible, any time, sent or draft. ## Request ```bash curl -sS -X POST https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/archive \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/archive', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/archive' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `post-broadcasts-id-archive` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `archived_at` | `string \| null` | yes | | | `content` | `object \| null` | yes | | | `created_at` | `string` | yes | | | `from_address` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string \| null` | yes | | | `segment_id` | `string \| null` | yes | | | `sent_at` | `string \| null` | yes | | | `sent_count` | `integer` | yes | | | `status` | `string` | yes | | | `subject` | `string \| null` | yes | | | `template_id` | `string \| null` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-broadcasts-id-archive — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-broadcasts-id-cancel # POST /broadcasts/{id}/cancel Cancel a scheduled broadcast, or stop one that is still sending. Mail already handed off is not pulled back. A scheduled broadcast returns to draft. ## Request ```bash curl -sS -X POST https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `post-broadcasts-id-cancel` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `archived_at` | `string \| null` | yes | | | `content` | `object \| null` | yes | | | `created_at` | `string` | yes | | | `from_address` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `scheduled_at` | `string \| null` | yes | | | `segment_id` | `string \| null` | yes | | | `sent_at` | `string \| null` | yes | | | `sent_count` | `integer` | yes | | | `status` | `string` | yes | | | `subject` | `string \| null` | yes | | | `template_id` | `string \| null` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-broadcasts-id-cancel — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-broadcasts-id-messages # GET /broadcasts/{id}/messages Per-member delivery state for this broadcast. ## Request ```bash curl -sS -X GET https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/messages \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/messages', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/messages' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `get-broadcasts-id-messages` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `outcome` query · `"sent" | "delivered" | "opened" | "clicked" | "bounced" | "complained" | "unsubscribed" | "skipped"` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].contact_id` | `string` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].message_id` | `string \| null` | yes | | | `data[].state` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-broadcasts-id-messages — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-broadcasts-id-preview # GET /broadcasts/{id}/preview Render this broadcast the way a recipient would see it. Nothing is sent. ## Request ```bash curl -sS -X GET https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/preview \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "html": "example", "subject": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/preview', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/preview' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `get-broadcasts-id-preview` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `html` | `string` | yes | | | `subject` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-broadcasts-id-preview — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-broadcasts-id-send # POST /broadcasts/{id}/send Send now. Returns 200 when the broadcast has finished, and 202 while it is still sending. A 202 has status sending. ## Request ```bash curl -sS -X POST https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/send \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "broadcast": { "archived_at": "2026-09-04T09:14:00.000Z", "content": {}, "created_at": "2026-09-04T09:14:00.000Z", "from_address": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "scheduled_at": "2026-09-04T09:14:00.000Z", "segment_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "sent_at": "2026-09-04T09:14:00.000Z", "sent_count": -9007199254740991, "status": "example", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "updated_at": "2026-09-04T09:14:00.000Z" }, "sent": -9007199254740991, "skipped": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/send', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/send' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `post-broadcasts-id-send` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — The send finished. - `202` — The send is still running. The broadcast status is sending. - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `broadcast` | `object` | yes | | | `broadcast.archived_at` | `string \| null` | yes | | | `broadcast.content` | `object \| null` | yes | | | `broadcast.created_at` | `string` | yes | | | `broadcast.from_address` | `string \| null` | yes | | | `broadcast.id` | `string` | yes | | | `broadcast.name` | `string` | yes | | | `broadcast.scheduled_at` | `string \| null` | yes | | | `broadcast.segment_id` | `string \| null` | yes | | | `broadcast.sent_at` | `string \| null` | yes | | | `broadcast.sent_count` | `integer` | yes | | | `broadcast.status` | `string` | yes | | | `broadcast.subject` | `string \| null` | yes | | | `broadcast.template_id` | `string \| null` | yes | | | `broadcast.updated_at` | `string` | yes | | | `sent` | `integer` | yes | | | `skipped` | `integer` | yes | | ## 202 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `broadcast` | `object` | yes | | | `broadcast.archived_at` | `string \| null` | yes | | | `broadcast.content` | `object \| null` | yes | | | `broadcast.created_at` | `string` | yes | | | `broadcast.from_address` | `string \| null` | yes | | | `broadcast.id` | `string` | yes | | | `broadcast.name` | `string` | yes | | | `broadcast.scheduled_at` | `string \| null` | yes | | | `broadcast.segment_id` | `string \| null` | yes | | | `broadcast.sent_at` | `string \| null` | yes | | | `broadcast.sent_count` | `integer` | yes | | | `broadcast.status` | `string` | yes | | | `broadcast.subject` | `string \| null` | yes | | | `broadcast.template_id` | `string \| null` | yes | | | `broadcast.updated_at` | `string` | yes | | | `sent` | `integer` | yes | | | `skipped` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-broadcasts-id-send — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-broadcasts-id-stats # GET /broadcasts/{id}/stats Sent, delivered, opened, clicked, bounced, complained and unsubscribed totals for one broadcast. A test send is not included. ## Request ```bash curl -sS -X GET https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/stats \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "bounced": -9007199254740991, "clicked": -9007199254740991, "clicked_percent": -9007199254740991, "complained": -9007199254740991, "delivered": -9007199254740991, "delivered_percent": -9007199254740991, "opened": -9007199254740991, "opened_percent": -9007199254740991, "sent": -9007199254740991, "unsubscribed": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/stats', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/broadcasts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/stats' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: broadcasts. Generated from `openapi.json`; the anchor `get-broadcasts-id-stats` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `bounced` | `integer` | yes | | | `clicked` | `integer` | yes | | | `clicked_percent` | `integer` | yes | | | `complained` | `integer` | yes | | | `delivered` | `integer` | yes | | | `delivered_percent` | `integer` | yes | | | `opened` | `integer` | yes | | | `opened_percent` | `integer` | yes | | | `sent` | `integer` | yes | | | `unsubscribed` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-broadcasts-id-stats — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contact-properties # GET /contact-properties Property names and types already stored on this account. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contact-properties \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contact-properties', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contact-properties' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contact-properties` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].fallback_value` | `null` | yes | | | `data[].id` | `string` | yes | | | `data[].key` | `string` | yes | | | `data[].object` | `string` | yes | | | `data[].type` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-contact-properties — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contact-properties-id # GET /contact-properties/{id} One stored property name and its type. Creating a property definition is not available. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contact-properties/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "fallback_value": null, "id": "example", "key": "example", "object": "contact_property", "type": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contact-properties/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contact-properties/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contact-properties-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `fallback_value` | `null` | yes | | | `id` | `string` | yes | | | `key` | `string` | yes | | | `object` | `string` | yes | | | `type` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-contact-properties-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contacts # GET /contacts List contacts, newest first. email is an exact match; q is a substring. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contacts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contacts', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contacts` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `email` query · `string` · optional - `q` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].first_name` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_name` | `string \| null` | yes | | | `data[].object` | `string` | yes | | | `data[].properties` | `object` | yes | | | `data[].property_types` | `object` | yes | | | `data[].status` | `string` | yes | | | `data[].unsubscribed` | `boolean` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-contacts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-contacts # POST /contacts Create or update a contact by email. first_name, last_name and unsubscribed are accepted. Properties are typed from their value and auto-created. ## Request ```bash curl -sS -X POST https://api.agentisend.com/contacts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"customer@example.com"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/contacts', body: { "email": "customer@example.com" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"email":"customer@example.com"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-contacts` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | yes | The contact address. An existing address is updated. | | `first_name` | `string \| null` | no | Given name. Null clears it. | | `last_name` | `string \| null` | no | Family name. Null clears it. | | `properties` | `object` | no | Named values stored on the contact. A new name is created. | | `status` | `"active" \| "unsubscribed"` | no | active, or unsubscribed to stop marketing mail. | | `unsubscribed` | `boolean` | no | true stops marketing mail to this address. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`contact_resubscribe_required`](https://agentisend.com/docs/errors#contact_resubscribe_required) (409) — This address asked not to be contacted, so marking the contact active leaves that in place. **Fix:** POST /contacts/:id/resubscribe with consent_source and consent_at after the person opts back in. The id can be the contact id or the email address. A spam report is not lifted by that call. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-contacts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-contacts-batch # POST /contacts/batch Update up to 1,000 contacts that already exist. A new address is rejected. ## Request ```bash curl -sS -X POST https://api.agentisend.com/contacts/batch \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"contacts":[{"email":"example"}]}' ``` ```json Response 200 { "data": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/contacts/batch', body: { "contacts": [ { "email": "example" } ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/batch' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"contacts":[{"email":"example"}]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-contacts-batch` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `contacts` | `array` | yes | Contacts to update. At most 1,000. A new address is rejected. | | `contacts[].email` | `string` | yes | The contact address. A new address is rejected; an existing one is updated. | | `contacts[].first_name` | `string \| null` | no | Given name. Null clears it. | | `contacts[].last_name` | `string \| null` | no | Family name. Null clears it. | | `contacts[].properties` | `object` | no | Named values stored on the contact. A new name is created. | | `contacts[].status` | `"active" \| "unsubscribed"` | no | active, or unsubscribed to stop marketing mail. | | `contacts[].unsubscribed` | `boolean` | no | true stops marketing mail to this address. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].email` | `string` | no | | | `data[].error` | `object` | no | | | `data[].id` | `string` | no | | | `data[].index` | `integer` | yes | | | `data[].status` | `"created" \| "updated" \| "rejected"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-contacts-batch — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-contacts-imports # POST /contacts/imports Update contacts from a CSV. A new address is rejected. At most 1,000 data rows. ## Request ```bash curl -sS -X POST https://api.agentisend.com/contacts/imports \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"csv":"email\ncustomer@example.com\n"}' ``` ```json Response 200 { "counts": { "created": -9007199254740991, "failed": -9007199254740991, "skipped": -9007199254740991, "total": -9007199254740991, "updated": -9007199254740991 }, "object": "contact_import", "rejected": [], "status": "completed" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/contacts/imports', body: { "csv": "email\ncustomer@example.com\n" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/imports' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"csv":"email\ncustomer@example.com\n"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-contacts-imports` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `column_map` | `object` | no | Maps a CSV header to email, first_name, last_name or unsubscribed. | | `csv` | `string` | yes | CSV text. The first row is the header and must include email. | | `on_conflict` | `"upsert" \| "skip"` | no | skip leaves an existing contact unchanged. upsert updates it. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `counts` | `object` | yes | | | `counts.created` | `integer` | yes | | | `counts.failed` | `integer` | yes | | | `counts.skipped` | `integer` | yes | | | `counts.total` | `integer` | yes | | | `counts.updated` | `integer` | yes | | | `object` | `string` | yes | | | `rejected` | `array` | yes | | | `rejected[].code` | `string` | yes | | | `rejected[].email` | `string` | yes | | | `rejected[].fix` | `string` | yes | | | `rejected[].message` | `string` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-contacts-imports — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contacts-id # GET /contacts/{id} One contact with its properties. The path is the contact id or its email address. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-contacts-id # PATCH /contacts/{id} Edit one contact by id or email. first_name, last_name and unsubscribed are accepted. Properties merge; null removes one. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"properties":{"plan":"starter"}}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "properties": { "plan": "starter" } }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"properties":{"plan":"starter"}}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `patch-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | no | A new address for this contact. | | `first_name` | `string \| null` | no | Given name. Null clears it. | | `last_name` | `string \| null` | no | Family name. Null clears it. | | `properties` | `object` | no | Values to merge. Null removes that property. | | `status` | `"active" \| "unsubscribed"` | no | active, or unsubscribed to stop marketing mail. | | `unsubscribed` | `boolean` | no | true stops marketing mail to this address. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`contact_resubscribe_required`](https://agentisend.com/docs/errors#contact_resubscribe_required) (409) — This address asked not to be contacted, so marking the contact active leaves that in place. **Fix:** POST /contacts/:id/resubscribe with consent_source and consent_at after the person opts back in. The id can be the contact id or the email address. A spam report is not lifted by that call. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-contacts-id # DELETE /contacts/{id} Delete one contact and its properties. The path is the contact id or its email address. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "contact": "example", "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "object": "contact" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `delete-contacts-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `contact` | `string` | yes | | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-contacts-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-contacts-id-resubscribe # POST /contacts/{id}/resubscribe Mark a contact active again after they opt back in. Requires consent_source and consent_at. Does not lift a spam report or a bounce. ## Request ```bash curl -sS -X POST https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resubscribe \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"consent_source":"account settings","consent_at":"2026-09-04T09:14:00.000Z"}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "first_name": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_name": "example", "object": "contact", "properties": {}, "property_types": {}, "status": "example", "unsubscribed": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resubscribe', body: { "consent_source": "account settings", "consent_at": "2026-09-04T09:14:00.000Z" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resubscribe' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"consent_source":"account settings","consent_at":"2026-09-04T09:14:00.000Z"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-contacts-id-resubscribe` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `consent_at` | `string` | yes | When they opted back in, as UTC. Not in the future. | | `consent_source` | `string` | yes | Where the person opted back in. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `first_name` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_name` | `string \| null` | yes | | | `object` | `string` | yes | | | `properties` | `object` | yes | | | `property_types` | `object` | yes | | | `status` | `string` | yes | | | `unsubscribed` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`contact_resubscribe_required`](https://agentisend.com/docs/errors#contact_resubscribe_required) (409) — This address asked not to be contacted, so marking the contact active leaves that in place. **Fix:** POST /contacts/:id/resubscribe with consent_source and consent_at after the person opts back in. The id can be the contact id or the email address. A spam report is not lifted by that call. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-contacts-id-resubscribe — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contacts-id-segments # GET /contacts/{id}/segments Segments whose rules include this contact. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contacts-id-segments` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-contacts-id-segments — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-contacts-id-segments-segmentid # POST /contacts/{id}/segments/{segmentId} Not available. Add people by changing rules with PATCH /segments/{id}. ## Request ```bash curl -sS -X POST https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 201 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `post-contacts-id-segments-segmentid` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `segmentId` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-contacts-id-segments-segmentid — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-contacts-id-segments-segmentid # DELETE /contacts/{id}/segments/{segmentId} Not available. Remove people by changing rules with PATCH /segments/{id}. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `delete-contacts-id-segments-segmentid` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `segmentId` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-contacts-id-segments-segmentid — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-contacts-id-topics # GET /contacts/{id}/topics What this contact has said about every topic. A topic they never answered reports the topic default, and says so. ## Request ```bash curl -sS -X GET https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-contacts-id-topics` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].basis` | `"explicit" \| "default"` | yes | | | `data[].description` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].source` | `string \| null` | yes | | | `data[].subscribed` | `boolean` | yes | | | `data[].subscription` | `"opt_in" \| "opt_out"` | yes | | | `data[].updated_at` | `string \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-contacts-id-topics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-contacts-id-topics # PATCH /contacts/{id}/topics Record this contact’s answer for one or more topics. Answers are absolute — nothing is inferred from what is left out. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"topics":[{"subscribed":false,"topic_id":"9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42"}]}' ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics', body: { "topics": [ { "subscribed": false, "topic_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/contacts/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/topics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"topics":[{"subscribed":false,"topic_id":"9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42"}]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `patch-contacts-id-topics` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].basis` | `"explicit" \| "default"` | yes | | | `data[].description` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].source` | `string \| null` | yes | | | `data[].subscribed` | `boolean` | yes | | | `data[].subscription` | `"opt_in" \| "opt_out"` | yes | | | `data[].updated_at` | `string \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-contacts-id-topics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-dedicated-ips # GET /dedicated-ips This account dedicated IPs with live warmup percentages. ## Request ```bash curl -sS -X GET https://api.agentisend.com/dedicated-ips \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/dedicated-ips', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/dedicated-ips' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: dedicated-ips. Generated from `openapi.json`; the anchor `get-dedicated-ips` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].ip` | `string` | yes | | | `data[].region` | `string` | yes | | | `data[].started_at` | `string` | yes | | | `data[].state` | `string` | yes | | | `data[].warmup_percent` | `integer` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-dedicated-ips — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-dedicated-ips # POST /dedicated-ips Refused: a dedicated IP is assigned by us from the addresses we send from — ask support. GET /dedicated-ips lists it once assigned. ## Request ```bash curl -sS -X POST https://api.agentisend.com/dedicated-ips \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"ip":"example","region":"example"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "ip": "example", "region": "example", "started_at": "2026-09-04T09:14:00.000Z", "state": "example", "warmup_percent": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/dedicated-ips', body: { "ip": "example", "region": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/dedicated-ips' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"ip":"example","region":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: dedicated-ips. Generated from `openapi.json`; the anchor `post-dedicated-ips` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `ip` | `string` | yes | | | `region` | `string` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `ip` | `string` | yes | | | `region` | `string` | yes | | | `started_at` | `string` | yes | | | `state` | `string` | yes | | | `warmup_percent` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`dedicated_ip_assigned_by_us`](https://agentisend.com/docs/errors#dedicated_ip_assigned_by_us) (403) — Dedicated IPs are assigned by us from the addresses we send from; the API cannot create one. **Fix:** Ask support for a dedicated IP (available on Scale, about $30 a month, warmup included). Once it is assigned, GET /dedicated-ips lists it and GET /dedicated-ips/ramp shows the warmup curve it follows. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-dedicated-ips — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-dedicated-ips-ramp # GET /dedicated-ips/ramp The PUBLISHED warmup curve — exactly how volume moves and when. ## Request ```bash curl -sS -X GET https://api.agentisend.com/dedicated-ips/ramp \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "curve": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/dedicated-ips/ramp', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/dedicated-ips/ramp' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: dedicated-ips. Generated from `openapi.json`; the anchor `get-dedicated-ips-ramp` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `curve` | `array` | yes | | | `curve[].percent` | `number` | yes | | | `curve[].up_to_day` | `number` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-dedicated-ips-ramp — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-dedicated-ips-route-decision-messageid # GET /dedicated-ips/route-decision/{messageId} Which route this message would take RIGHT NOW — reproducible, the same math the send path uses. ## Request ```bash curl -sS -X GET https://api.agentisend.com/dedicated-ips/route-decision/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "ip": "example", "route": "shared", "warmup_percent": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/dedicated-ips/route-decision/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/dedicated-ips/route-decision/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: dedicated-ips. Generated from `openapi.json`; the anchor `get-dedicated-ips-route-decision-messageid` is the id the console's error `fix` links point at. ## Parameters - `messageId` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `ip` | `string \| null` | yes | | | `route` | `"shared" \| "dedicated"` | yes | | | `warmup_percent` | `integer \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-dedicated-ips-route-decision-messageid — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-dedicated-ips-id # DELETE /dedicated-ips/{id} Release a dedicated IP. Traffic returns to shared automatically. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/dedicated-ips/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/dedicated-ips/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/dedicated-ips/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: dedicated-ips. Generated from `openapi.json`; the anchor `delete-dedicated-ips-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-dedicated-ips-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-deliverability-dmarc # GET /deliverability/dmarc Authentication reports for verified domains. Aligned and failing volume per day, and addresses sending as you that are not ours. ## Request ```bash curl -sS -X GET https://api.agentisend.com/deliverability/dmarc \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "alignment_failure_threshold": 1, "days": [], "sources": [], "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/deliverability/dmarc', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/deliverability/dmarc' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: deliverability. Generated from `openapi.json`; the anchor `get-deliverability-dmarc` is the id the console's error `fix` links point at. ## Parameters - `domain` query · `string` · optional - `window_days` query · `integer` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `alignment_failure_threshold` | `number` | yes | | | `days` | `array` | yes | | | `days[].aligned` | `integer` | yes | | | `days[].day` | `string` | yes | | | `days[].domain` | `string` | yes | | | `days[].failing` | `integer` | yes | | | `days[].failure_rate` | `number \| null` | yes | | | `days[].total` | `integer` | yes | | | `sources` | `array` | yes | | | `sources[].aligned` | `integer` | yes | | | `sources[].domain` | `string` | yes | | | `sources[].failing` | `integer` | yes | | | `sources[].last_seen_day` | `string` | yes | | | `sources[].message_count` | `integer` | yes | | | `sources[].ours` | `boolean` | yes | | | `sources[].source_ip` | `string` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-deliverability-dmarc — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-deliverability-domains # GET /deliverability/domains Every sending domain with its standing over the window, worst first — the failing domain is the first row, not one you have to find. ## Request ```bash curl -sS -X GET https://api.agentisend.com/deliverability/domains \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "thresholds": { "bounce": { "limit": 1, "warn": 1 }, "complaint": { "limit": 1, "warn": 1 } }, "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/deliverability/domains', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/deliverability/domains' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: deliverability. Generated from `openapi.json`; the anchor `get-deliverability-domains` is the id the console's error `fix` links point at. ## Parameters - `window_days` query · `integer` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].bounce_rate` | `number \| null` | yes | | | `data[].complaint_rate` | `number \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].sent` | `integer` | yes | | | `data[].standing` | `"no_data" \| "ok" \| "warning" \| "over_limit"` | yes | | | `thresholds` | `object` | yes | | | `thresholds.bounce` | `object` | yes | | | `thresholds.complaint` | `object` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-deliverability-domains — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-deliverability-domains-id # GET /deliverability/domains/{id} Per-domain reputation: live rates over the rolling window, daily snapshots, the thresholds those rates are judged against, the bounce breakdown by class with… Per-domain reputation: live rates over the rolling window, daily snapshots, the thresholds those rates are judged against, the bounce breakdown by class with its remediation, and the receiving domains rejecting the most. ## Request ```bash curl -sS -X GET https://api.agentisend.com/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "blocklists": {}, "bounce_classes": [], "domain_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "domain_name": "example", "live": { "bounce_rate": 1, "bounced": -9007199254740991, "click_rate": 1, "clicked": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "delivered": -9007199254740991, "open_rate": 1, "opened": -9007199254740991, "sent": -9007199254740991 }, "postmaster": {}, "snapshots": [], "standing": "no_data", "thresholds": { "bounce": { "limit": 1, "warn": 1 }, "complaint": { "limit": 1, "warn": 1 } }, "top_recipient_domains": [], "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: deliverability. Generated from `openapi.json`; the anchor `get-deliverability-domains-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `window_days` query · `integer` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `blocklists` | `object` | yes | | | `bounce_classes` | `array` | yes | | | `bounce_classes[].class` | `"hard" \| "soft" \| "block" \| "policy"` | yes | | | `bounce_classes[].count` | `integer` | yes | | | `bounce_classes[].remediation` | `object` | yes | | | `bounce_classes[].share` | `number` | yes | | | `domain_id` | `string` | yes | | | `domain_name` | `string` | yes | | | `live` | `object` | yes | | | `live.bounce_rate` | `number \| null` | yes | | | `live.bounced` | `integer` | yes | | | `live.click_rate` | `number \| null` | yes | | | `live.clicked` | `integer` | yes | | | `live.complained` | `integer` | yes | | | `live.complaint_rate` | `number \| null` | yes | | | `live.delivered` | `integer` | yes | | | `live.open_rate` | `number \| null` | yes | | | `live.opened` | `integer` | yes | | | `live.sent` | `integer` | yes | | | `postmaster` | `object` | yes | | | `snapshots` | `array` | yes | | | `snapshots[].created_at` | `string` | yes | | | `snapshots[].rates` | `object` | yes | | | `snapshots[].snapshot_date` | `string` | yes | | | `standing` | `"no_data" \| "ok" \| "warning" \| "over_limit"` | yes | | | `thresholds` | `object` | yes | | | `thresholds.bounce` | `object` | yes | | | `thresholds.complaint` | `object` | yes | | | `top_recipient_domains` | `array` | yes | | | `top_recipient_domains[].bounce_rate` | `number \| null` | yes | | | `top_recipient_domains[].bounced` | `integer` | yes | | | `top_recipient_domains[].domain` | `string` | yes | | | `top_recipient_domains[].sent` | `integer` | yes | | | `top_recipient_domains[].top_reason` | `string \| null` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-deliverability-domains-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-deliverability-domains-id-snapshot # POST /deliverability/domains/{id}/snapshot Persist today rates as a snapshot row. Idempotent per domain per day. ## Request ```bash curl -sS -X POST https://api.agentisend.com/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/snapshot \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 201 { "domain_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "rates": { "bounce_rate": 1, "bounced": -9007199254740991, "click_rate": 1, "clicked": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "delivered": -9007199254740991, "open_rate": 1, "opened": -9007199254740991, "sent": -9007199254740991 }, "snapshot_date": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/snapshot', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/deliverability/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/snapshot' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: deliverability. Generated from `openapi.json`; the anchor `post-deliverability-domains-id-snapshot` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `domain_id` | `string` | yes | | | `rates` | `object` | yes | | | `rates.bounce_rate` | `number \| null` | yes | | | `rates.bounced` | `integer` | yes | | | `rates.click_rate` | `number \| null` | yes | | | `rates.clicked` | `integer` | yes | | | `rates.complained` | `integer` | yes | | | `rates.complaint_rate` | `number \| null` | yes | | | `rates.delivered` | `integer` | yes | | | `rates.open_rate` | `number \| null` | yes | | | `rates.opened` | `integer` | yes | | | `rates.sent` | `integer` | yes | | | `snapshot_date` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-deliverability-domains-id-snapshot — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains # GET /domains List domains. Items omit records; GET /domains/:id has the DNS sheet. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].click_tracking` | `boolean` | yes | | | `data[].created_at` | `string` | yes | | | `data[].dkim_selector` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].open_tracking` | `boolean` | yes | | | `data[].region` | `"us" \| "eu"` | yes | | | `data[].return_path_subdomain` | `string` | yes | | | `data[].status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | | `data[].tls_mode` | `"opportunistic" \| "enforced"` | yes | | | `data[].tracking_subdomain` | `string` | yes | | | `data[].verified_at` | `string \| null` | yes | | | `data[].zone` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-domains # POST /domains Register a sending domain. Region is optional and defaults to us (Oregon); the stored value is returned. ## Request ```bash curl -sS -X POST https://api.agentisend.com/domains \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"example"}' ``` ```json Response 201 { "click_tracking": false, "created_at": "2026-09-04T09:14:00.000Z", "dkim_selector": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "open_tracking": false, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "recent_events": [], "records": [], "region": "us", "return_path_subdomain": "example", "status": "pending", "tls_mode": "opportunistic", "tracking_issues": [], "tracking_subdomain": "example", "verified_at": "2026-09-04T09:14:00.000Z", "warnings": [], "zone": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/domains', body: { "name": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `post-domains` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `clickTracking` | `boolean` | no | Same as click_tracking. click_tracking wins if both are sent. | | `click_tracking` | `boolean` | no | Rewrite links so clicks can be counted. Off unless you set this. | | `customReturnPath` | `string` | no | Same as custom_return_path. | | `custom_return_path` | `string` | no | Same as return_path_subdomain. | | `name` | `string` | yes | The domain you send from, such as yourdomain.com. | | `openTracking` | `boolean` | no | Same as open_tracking. open_tracking wins if both are sent. | | `open_tracking` | `boolean` | no | Count opens. Off unless you set this. | | `region` | `"us" \| "eu"` | no | us or eu. Default us. The region is recorded on the domain. All mail is sent from the US today. For one release the legacy names us-east-1, sa-east-1 and ap-northeast-1 map to us; eu-west-1 maps to eu. | | `return_path_subdomain` | `string` | no | The label of the return-path host. Default send. Up to 63 characters, starting with a letter. | | `tls` | `"opportunistic" \| "enforced"` | no | Same as tls_mode. tls_mode wins if both are sent. | | `tls_mode` | `"opportunistic" \| "enforced"` | no | opportunistic tries TLS and falls back. enforced refuses a receiver that cannot do TLS. | | `tracking` | `boolean` | no | Whether to publish a tracking host. On by default. Not required to verify the domain. | | `tracking_subdomain` | `string` | no | The label of the tracking host. Default links, which publishes links.yourdomain.com. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `click_tracking` | `boolean` | yes | | | `created_at` | `string` | yes | | | `dkim_selector` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `open_tracking` | `boolean` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `recent_events` | `array` | yes | | | `recent_events[].detail` | `string` | yes | | | `recent_events[].id` | `string` | yes | | | `recent_events[].occurred_at` | `string` | yes | | | `recent_events[].type` | `"domain.added" \| "domain.first_check" \| "domain.record_seen" \| "domain.record_lost" \| "domain.verified" \| "domain.demoted" \| "domain.window_closed" \| "domain.deleted"` | yes | | | `records` | `array` | yes | | | `records[].checked_at` | `string \| null` | yes | | | `records[].fix` | `string` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].observed` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].reason` | `"ok" \| "not_found" \| "unreachable" \| "mismatch" \| "not_published" \| null` | yes | | | `records[].record` | `"SPF" \| "DKIM" \| "DMARC" \| "RETURN_PATH" \| "TRACKING" \| "RECEIVING" \| "TRACKING_CAA"` | yes | | | `records[].required` | `boolean` | yes | | | `records[].status` | `"pending" \| "verified" \| "failed" \| "recommended"` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `"TXT" \| "MX" \| "CNAME" \| "CAA"` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `region` | `"us" \| "eu"` | yes | | | `return_path_subdomain` | `string` | yes | | | `status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | | `tls_mode` | `"opportunistic" \| "enforced"` | yes | | | `tracking_issues` | `array` | yes | | | `tracking_issues[].fix` | `string` | yes | | | `tracking_issues[].message` | `string` | yes | | | `tracking_issues[].record` | `"TRACKING" \| "TRACKING_CAA"` | yes | | | `tracking_subdomain` | `string` | yes | | | `verified_at` | `string \| null` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `"spf_conflict" \| "spf_lookup_limit" \| "legacy_region"` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].merged` | `string \| null` | yes | | | `warnings[].message` | `string` | yes | | | `warnings[].observed` | `string` | yes | | | `zone` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`domain_already_exists`](https://agentisend.com/docs/errors#domain_already_exists) (409) — That domain is already registered on this account. **Fix:** Use the existing domain from GET /domains. A person removes a domain in the console under Domains. - [`domain_blocklisted`](https://agentisend.com/docs/errors#domain_blocklisted) (422) — This domain is on a public blocklist, so it cannot be added. **Fix:** Use a domain that is not listed, or wait until the listing is removed, then POST /domains again. - [`domain_limit_reached`](https://agentisend.com/docs/errors#domain_limit_reached) (422) — This plan has no sending domain left. **Fix:** Remove a domain in the console under Domains, or upgrade in Settings → Billing. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`invalid_region`](https://agentisend.com/docs/errors#invalid_region) (422) — Region must be one of us, eu. **Fix:** Pass region as us or eu in POST /domains. Omitting it stores us. For this release us-east-1, sa-east-1 and ap-northeast-1 map to us, and eu-west-1 maps to eu. - [`mailbox_provider_domain`](https://agentisend.com/docs/errors#mailbox_provider_domain) (422) — You cannot send as a mailbox provider’s domain. **Fix:** Add a domain you own with POST /domains, such as acme.com or mail.acme.com, and send from an address on it. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`return_path_subdomain_in_use`](https://agentisend.com/docs/errors#return_path_subdomain_in_use) (409) — The return-path host already has an MX record pointing somewhere else. **Fix:** Pass return_path_subdomain on POST /domains: a label of up to 63 characters that starts with a letter. send is the default; bounce is the usual choice when send already has an MX. - [`sending_domain_blocked`](https://agentisend.com/docs/errors#sending_domain_blocked) (403) — This domain cannot send through AgentiSend. **Fix:** Send from a different domain you own. If you believe this is a mistake, contact support and name the domain. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-domains — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains-id # GET /domains/{id} One domain, with the DNS to publish and what each record last resolved to. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "click_tracking": false, "created_at": "2026-09-04T09:14:00.000Z", "dkim_selector": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "open_tracking": false, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "recent_events": [], "records": [], "region": "us", "return_path_subdomain": "example", "status": "pending", "tls_mode": "opportunistic", "tracking_issues": [], "tracking_subdomain": "example", "verified_at": "2026-09-04T09:14:00.000Z", "warnings": [], "zone": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `click_tracking` | `boolean` | yes | | | `created_at` | `string` | yes | | | `dkim_selector` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `open_tracking` | `boolean` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `recent_events` | `array` | yes | | | `recent_events[].detail` | `string` | yes | | | `recent_events[].id` | `string` | yes | | | `recent_events[].occurred_at` | `string` | yes | | | `recent_events[].type` | `"domain.added" \| "domain.first_check" \| "domain.record_seen" \| "domain.record_lost" \| "domain.verified" \| "domain.demoted" \| "domain.window_closed" \| "domain.deleted"` | yes | | | `records` | `array` | yes | | | `records[].checked_at` | `string \| null` | yes | | | `records[].fix` | `string` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].observed` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].reason` | `"ok" \| "not_found" \| "unreachable" \| "mismatch" \| "not_published" \| null` | yes | | | `records[].record` | `"SPF" \| "DKIM" \| "DMARC" \| "RETURN_PATH" \| "TRACKING" \| "RECEIVING" \| "TRACKING_CAA"` | yes | | | `records[].required` | `boolean` | yes | | | `records[].status` | `"pending" \| "verified" \| "failed" \| "recommended"` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `"TXT" \| "MX" \| "CNAME" \| "CAA"` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `region` | `"us" \| "eu"` | yes | | | `return_path_subdomain` | `string` | yes | | | `status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | | `tls_mode` | `"opportunistic" \| "enforced"` | yes | | | `tracking_issues` | `array` | yes | | | `tracking_issues[].fix` | `string` | yes | | | `tracking_issues[].message` | `string` | yes | | | `tracking_issues[].record` | `"TRACKING" \| "TRACKING_CAA"` | yes | | | `tracking_subdomain` | `string` | yes | | | `verified_at` | `string \| null` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `"spf_conflict" \| "spf_lookup_limit" \| "legacy_region"` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].merged` | `string \| null` | yes | | | `warnings[].message` | `string` | yes | | | `warnings[].observed` | `string` | yes | | | `zone` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-domains-id # PATCH /domains/{id} Turn click or open tracking on, or change the tracking subdomain. Name, region and return-path cannot change. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "click_tracking": false, "created_at": "2026-09-04T09:14:00.000Z", "dkim_selector": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "open_tracking": false, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "recent_events": [], "records": [], "region": "us", "return_path_subdomain": "example", "status": "pending", "tls_mode": "opportunistic", "tracking_issues": [], "tracking_subdomain": "example", "verified_at": "2026-09-04T09:14:00.000Z", "warnings": [], "zone": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `patch-domains-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `click_tracking` | `boolean` | no | Rewrite links so clicks can be counted. Off unless you set this. | | `custom_return_path` | `any` | no | The return-path label cannot be changed after the domain is created. | | `name` | `any` | no | The domain name cannot be changed. Create another domain. | | `open_tracking` | `boolean` | no | Count opens. Off unless you set this. | | `region` | `any` | no | The region cannot be changed after the domain is created. | | `return_path` | `any` | no | The return-path label cannot be changed after the domain is created. | | `tls_mode` | `"opportunistic" \| "enforced"` | no | opportunistic tries TLS and falls back. enforced refuses a receiver that cannot do TLS. | | `tracking_subdomain` | `string \| null` | no | Change the tracking host label. Null is refused: the host can be renamed, not removed. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `click_tracking` | `boolean` | yes | | | `created_at` | `string` | yes | | | `dkim_selector` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `open_tracking` | `boolean` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `recent_events` | `array` | yes | | | `recent_events[].detail` | `string` | yes | | | `recent_events[].id` | `string` | yes | | | `recent_events[].occurred_at` | `string` | yes | | | `recent_events[].type` | `"domain.added" \| "domain.first_check" \| "domain.record_seen" \| "domain.record_lost" \| "domain.verified" \| "domain.demoted" \| "domain.window_closed" \| "domain.deleted"` | yes | | | `records` | `array` | yes | | | `records[].checked_at` | `string \| null` | yes | | | `records[].fix` | `string` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].observed` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].reason` | `"ok" \| "not_found" \| "unreachable" \| "mismatch" \| "not_published" \| null` | yes | | | `records[].record` | `"SPF" \| "DKIM" \| "DMARC" \| "RETURN_PATH" \| "TRACKING" \| "RECEIVING" \| "TRACKING_CAA"` | yes | | | `records[].required` | `boolean` | yes | | | `records[].status` | `"pending" \| "verified" \| "failed" \| "recommended"` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `"TXT" \| "MX" \| "CNAME" \| "CAA"` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `region` | `"us" \| "eu"` | yes | | | `return_path_subdomain` | `string` | yes | | | `status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | | `tls_mode` | `"opportunistic" \| "enforced"` | yes | | | `tracking_issues` | `array` | yes | | | `tracking_issues[].fix` | `string` | yes | | | `tracking_issues[].message` | `string` | yes | | | `tracking_issues[].record` | `"TRACKING" \| "TRACKING_CAA"` | yes | | | `tracking_subdomain` | `string` | yes | | | `verified_at` | `string \| null` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `"spf_conflict" \| "spf_lookup_limit" \| "legacy_region"` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].merged` | `string \| null` | yes | | | `warnings[].message` | `string` | yes | | | `warnings[].observed` | `string` | yes | | | `zone` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`domain_field_immutable`](https://agentisend.com/docs/errors#domain_field_immutable) (422) — Name, region, and return-path cannot change on an existing domain. **Fix:** Add a new domain with POST /domains. PATCH /domains/:id accepts click_tracking, open_tracking, tracking_subdomain, and tls_mode only. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`tracking_subdomain_cannot_be_removed`](https://agentisend.com/docs/errors#tracking_subdomain_cannot_be_removed) (422) — The tracking subdomain can be changed, never removed. **Fix:** Pass a new label such as "clicks" in PATCH /domains/:id. To stop counting opens and clicks, turn those switches off instead. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-domains-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-domains-id # DELETE /domains/{id} Remove a domain and its records. Messages already sent keep their history. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `delete-domains-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-domains-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains-id-connect # GET /domains/{id}/connect Alias of GET /domains/:id/setup. Domain Connect: detect the DNS provider and hand back the exact records to add. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/connect \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "commands": { "cloudflare": [], "gcloud": [], "route53": {} }, "deep_link": "example", "detected": false, "domain": "example", "nameservers": [], "provider": { "dnsConsoleUrl": "example", "id": "example", "name": "example" }, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "records": [], "zone": "example", "zone_file": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/connect', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/connect' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains-id-connect` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `commands` | `object` | yes | | | `commands.cloudflare` | `array` | yes | | | `commands.gcloud` | `array` | yes | | | `commands.route53` | `object` | yes | | | `deep_link` | `string \| null` | yes | | | `detected` | `boolean` | yes | | | `domain` | `string` | yes | | | `nameservers` | `array` | yes | | | `provider` | `object \| null` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `records` | `array` | yes | | | `records[].action` | `"add" \| "edit" \| "none" \| "check"` | yes | add: publish value. edit: a record of this kind is already there (current) — change it to value instead of adding a second. none: already in place. check: the current records could not be read; see note. | | `records[].current` | `string \| null` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].note` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].record` | `string` | yes | | | `records[].required` | `boolean` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `string` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `zone` | `string` | yes | | | `zone_file` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains-id-connect — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains-id-events # GET /domains/{id}/events Newest-first timeline for one domain. Rows cover added, the first DNS check, each required record found or lost, verified, no longer verified, the 72-hour window closing, and deleted. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains-id-events` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].detail` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].occurred_at` | `string` | yes | | | `data[].type` | `"domain.added" \| "domain.first_check" \| "domain.record_seen" \| "domain.record_lost" \| "domain.verified" \| "domain.demoted" \| "domain.window_closed" \| "domain.deleted"` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains-id-events — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains-id-setup # GET /domains/{id}/setup One-shot DNS setup: zone file, copy-paste commands, provider detection, and every record with host, zone, value_strings. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/setup \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "commands": { "cloudflare": [], "gcloud": [], "route53": {} }, "deep_link": "example", "detected": false, "domain": "example", "nameservers": [], "provider": { "dnsConsoleUrl": "example", "id": "example", "name": "example" }, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "records": [], "zone": "example", "zone_file": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/setup', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/setup' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains-id-setup` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `commands` | `object` | yes | | | `commands.cloudflare` | `array` | yes | | | `commands.gcloud` | `array` | yes | | | `commands.route53` | `object` | yes | | | `deep_link` | `string \| null` | yes | | | `detected` | `boolean` | yes | | | `domain` | `string` | yes | | | `nameservers` | `array` | yes | | | `provider` | `object \| null` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `records` | `array` | yes | | | `records[].action` | `"add" \| "edit" \| "none" \| "check"` | yes | add: publish value. edit: a record of this kind is already there (current) — change it to value instead of adding a second. none: already in place. check: the current records could not be read; see note. | | `records[].current` | `string \| null` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].note` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].record` | `string` | yes | | | `records[].required` | `boolean` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `string` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `zone` | `string` | yes | | | `zone_file` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains-id-setup — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-domains-id-verify # POST /domains/{id}/verify Re-check every record and update the domain’s status. ## Request ```bash curl -sS -X POST https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/verify \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "click_tracking": false, "created_at": "2026-09-04T09:14:00.000Z", "dkim_selector": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "open_tracking": false, "provider_hints": { "cloudflare": "example", "godaddy": "example", "namecheap": "example", "route53": "example" }, "recent_events": [], "records": [], "region": "us", "return_path_subdomain": "example", "status": "pending", "tls_mode": "opportunistic", "tracking_issues": [], "tracking_subdomain": "example", "verified_at": "2026-09-04T09:14:00.000Z", "warnings": [], "zone": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/verify', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/verify' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `post-domains-id-verify` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `click_tracking` | `boolean` | yes | | | `created_at` | `string` | yes | | | `dkim_selector` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `open_tracking` | `boolean` | yes | | | `provider_hints` | `object` | yes | | | `provider_hints.cloudflare` | `string` | yes | | | `provider_hints.godaddy` | `string` | yes | | | `provider_hints.namecheap` | `string` | yes | | | `provider_hints.route53` | `string` | yes | | | `recent_events` | `array` | yes | | | `recent_events[].detail` | `string` | yes | | | `recent_events[].id` | `string` | yes | | | `recent_events[].occurred_at` | `string` | yes | | | `recent_events[].type` | `"domain.added" \| "domain.first_check" \| "domain.record_seen" \| "domain.record_lost" \| "domain.verified" \| "domain.demoted" \| "domain.window_closed" \| "domain.deleted"` | yes | | | `records` | `array` | yes | | | `records[].checked_at` | `string \| null` | yes | | | `records[].fix` | `string` | yes | | | `records[].host` | `string` | yes | | | `records[].name` | `string` | yes | | | `records[].name_relative` | `string` | yes | | | `records[].observed` | `string \| null` | yes | | | `records[].priority` | `integer \| null` | yes | | | `records[].reason` | `"ok" \| "not_found" \| "unreachable" \| "mismatch" \| "not_published" \| null` | yes | | | `records[].record` | `"SPF" \| "DKIM" \| "DMARC" \| "RETURN_PATH" \| "TRACKING" \| "RECEIVING" \| "TRACKING_CAA"` | yes | | | `records[].required` | `boolean` | yes | | | `records[].status` | `"pending" \| "verified" \| "failed" \| "recommended"` | yes | | | `records[].ttl` | `integer` | yes | | | `records[].type` | `"TXT" \| "MX" \| "CNAME" \| "CAA"` | yes | | | `records[].value` | `string` | yes | | | `records[].value_bind` | `string` | yes | | | `records[].value_strings` | `array` | yes | | | `region` | `"us" \| "eu"` | yes | | | `return_path_subdomain` | `string` | yes | | | `status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | | `tls_mode` | `"opportunistic" \| "enforced"` | yes | | | `tracking_issues` | `array` | yes | | | `tracking_issues[].fix` | `string` | yes | | | `tracking_issues[].message` | `string` | yes | | | `tracking_issues[].record` | `"TRACKING" \| "TRACKING_CAA"` | yes | | | `tracking_subdomain` | `string` | yes | | | `verified_at` | `string \| null` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `"spf_conflict" \| "spf_lookup_limit" \| "legacy_region"` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].merged` | `string \| null` | yes | | | `warnings[].message` | `string` | yes | | | `warnings[].observed` | `string` | yes | | | `zone` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`domain_verified_elsewhere`](https://agentisend.com/docs/errors#domain_verified_elsewhere) (409) — This domain is already verified on another account. **Fix:** Contact support to move the domain. We cannot verify it here while another account already has it verified. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_domain_blocked`](https://agentisend.com/docs/errors#sending_domain_blocked) (403) — This domain cannot send through AgentiSend. **Fix:** Send from a different domain you own. If you believe this is a mistake, contact support and name the domain. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-domains-id-verify — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-domains-id-wait # GET /domains/{id}/wait Long-poll a domain until it is verified or failed, or until timeout (0–25 seconds). timeout=0 is a snapshot. Does not re-check DNS; the server checks on its own. ## Request ```bash curl -sS -X GET https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/wait \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "deadline": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "next_poll_seconds": 0, "progress": { "required_total": 0, "required_verified": 0 }, "reason": "ok", "status": "pending" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/wait', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/domains/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/wait' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: domains. Generated from `openapi.json`; the anchor `get-domains-id-wait` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `timeout` query · `integer` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deadline` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `next_poll_seconds` | `integer` | yes | | | `progress` | `object` | yes | | | `progress.required_total` | `integer` | yes | | | `progress.required_verified` | `integer` | yes | | | `reason` | `"ok" \| "not_found" \| "unreachable" \| "mismatch" \| "dkim_key_mismatch" \| "domain_check_window_expired" \| null` | yes | | | `status` | `"pending" \| "verified" \| "failed" \| "partially_verified" \| "partially_failed"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-domains-id-wait — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails # GET /emails List messages. Every console filter is a query param here. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails` is the id the console's error `fix` links point at. ## Parameters - `status` query · `string` · optional - `q` query · `string` · optional - `from` query · `string` · optional - `to` query · `string` · optional - `tag` query · `string` · optional - `domain` query · `string` · optional - `bounce_class` query · `"hard" | "soft" | "block" | "policy"` · optional - `api_key_id` query · `string` · optional - `template_id` query · `string` · optional - `since` query · `string` · optional - `until` query · `string` · optional - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].api_key_id` | `string \| null` | yes | | | `data[].attachments` | `array \| null` | yes | | | `data[].bcc` | `array \| null` | yes | | | `data[].cc` | `array \| null` | yes | | | `data[].created_at` | `string` | yes | | | `data[].domain` | `string` | yes | | | `data[].from` | `string` | yes | | | `data[].headers` | `object \| null` | yes | | | `data[].html` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_event` | `"queued" \| "scheduled" \| "sent" \| "delivered" \| "delivery_delayed" \| "bounced" \| "complained" \| "opened" \| "clicked" \| "failed" \| "canceled" \| "suppressed" \| null` | yes | | | `data[].object` | `string` | yes | | | `data[].provider_message_id` | `string \| null` | yes | | | `data[].reply_to` | `array \| null` | yes | | | `data[].scheduled_at` | `string \| null` | yes | | | `data[].status` | `"queued" \| "scheduled" \| "sent" \| "delivered" \| "delivery_delayed" \| "bounced" \| "complained" \| "opened" \| "clicked" \| "failed" \| "canceled" \| "suppressed"` | yes | | | `data[].subject` | `string` | yes | | | `data[].tags` | `object \| null` | yes | | | `data[].template_id` | `string \| null` | yes | | | `data[].template_version` | `integer \| null` | yes | | | `data[].text` | `string \| null` | yes | | | `data[].to` | `array` | yes | | | `data[].updated_at` | `string` | yes | | | `data[].warnings` | `array` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails # POST /emails Send an email. Returns the message id; delivery happens on the queue. Before a domain is verified, from onboarding@agentisend.com delivers only to this account's member sign-in addresses (20 per UTC day, no cc/bcc/attachments/tracking/extra headers). Addresses ending in @simulator.agentisend.com cost nothing and reach nobody. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}' ``` ```json Response 201 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "simulated": true, "warnings": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails', body: { "from": "billing@yourdomain.com", "to": "delivered@simulator.agentisend.com", "subject": "Your receipt", "text": "Thanks — the details are attached." }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachments` | `array` | no | Files to attach. At most 100, and 40 MB of base64 content together. | | `attachments[].content` | `string \| object \| array` | no | Base64 text, a byte array, or a Buffer. Provide content or path. | | `attachments[].contentId` | `string` | no | Same as content_id. content_id wins if both are sent. | | `attachments[].contentType` | `string` | no | Same as content_type. content_type wins if both are sent. | | `attachments[].content_id` | `string` | no | Referenced from HTML as cid: this value, for an inline image. | | `attachments[].content_type` | `string` | no | Media type, such as application/pdf. No parameters. | | `attachments[].filename` | `string` | no | File name shown to the recipient. | | `attachments[].path` | `string` | no | https URL of a hosted file. Fetched when the send is accepted. | | `bcc` | `string \| array` | no | Blind copy recipients. | | `cc` | `string \| array` | no | Copy recipients. | | `expires_at` | `string` | no | When a held send stops waiting for a person. At most 7 days ahead. Ignored when the send is not held. | | `from` | `string` | yes | Sender. A verified domain, or the onboarding address while a domain is still pending. | | `headers` | `object` | no | Extra headers. Names that this API sets itself are replaced. | | `html` | `string` | no | HTML body. Provide html, text, or a template. | | `replyTo` | `string \| array` | no | Same as reply_to. reply_to wins if both are sent. | | `reply_to` | `string \| array` | no | Reply-To addresses. | | `scheduledAt` | `string` | no | Resend Node SDK name for scheduled_at. | | `scheduled_at` | `string` | no | ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead. | | `subject` | `string` | no | Required unless template or template_id names a published template that has a subject. | | `tags` | `object \| array` | no | Tags as an object of name to value, or a list of {name, value}. | | `template` | `object` | no | A published template, instead of html or text. | | `template.id` | `string` | yes | Published template id. An alias is refused; use the id from GET /templates. | | `template.variables` | `object` | no | Values for the template placeholders. A string or a number per name. | | `template_id` | `string` | no | Published template to render, instead of html or text. | | `template_values` | `object` | no | Values for the template placeholders. | | `text` | `string` | no | Plain-text body. Provide html, text, or a template. | | `timezone` | `string` | no | Time zone for a scheduled_at phrase such as "tomorrow 9am". An ISO time ignores this. Example: America/Los_Angeles. Omitted phrases are read in UTC. | | `to` | `string \| array` | yes | Recipients. One address or a list. | | `topicId` | `string` | no | Resend Node SDK name for topic_id. | | `topic_id` | `string` | no | Subscription topic. Recipients who opted out of it are not sent this message. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `402` — A budget, quota or plan limit would be exceeded. Codes: overage_cap_reached, daily_limit_reached, agent_budget_exceeded, plan_limit_reached. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `simulated` | `boolean` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `string` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].message` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`account_sandboxed`](https://agentisend.com/docs/errors#account_sandboxed) (403) — This account is in the sandbox and may only send to its own verified domains. **Fix:** Verify the recipient domain with POST /domains + POST /domains/:id/verify, or file POST /trust/appeal for a person to review this account. - [`account_suspended`](https://agentisend.com/docs/errors#account_suspended) (403) — This account is suspended. **Fix:** Read the enforcement policy at https://agentisend.com/policy/enforcement, then contact hello@agentisend.com to appeal. - [`agent_budget_exceeded`](https://agentisend.com/docs/errors#agent_budget_exceeded) (402) — Key budget for the current period is exhausted. **Fix:** Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own. - [`approval_required`](https://agentisend.com/docs/errors#approval_required) (403) — This action requires human approval before it executes. **Fix:** Do not send it again: a person approves or rejects it in the console under Agents → Approvals, and approving sends it — the message then appears in GET /emails. action_id in this error names the held send; the key that asked cannot approve itself, and a retry waits on the same approval. - [`content_refused`](https://agentisend.com/docs/errors#content_refused) (422) — This email was refused because of what it contains. **Fix:** The message names the field and what matched in it. Remove or change that part and send again. POST /emails/preflight runs the same check without sending anything. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`daily_limit_reached`](https://agentisend.com/docs/errors#daily_limit_reached) (402) — This account has sent its daily allowance of emails; sending resumes at 00:00 UTC. **Fix:** Wait for 00:00 UTC, or upgrade in Settings → Billing — every paid plan has no daily cap. - [`domain_not_verified`](https://agentisend.com/docs/errors#domain_not_verified) (403) — This sending domain is not verified. **Fix:** If it is pending, publish the required records from GET /domains/:id; checks continue for 72 hours. Test now by sending to an address ending in @simulator.agentisend.com. If it is not registered, POST /domains first. If it is failed, GET /domains/:id names the record to fix, then POST /domains/:id/verify to reopen the window. - [`domain_scope_violation`](https://agentisend.com/docs/errors#domain_scope_violation) (403) — This API key may only send from its scoped domain. **Fix:** Send from the scoped domain, or create a key without a domain scope via POST /api-keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_attachment`](https://agentisend.com/docs/errors#invalid_attachment) (422, invalid_attachment) — Each attachment needs content (base64) or path. **Fix:** Provide attachment.content or attachment.path in POST /emails. - [`invalid_from_address`](https://agentisend.com/docs/errors#invalid_from_address) (422, invalid_from_address) — The from field is not a valid address. **Fix:** Use a plain address or "Name " format in POST /emails. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`kill_switch_active`](https://agentisend.com/docs/errors#kill_switch_active) (403) — This API key has been paused with the kill switch. **Fix:** Read GET /trust/standing for why it was paused. Only a person signed in to the console can resume it; the paused key cannot resume itself. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`onboarding_daily_cap_reached`](https://agentisend.com/docs/errors#onboarding_daily_cap_reached) (429) — This account has used its 20 onboarding emails for today. **Fix:** Wait until tomorrow (UTC), or verify a domain with POST /domains and send from that domain. - [`onboarding_recipient_not_a_member`](https://agentisend.com/docs/errors#onboarding_recipient_not_a_member) (403) — The onboarding sender can only mail this account's own members — the addresses they sign in with. **Fix:** Send to a member sign-in address, or verify a domain with POST /domains and send from that domain. - [`onboarding_sender_unavailable`](https://agentisend.com/docs/errors#onboarding_sender_unavailable) (403) — The onboarding sender is not available. **Fix:** Send to an address ending in @simulator.agentisend.com, or verify a domain with POST /domains and send from that domain. - [`onboarding_shape_refused`](https://agentisend.com/docs/errors#onboarding_shape_refused) (422) — The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers. **Fix:** Omit those fields, or verify a domain with POST /domains and send from that domain. - [`overage_cap_reached`](https://agentisend.com/docs/errors#overage_cap_reached) (402) — This account has used every email in its plan and every extra email its owner allowed this period. **Fix:** Raise the overage ceiling or move up a plan in Settings → Billing, or wait until the reset date in this error. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_limit_reached`](https://agentisend.com/docs/errors#plan_limit_reached) (402) — This account has used every email included in its plan for the current period. **Fix:** Upgrade in Settings → Billing, or wait until the reset date in this error. - [`rate_ceiling_exceeded`](https://agentisend.com/docs/errors#rate_ceiling_exceeded) (429) — Per-minute rate ceiling for this key is exhausted. **Fix:** Wait the seconds below and send the same request again. Raising the ceiling is a person’s decision, made in the console; a key cannot raise its own. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`recipient_blocklisted`](https://agentisend.com/docs/errors#recipient_blocklisted) (422) — This recipient is blocked. **Fix:** Send to a different address. An address ending in @simulator.agentisend.com is never blocked. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_paused_everywhere`](https://agentisend.com/docs/errors#sending_paused_everywhere) (503) — Sending is paused for every account while AgentiSend handles an incident. Nothing was sent or charged. **Fix:** Retry the same request, with the same Idempotency-Key, after the seconds given in Retry-After. Scheduled sends wait and go out once sending resumes. - [`suppressed_recipient`](https://agentisend.com/docs/errors#suppressed_recipient) (422) — Recipient is on the account suppression list. **Fix:** GET /suppressions says which address and why. A hard bounce you have fixed can be cleared with DELETE /suppressions/:id; an unsubscribe or a spam complaint cannot — that address asked not to be contacted. - [`trust_paused`](https://agentisend.com/docs/errors#trust_paused) (403) — Sending is paused by the trust system. **Fix:** Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal. - [`trust_throttled`](https://agentisend.com/docs/errors#trust_throttled) (429) — This account is being throttled by the trust ladder. **Fix:** Send volume is temporarily capped because deliverability metrics crossed a published threshold. Check GET /trust/standing for the metric and value, file POST /trust/appeal if this is unexpected. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. - [`young_domain_held`](https://agentisend.com/docs/errors#young_domain_held) (403) — Mail from this domain waits for a review. It was registered less than 30 days ago. **Fix:** Mail from your other verified domains still sends. Write to hello@agentisend.com and name this domain. --- Source: https://agentisend.com/docs/api/post-emails — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-batch # POST /emails/batch Send up to 500 emails. Each item succeeds or fails on its own — read data[i].status. x-batch-validation: strict (all or none) or permissive (ids and errors). ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/batch \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '[{"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}]' ``` ```json Response 200 { "data": [ { "index": 0, "status": "accepted", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "simulated": true } ] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/batch', body: [ { "from": "billing@yourdomain.com", "to": "delivered@simulator.agentisend.com", "subject": "Your receipt", "text": "Thanks — the details are attached." } ], }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/batch' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps([{"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}]).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-batch` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `[].attachments` | `array` | no | Files to attach. At most 100, and 40 MB of base64 content together. | | `[].attachments[].content` | `string \| object \| array` | no | Base64 text, a byte array, or a Buffer. Provide content or path. | | `[].attachments[].contentId` | `string` | no | Same as content_id. content_id wins if both are sent. | | `[].attachments[].contentType` | `string` | no | Same as content_type. content_type wins if both are sent. | | `[].attachments[].content_id` | `string` | no | Referenced from HTML as cid: this value, for an inline image. | | `[].attachments[].content_type` | `string` | no | Media type, such as application/pdf. No parameters. | | `[].attachments[].filename` | `string` | no | File name shown to the recipient. | | `[].attachments[].path` | `string` | no | https URL of a hosted file. Fetched when the send is accepted. | | `[].bcc` | `string \| array` | no | Blind copy recipients. | | `[].cc` | `string \| array` | no | Copy recipients. | | `[].expires_at` | `string` | no | When a held send stops waiting for a person. At most 7 days ahead. Ignored when the send is not held. | | `[].from` | `string` | yes | Sender. A verified domain, or the onboarding address while a domain is still pending. | | `[].headers` | `object` | no | Extra headers. Names that this API sets itself are replaced. | | `[].html` | `string` | no | HTML body. Provide html, text, or a template. | | `[].replyTo` | `string \| array` | no | Same as reply_to. reply_to wins if both are sent. | | `[].reply_to` | `string \| array` | no | Reply-To addresses. | | `[].scheduledAt` | `string` | no | Resend Node SDK name for scheduled_at. | | `[].scheduled_at` | `string` | no | ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead. | | `[].subject` | `string` | no | Required unless template or template_id names a published template that has a subject. | | `[].tags` | `object \| array` | no | Tags as an object of name to value, or a list of {name, value}. | | `[].template` | `object` | no | A published template, instead of html or text. | | `[].template.id` | `string` | yes | Published template id. An alias is refused; use the id from GET /templates. | | `[].template.variables` | `object` | no | Values for the template placeholders. A string or a number per name. | | `[].template_id` | `string` | no | Published template to render, instead of html or text. | | `[].template_values` | `object` | no | Values for the template placeholders. | | `[].text` | `string` | no | Plain-text body. Provide html, text, or a template. | | `[].timezone` | `string` | no | Time zone for a scheduled_at phrase such as "tomorrow 9am". An ISO time ignores this. Example: America/Los_Angeles. Omitted phrases are read in UTC. | | `[].to` | `string \| array` | yes | Recipients. One address or a list. | | `[].topicId` | `string` | no | Resend Node SDK name for topic_id. | | `[].topic_id` | `string` | no | Subscription topic. Recipients who opted out of it are not sent this message. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `402` — A budget, quota or plan limit would be exceeded. Codes: overage_cap_reached, daily_limit_reached, agent_budget_exceeded, plan_limit_reached. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].error` | `object` | no | | | `data[].id` | `string` | no | | | `data[].index` | `integer` | yes | | | `data[].simulated` | `boolean` | no | | | `data[].status` | `"accepted" \| "rejected"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`account_sandboxed`](https://agentisend.com/docs/errors#account_sandboxed) (403) — This account is in the sandbox and may only send to its own verified domains. **Fix:** Verify the recipient domain with POST /domains + POST /domains/:id/verify, or file POST /trust/appeal for a person to review this account. - [`account_suspended`](https://agentisend.com/docs/errors#account_suspended) (403) — This account is suspended. **Fix:** Read the enforcement policy at https://agentisend.com/policy/enforcement, then contact hello@agentisend.com to appeal. - [`agent_budget_exceeded`](https://agentisend.com/docs/errors#agent_budget_exceeded) (402) — Key budget for the current period is exhausted. **Fix:** Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own. - [`approval_required`](https://agentisend.com/docs/errors#approval_required) (403) — This action requires human approval before it executes. **Fix:** Do not send it again: a person approves or rejects it in the console under Agents → Approvals, and approving sends it — the message then appears in GET /emails. action_id in this error names the held send; the key that asked cannot approve itself, and a retry waits on the same approval. - [`content_refused`](https://agentisend.com/docs/errors#content_refused) (422) — This email was refused because of what it contains. **Fix:** The message names the field and what matched in it. Remove or change that part and send again. POST /emails/preflight runs the same check without sending anything. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`daily_limit_reached`](https://agentisend.com/docs/errors#daily_limit_reached) (402) — This account has sent its daily allowance of emails; sending resumes at 00:00 UTC. **Fix:** Wait for 00:00 UTC, or upgrade in Settings → Billing — every paid plan has no daily cap. - [`domain_not_verified`](https://agentisend.com/docs/errors#domain_not_verified) (403) — This sending domain is not verified. **Fix:** If it is pending, publish the required records from GET /domains/:id; checks continue for 72 hours. Test now by sending to an address ending in @simulator.agentisend.com. If it is not registered, POST /domains first. If it is failed, GET /domains/:id names the record to fix, then POST /domains/:id/verify to reopen the window. - [`domain_scope_violation`](https://agentisend.com/docs/errors#domain_scope_violation) (403) — This API key may only send from its scoped domain. **Fix:** Send from the scoped domain, or create a key without a domain scope via POST /api-keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_attachment`](https://agentisend.com/docs/errors#invalid_attachment) (422, invalid_attachment) — Each attachment needs content (base64) or path. **Fix:** Provide attachment.content or attachment.path in POST /emails. - [`invalid_from_address`](https://agentisend.com/docs/errors#invalid_from_address) (422, invalid_from_address) — The from field is not a valid address. **Fix:** Use a plain address or "Name " format in POST /emails. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`kill_switch_active`](https://agentisend.com/docs/errors#kill_switch_active) (403) — This API key has been paused with the kill switch. **Fix:** Read GET /trust/standing for why it was paused. Only a person signed in to the console can resume it; the paused key cannot resume itself. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`onboarding_daily_cap_reached`](https://agentisend.com/docs/errors#onboarding_daily_cap_reached) (429) — This account has used its 20 onboarding emails for today. **Fix:** Wait until tomorrow (UTC), or verify a domain with POST /domains and send from that domain. - [`onboarding_recipient_not_a_member`](https://agentisend.com/docs/errors#onboarding_recipient_not_a_member) (403) — The onboarding sender can only mail this account's own members — the addresses they sign in with. **Fix:** Send to a member sign-in address, or verify a domain with POST /domains and send from that domain. - [`onboarding_sender_unavailable`](https://agentisend.com/docs/errors#onboarding_sender_unavailable) (403) — The onboarding sender is not available. **Fix:** Send to an address ending in @simulator.agentisend.com, or verify a domain with POST /domains and send from that domain. - [`onboarding_shape_refused`](https://agentisend.com/docs/errors#onboarding_shape_refused) (422) — The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers. **Fix:** Omit those fields, or verify a domain with POST /domains and send from that domain. - [`overage_cap_reached`](https://agentisend.com/docs/errors#overage_cap_reached) (402) — This account has used every email in its plan and every extra email its owner allowed this period. **Fix:** Raise the overage ceiling or move up a plan in Settings → Billing, or wait until the reset date in this error. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_limit_reached`](https://agentisend.com/docs/errors#plan_limit_reached) (402) — This account has used every email included in its plan for the current period. **Fix:** Upgrade in Settings → Billing, or wait until the reset date in this error. - [`rate_ceiling_exceeded`](https://agentisend.com/docs/errors#rate_ceiling_exceeded) (429) — Per-minute rate ceiling for this key is exhausted. **Fix:** Wait the seconds below and send the same request again. Raising the ceiling is a person’s decision, made in the console; a key cannot raise its own. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`recipient_blocklisted`](https://agentisend.com/docs/errors#recipient_blocklisted) (422) — This recipient is blocked. **Fix:** Send to a different address. An address ending in @simulator.agentisend.com is never blocked. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_paused_everywhere`](https://agentisend.com/docs/errors#sending_paused_everywhere) (503) — Sending is paused for every account while AgentiSend handles an incident. Nothing was sent or charged. **Fix:** Retry the same request, with the same Idempotency-Key, after the seconds given in Retry-After. Scheduled sends wait and go out once sending resumes. - [`suppressed_recipient`](https://agentisend.com/docs/errors#suppressed_recipient) (422) — Recipient is on the account suppression list. **Fix:** GET /suppressions says which address and why. A hard bounce you have fixed can be cleared with DELETE /suppressions/:id; an unsubscribe or a spam complaint cannot — that address asked not to be contacted. - [`trust_paused`](https://agentisend.com/docs/errors#trust_paused) (403) — Sending is paused by the trust system. **Fix:** Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal. - [`trust_throttled`](https://agentisend.com/docs/errors#trust_throttled) (429) — This account is being throttled by the trust ladder. **Fix:** Send volume is temporarily capped because deliverability metrics crossed a published threshold. Check GET /trust/standing for the metric and value, file POST /trust/appeal if this is unexpected. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. - [`young_domain_held`](https://agentisend.com/docs/errors#young_domain_held) (403) — Mail from this domain waits for a review. It was registered less than 30 days ago. **Fix:** Mail from your other verified domains still sends. Write to hello@agentisend.com and name this domain. --- Source: https://agentisend.com/docs/api/post-emails-batch — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-bulk-cancel # POST /emails/bulk-cancel Cancel many emails at once: by explicit ids or every scheduled/queued email before a time. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/bulk-cancel \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"ids":["9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42"]}' ``` ```json Response 200 { "canceled": [], "skipped": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/bulk-cancel', body: { "ids": [ "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/bulk-cancel' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"ids":["9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42"]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-bulk-cancel` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `before` | `string` | no | Cancel scheduled and queued messages accepted before this time. | | `ids` | `array` | no | Messages to cancel. At most 500. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `canceled` | `array` | yes | | | `skipped` | `array` | yes | | | `skipped[].id` | `string` | yes | | | `skipped[].status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-emails-bulk-cancel — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-export-csv # GET /emails/export.csv The message log as CSV — yours, take it with you. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/export.csv \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/export.csv', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/export.csv' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-export-csv` is the id the console's error `fix` links point at. ## Parameters - `status` query · `string` · optional - `q` query · `string` · optional - `from` query · `string` · optional - `to` query · `string` · optional - `tag` query · `string` · optional - `domain` query · `string` · optional - `bounce_class` query · `"hard" | "soft" | "block" | "policy"` · optional - `api_key_id` query · `string` · optional - `template_id` query · `string` · optional - `since` query · `string` · optional - `until` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-export-csv — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-lint # POST /emails/lint Deliverability lint without sending: a 0-100 placement score plus every finding with its fix. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/lint \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"from":"example","to":["example"]}' ``` ```json Response 200 { "findings": [], "score": 0 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/lint', body: { "from": "example", "to": [ "example" ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/lint' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"from":"example","to":["example"]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-lint` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `from` | `string` | yes | Sender address the lint reads. | | `headers` | `object` | no | Headers to score. | | `html` | `string` | no | HTML body to score. | | `subject` | `string` | no | Subject. Empty is allowed here, because this call sends nothing. | | `text` | `string` | no | Plain-text body to score. | | `to` | `array` | yes | Recipient addresses. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `findings` | `array` | yes | | | `findings[].fix` | `string` | yes | | | `findings[].message` | `string` | yes | | | `findings[].rule` | `string` | yes | | | `findings[].severity` | `"error" \| "warning" \| "info"` | yes | | | `score` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-emails-lint — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-metrics # GET /emails/metrics Alias of GET /metrics. start_date and end_date are accepted as names for since and until. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/metrics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "by_api_key": [], "by_domain": [], "event": "sent", "previous": { "bounced": -9007199254740991, "clicks": -9007199254740991, "complaints": -9007199254740991, "delivered": -9007199254740991, "opens": -9007199254740991, "sent": -9007199254740991 }, "series": [], "since": "example", "totals": { "bounced": -9007199254740991, "clicks": -9007199254740991, "complaints": -9007199254740991, "delivered": -9007199254740991, "opens": -9007199254740991, "sent": -9007199254740991 }, "until": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/metrics', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/metrics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: metrics. Generated from `openapi.json`; the anchor `get-emails-metrics` is the id the console's error `fix` links point at. ## Parameters - `since` query · `string` · optional - `until` query · `string` · optional - `start_date` query · `string` · optional - `end_date` query · `string` · optional - `group_by` query · `string` · optional - `event` query · `"sent" | "delivered" | "bounced" | "complained" | "opened" | "clicked"` · optional - `domain` query · `string` · optional - `api_key_id` query · `string | string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `by_api_key` | `array` | yes | | | `by_api_key[].bounced` | `integer` | yes | | | `by_api_key[].complained` | `integer` | yes | | | `by_api_key[].delivered` | `integer` | yes | | | `by_api_key[].id` | `string` | yes | | | `by_api_key[].name` | `string` | yes | | | `by_api_key[].sent` | `integer` | yes | | | `by_api_key[].series` | `array` | yes | | | `by_domain` | `array` | yes | | | `by_domain[].bounced` | `integer` | yes | | | `by_domain[].complained` | `integer` | yes | | | `by_domain[].delivered` | `integer` | yes | | | `by_domain[].id` | `string` | yes | | | `by_domain[].name` | `string` | yes | | | `by_domain[].sent` | `integer` | yes | | | `by_domain[].series` | `array` | yes | | | `event` | `"sent" \| "delivered" \| "bounced" \| "complained" \| "opened" \| "clicked" \| null` | yes | | | `previous` | `object` | yes | | | `previous.bounced` | `integer` | yes | | | `previous.clicks` | `integer` | yes | | | `previous.complaints` | `integer` | yes | | | `previous.delivered` | `integer` | yes | | | `previous.opens` | `integer` | yes | | | `previous.sent` | `integer` | yes | | | `series` | `array` | yes | | | `series[].bounced` | `integer` | yes | | | `series[].clicks` | `integer` | yes | | | `series[].complaints` | `integer` | yes | | | `series[].day` | `string` | yes | | | `series[].delivered` | `integer` | yes | | | `series[].opens` | `integer` | yes | | | `series[].sent` | `integer` | yes | | | `since` | `string` | yes | | | `totals` | `object` | yes | | | `totals.bounced` | `integer` | yes | | | `totals.clicks` | `integer` | yes | | | `totals.complaints` | `integer` | yes | | | `totals.delivered` | `integer` | yes | | | `totals.opens` | `integer` | yes | | | `totals.sent` | `integer` | yes | | | `until` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-metrics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-preflight # POST /emails/preflight Run EVERY send gate without sending: domain, sandbox, trust, suppression, budget, loop, content, verifier. The report matches what POST /emails would do, byte for byte — one code path. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/preflight \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}' ``` ```json Response 200 { "ok": true, "simulated": true, "error": null, "checks": { "validation": { "ok": true }, "domain_scope": { "ok": true }, "suppression": { "ok": true, "kept": [], "suppressed": [] }, "account": { "ok": true, "status": "approved" }, "trust": { "ok": true, "state": "ok" }, "verifier": { "ok": true, "risky": [] }, "domain": { "ok": true, "registered": false, "status": null }, "budget": { "ok": true, "remaining": null, "would_cost": 0, "simulated": true }, "loop": { "ok": true, "decision": null }, "content": { "ok": true, "verdict": "clean", "findings": [] } } } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/preflight', body: { "from": "billing@yourdomain.com", "to": "delivered@simulator.agentisend.com", "subject": "Your receipt", "text": "Thanks — the details are attached." }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/preflight' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-preflight` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachments` | `array` | no | Files to attach. At most 100, and 40 MB of base64 content together. | | `attachments[].content` | `string \| object \| array` | no | Base64 text, a byte array, or a Buffer. Provide content or path. | | `attachments[].contentId` | `string` | no | Same as content_id. content_id wins if both are sent. | | `attachments[].contentType` | `string` | no | Same as content_type. content_type wins if both are sent. | | `attachments[].content_id` | `string` | no | Referenced from HTML as cid: this value, for an inline image. | | `attachments[].content_type` | `string` | no | Media type, such as application/pdf. No parameters. | | `attachments[].filename` | `string` | no | File name shown to the recipient. | | `attachments[].path` | `string` | no | https URL of a hosted file. Fetched when the send is accepted. | | `bcc` | `string \| array` | no | Blind copy recipients. | | `cc` | `string \| array` | no | Copy recipients. | | `expires_at` | `string` | no | When a held send stops waiting for a person. At most 7 days ahead. Ignored when the send is not held. | | `from` | `string` | yes | Sender. A verified domain, or the onboarding address while a domain is still pending. | | `headers` | `object` | no | Extra headers. Names that this API sets itself are replaced. | | `html` | `string` | no | HTML body. Provide html, text, or a template. | | `replyTo` | `string \| array` | no | Same as reply_to. reply_to wins if both are sent. | | `reply_to` | `string \| array` | no | Reply-To addresses. | | `scheduledAt` | `string` | no | Resend Node SDK name for scheduled_at. | | `scheduled_at` | `string` | no | ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead. | | `subject` | `string` | no | Required unless template or template_id names a published template that has a subject. | | `tags` | `object \| array` | no | Tags as an object of name to value, or a list of {name, value}. | | `template` | `object` | no | A published template, instead of html or text. | | `template.id` | `string` | yes | Published template id. An alias is refused; use the id from GET /templates. | | `template.variables` | `object` | no | Values for the template placeholders. A string or a number per name. | | `template_id` | `string` | no | Published template to render, instead of html or text. | | `template_values` | `object` | no | Values for the template placeholders. | | `text` | `string` | no | Plain-text body. Provide html, text, or a template. | | `timezone` | `string` | no | Time zone for a scheduled_at phrase such as "tomorrow 9am". An ISO time ignores this. Example: America/Los_Angeles. Omitted phrases are read in UTC. | | `to` | `string \| array` | yes | Recipients. One address or a list. | | `topicId` | `string` | no | Resend Node SDK name for topic_id. | | `topic_id` | `string` | no | Subscription topic. Recipients who opted out of it are not sent this message. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `402` — A budget, quota or plan limit would be exceeded. Codes: overage_cap_reached, daily_limit_reached, agent_budget_exceeded, plan_limit_reached. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `checks` | `object` | yes | | | `error` | `object \| null` | yes | | | `ok` | `boolean` | yes | | | `simulated` | `boolean` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`account_sandboxed`](https://agentisend.com/docs/errors#account_sandboxed) (403) — This account is in the sandbox and may only send to its own verified domains. **Fix:** Verify the recipient domain with POST /domains + POST /domains/:id/verify, or file POST /trust/appeal for a person to review this account. - [`account_suspended`](https://agentisend.com/docs/errors#account_suspended) (403) — This account is suspended. **Fix:** Read the enforcement policy at https://agentisend.com/policy/enforcement, then contact hello@agentisend.com to appeal. - [`agent_budget_exceeded`](https://agentisend.com/docs/errors#agent_budget_exceeded) (402) — Key budget for the current period is exhausted. **Fix:** Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own. - [`approval_required`](https://agentisend.com/docs/errors#approval_required) (403) — This action requires human approval before it executes. **Fix:** Do not send it again: a person approves or rejects it in the console under Agents → Approvals, and approving sends it — the message then appears in GET /emails. action_id in this error names the held send; the key that asked cannot approve itself, and a retry waits on the same approval. - [`content_refused`](https://agentisend.com/docs/errors#content_refused) (422) — This email was refused because of what it contains. **Fix:** The message names the field and what matched in it. Remove or change that part and send again. POST /emails/preflight runs the same check without sending anything. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`daily_limit_reached`](https://agentisend.com/docs/errors#daily_limit_reached) (402) — This account has sent its daily allowance of emails; sending resumes at 00:00 UTC. **Fix:** Wait for 00:00 UTC, or upgrade in Settings → Billing — every paid plan has no daily cap. - [`domain_not_verified`](https://agentisend.com/docs/errors#domain_not_verified) (403) — This sending domain is not verified. **Fix:** If it is pending, publish the required records from GET /domains/:id; checks continue for 72 hours. Test now by sending to an address ending in @simulator.agentisend.com. If it is not registered, POST /domains first. If it is failed, GET /domains/:id names the record to fix, then POST /domains/:id/verify to reopen the window. - [`domain_scope_violation`](https://agentisend.com/docs/errors#domain_scope_violation) (403) — This API key may only send from its scoped domain. **Fix:** Send from the scoped domain, or create a key without a domain scope via POST /api-keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_attachment`](https://agentisend.com/docs/errors#invalid_attachment) (422, invalid_attachment) — Each attachment needs content (base64) or path. **Fix:** Provide attachment.content or attachment.path in POST /emails. - [`invalid_from_address`](https://agentisend.com/docs/errors#invalid_from_address) (422, invalid_from_address) — The from field is not a valid address. **Fix:** Use a plain address or "Name " format in POST /emails. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`kill_switch_active`](https://agentisend.com/docs/errors#kill_switch_active) (403) — This API key has been paused with the kill switch. **Fix:** Read GET /trust/standing for why it was paused. Only a person signed in to the console can resume it; the paused key cannot resume itself. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`onboarding_daily_cap_reached`](https://agentisend.com/docs/errors#onboarding_daily_cap_reached) (429) — This account has used its 20 onboarding emails for today. **Fix:** Wait until tomorrow (UTC), or verify a domain with POST /domains and send from that domain. - [`onboarding_recipient_not_a_member`](https://agentisend.com/docs/errors#onboarding_recipient_not_a_member) (403) — The onboarding sender can only mail this account's own members — the addresses they sign in with. **Fix:** Send to a member sign-in address, or verify a domain with POST /domains and send from that domain. - [`onboarding_sender_unavailable`](https://agentisend.com/docs/errors#onboarding_sender_unavailable) (403) — The onboarding sender is not available. **Fix:** Send to an address ending in @simulator.agentisend.com, or verify a domain with POST /domains and send from that domain. - [`onboarding_shape_refused`](https://agentisend.com/docs/errors#onboarding_shape_refused) (422) — The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers. **Fix:** Omit those fields, or verify a domain with POST /domains and send from that domain. - [`overage_cap_reached`](https://agentisend.com/docs/errors#overage_cap_reached) (402) — This account has used every email in its plan and every extra email its owner allowed this period. **Fix:** Raise the overage ceiling or move up a plan in Settings → Billing, or wait until the reset date in this error. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_limit_reached`](https://agentisend.com/docs/errors#plan_limit_reached) (402) — This account has used every email included in its plan for the current period. **Fix:** Upgrade in Settings → Billing, or wait until the reset date in this error. - [`rate_ceiling_exceeded`](https://agentisend.com/docs/errors#rate_ceiling_exceeded) (429) — Per-minute rate ceiling for this key is exhausted. **Fix:** Wait the seconds below and send the same request again. Raising the ceiling is a person’s decision, made in the console; a key cannot raise its own. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`recipient_blocklisted`](https://agentisend.com/docs/errors#recipient_blocklisted) (422) — This recipient is blocked. **Fix:** Send to a different address. An address ending in @simulator.agentisend.com is never blocked. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_paused_everywhere`](https://agentisend.com/docs/errors#sending_paused_everywhere) (503) — Sending is paused for every account while AgentiSend handles an incident. Nothing was sent or charged. **Fix:** Retry the same request, with the same Idempotency-Key, after the seconds given in Retry-After. Scheduled sends wait and go out once sending resumes. - [`suppressed_recipient`](https://agentisend.com/docs/errors#suppressed_recipient) (422) — Recipient is on the account suppression list. **Fix:** GET /suppressions says which address and why. A hard bounce you have fixed can be cleared with DELETE /suppressions/:id; an unsubscribe or a spam complaint cannot — that address asked not to be contacted. - [`trust_paused`](https://agentisend.com/docs/errors#trust_paused) (403) — Sending is paused by the trust system. **Fix:** Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal. - [`trust_throttled`](https://agentisend.com/docs/errors#trust_throttled) (429) — This account is being throttled by the trust ladder. **Fix:** Send volume is temporarily capped because deliverability metrics crossed a published threshold. Check GET /trust/standing for the metric and value, file POST /trust/appeal if this is unexpected. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. - [`young_domain_held`](https://agentisend.com/docs/errors#young_domain_held) (403) — Mail from this domain waits for a review. It was registered less than 30 days ago. **Fix:** Mail from your other verified domains still sends. Write to hello@agentisend.com and name this domain. --- Source: https://agentisend.com/docs/api/post-emails-preflight — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving # GET /emails/receiving Not open yet: mail received at this account’s domains, newest first. Filter by recipient, sender or date range. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `to` query · `string` · optional - `from` query · `string` · optional - `q` query · `string` · optional - `since` query · `string` · optional - `until` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].attachment_count` | `integer` | yes | | | `data[].from` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].received_at` | `string` | yes | | | `data[].size_bytes` | `integer` | yes | | | `data[].subject` | `string \| null` | yes | | | `data[].to` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving-threads # GET /emails/receiving/threads Not open yet: received mail grouped into threads by Message-ID / In-Reply-To / References, newest thread first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving/threads \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving/threads', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/threads' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving-threads` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].id` | `string` | yes | | | `data[].last_received_at` | `string` | yes | | | `data[].latest_id` | `string` | yes | | | `data[].message_count` | `integer` | yes | | | `data[].participants` | `array` | yes | | | `data[].subject` | `string \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving-threads — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving-id # GET /emails/receiving/{id} Not open yet: one received email: headers, text and HTML bodies as data, and the attachments it carried. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "attachment_count": -9007199254740991, "attachments": [], "from": "example", "headers": {}, "html": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "received_at": "2026-09-04T09:14:00.000Z", "size_bytes": -9007199254740991, "subject": "example", "text": "example", "to": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachment_count` | `integer` | yes | | | `attachments` | `array` | yes | | | `attachments[].content_id` | `string \| null` | yes | | | `attachments[].content_type` | `string` | yes | | | `attachments[].filename` | `string` | yes | | | `attachments[].id` | `string` | yes | | | `attachments[].size_bytes` | `integer` | yes | | | `from` | `string` | yes | | | `headers` | `object` | yes | | | `html` | `string \| null` | yes | | | `id` | `string` | yes | | | `received_at` | `string` | yes | | | `size_bytes` | `integer` | yes | | | `subject` | `string \| null` | yes | | | `text` | `string \| null` | yes | | | `to` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving-id-attachments # GET /emails/receiving/{id}/attachments Not open yet: what this received email carried. Ids are stable positions in the message. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving-id-attachments` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].content_id` | `string \| null` | yes | | | `data[].content_type` | `string` | yes | | | `data[].filename` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].size_bytes` | `integer` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving-id-attachments — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving-id-attachments-aid # GET /emails/receiving/{id}/attachments/{aid} Not open yet: the bytes of one received attachment, as an inert download — always octet-stream, never the sender’s declared type. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving-id-attachments-aid` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `aid` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving-id-attachments-aid — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-receiving-id-raw # GET /emails/receiving/{id}/raw Not open yet: the stored RFC 5322 source, byte for byte. Served as an attachment with sniffing off — it is someone else’s content. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/raw \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/raw', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/raw' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-receiving-id-raw` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-receiving-id-raw — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-receiving-id-reply # POST /emails/receiving/{id}/reply Not open yet: reply to a received email. Threads on In-Reply-To and References, and runs every send check. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reply \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"text":"Thanks — the details are attached."}' ``` ```json Response 201 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "simulated": false, "warnings": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reply', body: { "text": "Thanks — the details are attached." }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/receiving/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reply' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"text":"Thanks — the details are attached."}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-receiving-id-reply` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `bcc` | `string \| array` | no | Blind copy recipients. | | `cc` | `string \| array` | no | Copy recipients. | | `from` | `string` | no | Sender. Omit it to reply from the address the message was sent to. | | `html` | `string` | no | HTML body. Provide html or text. | | `subject` | `string` | no | Subject. Omit it and the reply uses Re: plus the original subject. | | `text` | `string` | no | Plain-text body. Provide html or text. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `402` — A budget, quota or plan limit would be exceeded. Codes: overage_cap_reached, daily_limit_reached, agent_budget_exceeded, plan_limit_reached. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `simulated` | `boolean` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `string` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].message` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`account_sandboxed`](https://agentisend.com/docs/errors#account_sandboxed) (403) — This account is in the sandbox and may only send to its own verified domains. **Fix:** Verify the recipient domain with POST /domains + POST /domains/:id/verify, or file POST /trust/appeal for a person to review this account. - [`account_suspended`](https://agentisend.com/docs/errors#account_suspended) (403) — This account is suspended. **Fix:** Read the enforcement policy at https://agentisend.com/policy/enforcement, then contact hello@agentisend.com to appeal. - [`agent_budget_exceeded`](https://agentisend.com/docs/errors#agent_budget_exceeded) (402) — Key budget for the current period is exhausted. **Fix:** Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own. - [`approval_required`](https://agentisend.com/docs/errors#approval_required) (403) — This action requires human approval before it executes. **Fix:** Do not send it again: a person approves or rejects it in the console under Agents → Approvals, and approving sends it — the message then appears in GET /emails. action_id in this error names the held send; the key that asked cannot approve itself, and a retry waits on the same approval. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`daily_limit_reached`](https://agentisend.com/docs/errors#daily_limit_reached) (402) — This account has sent its daily allowance of emails; sending resumes at 00:00 UTC. **Fix:** Wait for 00:00 UTC, or upgrade in Settings → Billing — every paid plan has no daily cap. - [`domain_not_verified`](https://agentisend.com/docs/errors#domain_not_verified) (403) — This sending domain is not verified. **Fix:** If it is pending, publish the required records from GET /domains/:id; checks continue for 72 hours. Test now by sending to an address ending in @simulator.agentisend.com. If it is not registered, POST /domains first. If it is failed, GET /domains/:id names the record to fix, then POST /domains/:id/verify to reopen the window. - [`domain_scope_violation`](https://agentisend.com/docs/errors#domain_scope_violation) (403) — This API key may only send from its scoped domain. **Fix:** Send from the scoped domain, or create a key without a domain scope via POST /api-keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_attachment`](https://agentisend.com/docs/errors#invalid_attachment) (422, invalid_attachment) — Each attachment needs content (base64) or path. **Fix:** Provide attachment.content or attachment.path in POST /emails. - [`invalid_from_address`](https://agentisend.com/docs/errors#invalid_from_address) (422, invalid_from_address) — The from field is not a valid address. **Fix:** Use a plain address or "Name " format in POST /emails. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`kill_switch_active`](https://agentisend.com/docs/errors#kill_switch_active) (403) — This API key has been paused with the kill switch. **Fix:** Read GET /trust/standing for why it was paused. Only a person signed in to the console can resume it; the paused key cannot resume itself. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`missing_required_field`](https://agentisend.com/docs/errors#missing_required_field) (422, missing_required_field) — Body is missing required fields. **Fix:** Include from, to and subject in POST /emails. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`onboarding_daily_cap_reached`](https://agentisend.com/docs/errors#onboarding_daily_cap_reached) (429) — This account has used its 20 onboarding emails for today. **Fix:** Wait until tomorrow (UTC), or verify a domain with POST /domains and send from that domain. - [`onboarding_recipient_not_a_member`](https://agentisend.com/docs/errors#onboarding_recipient_not_a_member) (403) — The onboarding sender can only mail this account's own members — the addresses they sign in with. **Fix:** Send to a member sign-in address, or verify a domain with POST /domains and send from that domain. - [`onboarding_sender_unavailable`](https://agentisend.com/docs/errors#onboarding_sender_unavailable) (403) — The onboarding sender is not available. **Fix:** Send to an address ending in @simulator.agentisend.com, or verify a domain with POST /domains and send from that domain. - [`onboarding_shape_refused`](https://agentisend.com/docs/errors#onboarding_shape_refused) (422) — The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers. **Fix:** Omit those fields, or verify a domain with POST /domains and send from that domain. - [`overage_cap_reached`](https://agentisend.com/docs/errors#overage_cap_reached) (402) — This account has used every email in its plan and every extra email its owner allowed this period. **Fix:** Raise the overage ceiling or move up a plan in Settings → Billing, or wait until the reset date in this error. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`plan_limit_reached`](https://agentisend.com/docs/errors#plan_limit_reached) (402) — This account has used every email included in its plan for the current period. **Fix:** Upgrade in Settings → Billing, or wait until the reset date in this error. - [`rate_ceiling_exceeded`](https://agentisend.com/docs/errors#rate_ceiling_exceeded) (429) — Per-minute rate ceiling for this key is exhausted. **Fix:** Wait the seconds below and send the same request again. Raising the ceiling is a person’s decision, made in the console; a key cannot raise its own. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`recipient_blocklisted`](https://agentisend.com/docs/errors#recipient_blocklisted) (422) — This recipient is blocked. **Fix:** Send to a different address. An address ending in @simulator.agentisend.com is never blocked. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`sending_paused_everywhere`](https://agentisend.com/docs/errors#sending_paused_everywhere) (503) — Sending is paused for every account while AgentiSend handles an incident. Nothing was sent or charged. **Fix:** Retry the same request, with the same Idempotency-Key, after the seconds given in Retry-After. Scheduled sends wait and go out once sending resumes. - [`suppressed_recipient`](https://agentisend.com/docs/errors#suppressed_recipient) (422) — Recipient is on the account suppression list. **Fix:** GET /suppressions says which address and why. A hard bounce you have fixed can be cleared with DELETE /suppressions/:id; an unsubscribe or a spam complaint cannot — that address asked not to be contacted. - [`trust_paused`](https://agentisend.com/docs/errors#trust_paused) (403) — Sending is paused by the trust system. **Fix:** Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal. - [`trust_throttled`](https://agentisend.com/docs/errors#trust_throttled) (429) — This account is being throttled by the trust ladder. **Fix:** Send volume is temporarily capped because deliverability metrics crossed a published threshold. Check GET /trust/standing for the metric and value, file POST /trust/appeal if this is unexpected. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-emails-receiving-id-reply — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id # GET /emails/{id} Fetch one message with its current status and last event. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "api_key_id": "example", "attachments": [], "bcc": [], "cc": [], "created_at": "2026-09-04T09:14:00.000Z", "domain": "example", "from": "example", "headers": {}, "html": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_event": "queued", "object": "email", "provider_message_id": "example", "reply_to": [], "scheduled_at": "2026-09-04T09:14:00.000Z", "status": "queued", "subject": "example", "tags": {}, "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "template_version": -9007199254740991, "text": "example", "to": [], "updated_at": "2026-09-04T09:14:00.000Z", "warnings": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string \| null` | yes | | | `attachments` | `array \| null` | yes | | | `bcc` | `array \| null` | yes | | | `cc` | `array \| null` | yes | | | `created_at` | `string` | yes | | | `domain` | `string` | yes | | | `from` | `string` | yes | | | `headers` | `object \| null` | yes | | | `html` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_event` | `"queued" \| "scheduled" \| "sent" \| "delivered" \| "delivery_delayed" \| "bounced" \| "complained" \| "opened" \| "clicked" \| "failed" \| "canceled" \| "suppressed" \| null` | yes | | | `object` | `string` | yes | | | `provider_message_id` | `string \| null` | yes | | | `reply_to` | `array \| null` | yes | | | `scheduled_at` | `string \| null` | yes | | | `status` | `"queued" \| "scheduled" \| "sent" \| "delivered" \| "delivery_delayed" \| "bounced" \| "complained" \| "opened" \| "clicked" \| "failed" \| "canceled" \| "suppressed"` | yes | | | `subject` | `string` | yes | | | `tags` | `object \| null` | yes | | | `template_id` | `string \| null` | yes | | | `template_version` | `integer \| null` | yes | | | `text` | `string \| null` | yes | | | `to` | `array` | yes | | | `updated_at` | `string` | yes | | | `warnings` | `array` | yes | | | `warnings[].code` | `string` | yes | | | `warnings[].fix` | `string` | yes | | | `warnings[].message` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-emails-id # PATCH /emails/{id} Move a scheduled email to a new time — the same act as POST /emails/:id/reschedule, under the verb a Resend integration already uses. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"scheduled_at":"in 1 hour"}' ``` ```json Response 200 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "scheduled_at": "example", "status": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "scheduled_at": "in 1 hour" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"scheduled_at":"in 1 hour"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `patch-emails-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `scheduledAt` | `string` | no | Resend Node SDK name for scheduled_at. | | `scheduled_at` | `string` | no | ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead. | | `timezone` | `string` | no | Time zone for a scheduled_at phrase such as "tomorrow 9am". An ISO time ignores this. Example: America/Los_Angeles. Omitted phrases are read in UTC. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `scheduled_at` | `string` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-emails-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-attachments # GET /emails/{id}/attachments What this email carried. Ids are stable positions; bytes_available says whether the payload is still retrievable. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-attachments` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].bytes_available` | `boolean` | yes | | | `data[].content_id` | `string \| null` | yes | | | `data[].content_type` | `string \| null` | yes | | | `data[].filename` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].path` | `string \| null` | yes | | | `data[].size_bytes` | `integer \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-attachments — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-attachments-aid # GET /emails/{id}/attachments/{aid} The bytes of one attachment, exactly as they were sent. Served as an inert download. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-attachments-aid` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `aid` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-attachments-aid — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-id-cancel # POST /emails/{id}/cancel Cancel a scheduled or queued email. Already-sent mail is history, not cancellable. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "status": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-id-cancel` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-emails-id-cancel — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-eml # GET /emails/{id}/eml Download this email as.eml. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/eml \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/eml', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/eml' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-eml` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-eml — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-events # GET /emails/{id}/events Every event recorded for one message, oldest first, with the provider detail. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-events` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].detail` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].occurred_at` | `string` | yes | | | `data[].provider_message_id` | `string \| null` | yes | | | `data[].recipient` | `string \| null` | yes | | | `data[].type` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-events — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-explain # GET /emails/{id}/explain What happened to this email, the evidence, and the exact calls that fix it — machine-readable remediation. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/explain \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "actions": [], "evidence": {}, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "retryable": false, "status": "example", "verdict": "example", "what_happened": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/explain', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/explain' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-explain` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `actions` | `array` | yes | | | `actions[].call` | `object` | no | | | `actions[].do` | `string` | yes | | | `evidence` | `object` | yes | | | `id` | `string` | yes | | | `retryable` | `boolean` | yes | | | `status` | `string` | yes | | | `verdict` | `string` | yes | | | `what_happened` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-explain — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-emails-id-mime # GET /emails/{id}/mime The exact RFC 5322 source of this email — what Resend never shows you. ## Request ```bash curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/mime \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/mime', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/mime' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `get-emails-id-mime` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-emails-id-mime — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-emails-id-reschedule # POST /emails/{id}/reschedule Move an email to a new time. Works from scheduled AND canceled — a cancel is never terminal. ## Request ```bash curl -sS -X POST https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reschedule \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"scheduled_at":"in 1 hour"}' ``` ```json Response 200 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "scheduled_at": "example", "status": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reschedule', body: { "scheduled_at": "in 1 hour" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/reschedule' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"scheduled_at":"in 1 hour"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: emails. Generated from `openapi.json`; the anchor `post-emails-id-reschedule` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `scheduledAt` | `string` | no | Resend Node SDK name for scheduled_at. | | `scheduled_at` | `string` | no | ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead. | | `timezone` | `string` | no | Time zone for a scheduled_at phrase such as "tomorrow 9am". An ISO time ignores this. Example: America/Los_Angeles. Omitted phrases are read in UTC. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `scheduled_at` | `string` | yes | | | `status` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-emails-id-reschedule — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-events # GET /events Every custom event this account has declared, with its typed schema and when it was last seen. ## Request ```bash curl -sS -X GET https://api.agentisend.com/events \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/events', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/events' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-events` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].description` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_seen_at` | `string \| null` | yes | | | `data[].name` | `string` | yes | | | `data[].schema` | `object` | yes | | | `data[].strict` | `boolean` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-events — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-events # POST /events Ingest a custom event. Matching enabled automations fire synchronously (202 once enqueued). ## Request ```bash curl -sS -X POST https://api.agentisend.com/events \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"example"}' ``` ```json Response 202 { "fired": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/events', body: { "name": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/events' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `post-events` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `contact_id` | `string` | no | | | `data` | `object` | no | | | `name` | `string` | yes | | ## Responses - `202` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 202 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `fired` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-events — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-events-id # GET /events/{id} One event definition. ## Request ```bash curl -sS -X GET https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "description": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_seen_at": "2026-09-04T09:14:00.000Z", "name": "example", "schema": {}, "strict": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `get-events-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `description` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_seen_at` | `string \| null` | yes | | | `name` | `string` | yes | | | `schema` | `object` | yes | | | `strict` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-events-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-events-id # PATCH /events/{id} Declare or re-declare an event’s fields. Adding a field to a strict event starts refusing payloads that omit it — that is the point. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"description":"Fired when an order is paid."}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "description": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_seen_at": "2026-09-04T09:14:00.000Z", "name": "example", "schema": {}, "strict": false, "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "description": "Fired when an order is paid." }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"description":"Fired when an order is paid."}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `patch-events-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `description` | `string \| null` | no | | | `schema` | `object` | no | | | `strict` | `boolean` | no | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `description` | `string \| null` | yes | | | `id` | `string` | yes | | | `last_seen_at` | `string \| null` | yes | | | `name` | `string` | yes | | | `schema` | `object` | yes | | | `strict` | `boolean` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-events-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-events-id # DELETE /events/{id} Forget an event definition. Ingest keeps accepting the event — it just stops being checked. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/events/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: automations. Generated from `openapi.json`; the anchor `delete-events-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-events-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-health # GET /health Liveness probe. ## Request ```bash curl -sS -X GET https://api.agentisend.com/health \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/health', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/health' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: meta. Generated from `openapi.json`; the anchor `get-health` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-health — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-invite-token-accept # POST /invite/{token}/accept Accept an invitation. Requires a session signed in as the invited address; a person who has never signed in before is provisioned into the inviting account, not a new one. ## Request ```bash curl -sS -X POST https://api.agentisend.com/invite/invite-token-example/accept \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "account_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "account_name": "example", "member_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "role": "owner" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/invite/invite-token-example/accept', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/invite/invite-token-example/accept' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `post-invite-token-accept` is the id the console's error `fix` links point at. ## Parameters - `token` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `account_id` | `string` | yes | | | `account_name` | `string` | yes | | | `member_id` | `string` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`already_in_account`](https://agentisend.com/docs/errors#already_in_account) (409) — This address already belongs to an account. **Fix:** Leave the current account first, or ask the inviter to send the invitation to an address that has no account. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invite_email_mismatch`](https://agentisend.com/docs/errors#invite_email_mismatch) (403) — This invitation was sent to a different address than the one you are signed in as. **Fix:** Sign out, sign in as the invited address, then open the invitation link again — POST /invite/:token/accept binds the membership to the signed-in address. - [`invite_not_valid`](https://agentisend.com/docs/errors#invite_not_valid) (422) — This invitation is expired, cancelled, or already accepted. **Fix:** Ask an owner or admin to send a new one with POST /team/invites. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-invite-token-accept — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-limits-keys # GET /limits/keys The fleet: every key with its budget, ceiling, consumption, identity and current loop state. ## Request ```bash curl -sS -X GET https://api.agentisend.com/limits/keys \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/limits/keys', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/keys' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `get-limits-keys` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].api_key_id` | `string` | yes | | | `data[].budget_per_period` | `integer \| null` | yes | | | `data[].consumed_in_period` | `integer` | yes | | | `data[].consumed_in_window` | `integer` | yes | | | `data[].last_used_at` | `string \| null` | yes | | | `data[].loop_evidence` | `object` | yes | | | `data[].loop_state` | `"clear" \| "watch" \| "tripped"` | yes | | | `data[].name` | `string` | yes | | | `data[].paused` | `boolean` | yes | | | `data[].paused_at` | `string \| null` | yes | | | `data[].paused_reason` | `string \| null` | yes | | | `data[].period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `data[].period_started_at` | `string` | yes | | | `data[].rate_ceiling_per_minute` | `integer \| null` | yes | | | `data[].rate_window_started_at` | `string` | yes | | | `data[].system` | `boolean` | yes | | | `data[].token_prefix` | `string` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-limits-keys — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-limits-keys-id # GET /limits/keys/{id} Budget, ceiling and current consumption for one key. ## Request ```bash curl -sS -X GET https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "budget_per_period": -9007199254740991, "consumed_in_period": -9007199254740991, "consumed_in_window": -9007199254740991, "paused": false, "paused_at": "2026-09-04T09:14:00.000Z", "paused_reason": "example", "period": "hourly", "period_started_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "rate_window_started_at": "2026-09-04T09:14:00.000Z", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `get-limits-keys-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string` | yes | | | `budget_per_period` | `integer \| null` | yes | | | `consumed_in_period` | `integer` | yes | | | `consumed_in_window` | `integer` | yes | | | `paused` | `boolean` | yes | | | `paused_at` | `string \| null` | yes | | | `paused_reason` | `string \| null` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `period_started_at` | `string` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `rate_window_started_at` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-limits-keys-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-limits-keys-id # PATCH /limits/keys/{id} Set or clear this key’s period budget and per-minute ceiling. An API key may lower its own; raising one is a person’s decision, made in the console. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"budget_per_period":500,"rate_ceiling_per_minute":20}' ``` ```json Response 200 { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "budget_per_period": -9007199254740991, "consumed_in_period": -9007199254740991, "consumed_in_window": -9007199254740991, "paused": false, "paused_at": "2026-09-04T09:14:00.000Z", "paused_reason": "example", "period": "hourly", "period_started_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "rate_window_started_at": "2026-09-04T09:14:00.000Z", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "budget_per_period": 500, "rate_ceiling_per_minute": 20 }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"budget_per_period":500,"rate_ceiling_per_minute":20}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `patch-limits-keys-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `budget_per_period` | `integer \| null` | no | Messages this key may accept in the period. Null clears it. A key can only lower its own. | | `period` | `"hourly" \| "daily" \| "monthly"` | no | hourly, daily or monthly. | | `rate_ceiling_per_minute` | `integer \| null` | no | Messages this key may accept in one minute. Null clears it. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string` | yes | | | `budget_per_period` | `integer \| null` | yes | | | `consumed_in_period` | `integer` | yes | | | `consumed_in_window` | `integer` | yes | | | `paused` | `boolean` | yes | | | `paused_at` | `string \| null` | yes | | | `paused_reason` | `string \| null` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `period_started_at` | `string` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `rate_window_started_at` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`key_budget_exceeds_plan`](https://agentisend.com/docs/errors#key_budget_exceeds_plan) (422) — A key budget cannot be unlimited or larger than the emails this plan includes per month. **Fix:** Set a whole number at or below the plan inclusion, or upgrade in Settings → Billing. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-limits-keys-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-limits-keys-id-kill # POST /limits/keys/{id}/kill Stop this key from sending, immediately. Takes effect on the next request. ## Request ```bash curl -sS -X POST https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/kill \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "budget_per_period": -9007199254740991, "consumed_in_period": -9007199254740991, "consumed_in_window": -9007199254740991, "paused": false, "paused_at": "2026-09-04T09:14:00.000Z", "paused_reason": "example", "period": "hourly", "period_started_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "rate_window_started_at": "2026-09-04T09:14:00.000Z", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/kill', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/kill' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `post-limits-keys-id-kill` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `reason` | `string` | no | Why, recorded with the change. Optional. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string` | yes | | | `budget_per_period` | `integer \| null` | yes | | | `consumed_in_period` | `integer` | yes | | | `consumed_in_window` | `integer` | yes | | | `paused` | `boolean` | yes | | | `paused_at` | `string \| null` | yes | | | `paused_reason` | `string \| null` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `period_started_at` | `string` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `rate_window_started_at` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-limits-keys-id-kill — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-limits-keys-id-resume # POST /limits/keys/{id}/resume Undo the kill switch. A person signed in to the console does this; budgets and ceilings are unchanged. ## Request ```bash curl -sS -X POST https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resume \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "budget_per_period": -9007199254740991, "consumed_in_period": -9007199254740991, "consumed_in_window": -9007199254740991, "paused": false, "paused_at": "2026-09-04T09:14:00.000Z", "paused_reason": "example", "period": "hourly", "period_started_at": "2026-09-04T09:14:00.000Z", "rate_ceiling_per_minute": -9007199254740991, "rate_window_started_at": "2026-09-04T09:14:00.000Z", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resume', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/resume' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `post-limits-keys-id-resume` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string` | yes | | | `budget_per_period` | `integer \| null` | yes | | | `consumed_in_period` | `integer` | yes | | | `consumed_in_window` | `integer` | yes | | | `paused` | `boolean` | yes | | | `paused_at` | `string \| null` | yes | | | `paused_reason` | `string \| null` | yes | | | `period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `period_started_at` | `string` | yes | | | `rate_ceiling_per_minute` | `integer \| null` | yes | | | `rate_window_started_at` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-limits-keys-id-resume — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-limits-kill-all # POST /limits/kill-all Pause every key on this account at once. Takes effect on the next request. ## Request ```bash curl -sS -X POST https://api.agentisend.com/limits/kill-all \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "affected_key_ids": [], "at": "2026-09-04T09:14:00.000Z", "paused": false, "reason": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/limits/kill-all', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/kill-all' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `post-limits-kill-all` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `reason` | `string` | no | Why, recorded with the change. Optional. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `affected_key_ids` | `array` | yes | | | `at` | `string` | yes | | | `paused` | `boolean` | yes | | | `reason` | `string \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-limits-kill-all — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-limits-resume-all # POST /limits/resume-all Undo the global kill switch. A person signed in to the console does this; budgets and ceilings are unchanged, and a key killed on its own stays paused. ## Request ```bash curl -sS -X POST https://api.agentisend.com/limits/resume-all \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "affected_key_ids": [], "at": "2026-09-04T09:14:00.000Z", "paused": false, "reason": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/limits/resume-all', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/limits/resume-all' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: limits. Generated from `openapi.json`; the anchor `post-limits-resume-all` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `reason` | `string` | no | Why, recorded with the change. Optional. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `affected_key_ids` | `array` | yes | | | `at` | `string` | yes | | | `paused` | `boolean` | yes | | | `reason` | `string \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-limits-resume-all — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-logs # GET /logs Every API request this account made, with method, route, status and any refusal. Filter by date, status, key, source or a search string. ## Request ```bash curl -sS -X GET https://api.agentisend.com/logs \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/logs', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/logs' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: logs. Generated from `openapi.json`; the anchor `get-logs` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `since` query · `string` · optional - `until` query · `string` · optional - `status` query · `integer` · optional - `status_class` query · `"2xx" | "4xx" | "5xx"` · optional - `method` query · `"GET" | "POST" | "PATCH" | "PUT" | "DELETE"` · optional - `route` query · `string` · optional - `error_code` query · `string` · optional - `api_key_id` query · `string` · optional - `source` query · `"api" | "console" | "all"` · optional - `q` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].api_key_id` | `string \| null` | yes | | | `data[].api_key_name` | `string \| null` | yes | | | `data[].created_at` | `string` | yes | | | `data[].duration_ms` | `integer` | yes | | | `data[].error_code` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].method` | `string` | yes | | | `data[].path` | `string` | yes | | | `data[].request_id` | `string` | yes | | | `data[].route` | `string \| null` | yes | | | `data[].source` | `"api" \| "console"` | yes | | | `data[].status` | `integer` | yes | | | `data[].user_agent` | `string \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-logs — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-logs-id # GET /logs/{id} One request, by log id. The x-request-id the caller saw is on the row. ## Request ```bash curl -sS -X GET https://api.agentisend.com/logs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "api_key_name": "example", "created_at": "2026-09-04T09:14:00.000Z", "duration_ms": -9007199254740991, "error_code": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "method": "example", "path": "example", "request_id": "example", "route": "example", "source": "api", "status": -9007199254740991, "user_agent": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/logs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/logs/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: logs. Generated from `openapi.json`; the anchor `get-logs-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `api_key_id` | `string \| null` | yes | | | `api_key_name` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `duration_ms` | `integer` | yes | | | `error_code` | `string \| null` | yes | | | `id` | `string` | yes | | | `method` | `string` | yes | | | `path` | `string` | yes | | | `request_id` | `string` | yes | | | `route` | `string \| null` | yes | | | `source` | `"api" \| "console"` | yes | | | `status` | `integer` | yes | | | `user_agent` | `string \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-logs-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-metrics # GET /metrics Send/delivery/engagement KPIs with a daily series, computed from the event spine over a window. ## Request ```bash curl -sS -X GET https://api.agentisend.com/metrics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "by_api_key": [], "by_domain": [], "event": "sent", "previous": { "bounced": -9007199254740991, "clicks": -9007199254740991, "complaints": -9007199254740991, "delivered": -9007199254740991, "opens": -9007199254740991, "sent": -9007199254740991 }, "series": [], "since": "example", "totals": { "bounced": -9007199254740991, "clicks": -9007199254740991, "complaints": -9007199254740991, "delivered": -9007199254740991, "opens": -9007199254740991, "sent": -9007199254740991 }, "until": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/metrics', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/metrics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: metrics. Generated from `openapi.json`; the anchor `get-metrics` is the id the console's error `fix` links point at. ## Parameters - `since` query · `string` · optional - `until` query · `string` · optional - `start_date` query · `string` · optional - `end_date` query · `string` · optional - `group_by` query · `string` · optional - `event` query · `"sent" | "delivered" | "bounced" | "complained" | "opened" | "clicked"` · optional - `domain` query · `string` · optional - `api_key_id` query · `string | string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `by_api_key` | `array` | yes | | | `by_api_key[].bounced` | `integer` | yes | | | `by_api_key[].complained` | `integer` | yes | | | `by_api_key[].delivered` | `integer` | yes | | | `by_api_key[].id` | `string` | yes | | | `by_api_key[].name` | `string` | yes | | | `by_api_key[].sent` | `integer` | yes | | | `by_api_key[].series` | `array` | yes | | | `by_domain` | `array` | yes | | | `by_domain[].bounced` | `integer` | yes | | | `by_domain[].complained` | `integer` | yes | | | `by_domain[].delivered` | `integer` | yes | | | `by_domain[].id` | `string` | yes | | | `by_domain[].name` | `string` | yes | | | `by_domain[].sent` | `integer` | yes | | | `by_domain[].series` | `array` | yes | | | `event` | `"sent" \| "delivered" \| "bounced" \| "complained" \| "opened" \| "clicked" \| null` | yes | | | `previous` | `object` | yes | | | `previous.bounced` | `integer` | yes | | | `previous.clicks` | `integer` | yes | | | `previous.complaints` | `integer` | yes | | | `previous.delivered` | `integer` | yes | | | `previous.opens` | `integer` | yes | | | `previous.sent` | `integer` | yes | | | `series` | `array` | yes | | | `series[].bounced` | `integer` | yes | | | `series[].clicks` | `integer` | yes | | | `series[].complaints` | `integer` | yes | | | `series[].day` | `string` | yes | | | `series[].delivered` | `integer` | yes | | | `series[].opens` | `integer` | yes | | | `series[].sent` | `integer` | yes | | | `since` | `string` | yes | | | `totals` | `object` | yes | | | `totals.bounced` | `integer` | yes | | | `totals.clicks` | `integer` | yes | | | `totals.complaints` | `integer` | yes | | | `totals.delivered` | `integer` | yes | | | `totals.opens` | `integer` | yes | | | `totals.sent` | `integer` | yes | | | `until` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-metrics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-notifications # GET /notifications Conditions this account should know about. Open rows are live; resolved ones ended. One row per condition, counted, never one per re-fire. ## Request ```bash curl -sS -X GET https://api.agentisend.com/notifications \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/notifications', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/notifications' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: notifications. Generated from `openapi.json`; the anchor `get-notifications` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `state` query · `"open" | "resolved"` · optional - `unread` query · `"true" | "false"` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].body` | `string` | yes | | | `data[].console_path` | `string` | yes | | | `data[].dedupe_key` | `string` | yes | | | `data[].first_seen_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].last_seen_at` | `string` | yes | | | `data[].occurrences` | `integer` | yes | | | `data[].read_at` | `string \| null` | yes | | | `data[].resolved_at` | `string \| null` | yes | | | `data[].state` | `"open" \| "resolved"` | yes | | | `data[].title` | `string` | yes | | | `data[].type` | `"budget_exhausted" \| "kill_switch_engaged" \| "approvals_pending" \| "trust_state_changed" \| "webhook_endpoint_disabled" \| "domain_verification_lost" \| "domain_verified" \| "appeal_decided" \| "onboarding" \| "api_key_leaked" \| "dmarc_unaligned_source" \| "welcome" \| "billing" \| "support" \| "trial"` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-notifications — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-notifications-preferences # GET /notifications/preferences Which channels each notification type uses. A type with no stored row is on for both. ## Request ```bash curl -sS -X GET https://api.agentisend.com/notifications/preferences \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "preferences": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/notifications/preferences', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/notifications/preferences' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: notifications. Generated from `openapi.json`; the anchor `get-notifications-preferences` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `preferences` | `array` | yes | | | `preferences[].email` | `boolean` | yes | | | `preferences[].in_app` | `boolean` | yes | | | `preferences[].type` | `"budget_exhausted" \| "kill_switch_engaged" \| "approvals_pending" \| "trust_state_changed" \| "webhook_endpoint_disabled" \| "domain_verification_lost" \| "domain_verified" \| "appeal_decided" \| "onboarding" \| "api_key_leaked" \| "dmarc_unaligned_source" \| "welcome" \| "billing" \| "support" \| "trial"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. --- Source: https://agentisend.com/docs/api/get-notifications-preferences — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-notifications-preferences # PATCH /notifications/preferences Turn a notification type on or off per channel. The gate is the type — there is no severity to mute instead. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/notifications/preferences \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"preferences":[{"type":"budget_exhausted"}]}' ``` ```json Response 200 { "preferences": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/notifications/preferences', body: { "preferences": [ { "type": "budget_exhausted" } ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/notifications/preferences' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"preferences":[{"type":"budget_exhausted"}]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: notifications. Generated from `openapi.json`; the anchor `patch-notifications-preferences` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `preferences` | `array` | yes | | | `preferences[].email` | `boolean` | no | | | `preferences[].in_app` | `boolean` | no | | | `preferences[].type` | `"budget_exhausted" \| "kill_switch_engaged" \| "approvals_pending" \| "trust_state_changed" \| "webhook_endpoint_disabled" \| "domain_verification_lost" \| "domain_verified" \| "appeal_decided" \| "onboarding" \| "api_key_leaked" \| "dmarc_unaligned_source" \| "welcome" \| "billing" \| "support" \| "trial"` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `preferences` | `array` | yes | | | `preferences[].email` | `boolean` | yes | | | `preferences[].in_app` | `boolean` | yes | | | `preferences[].type` | `"budget_exhausted" \| "kill_switch_engaged" \| "approvals_pending" \| "trust_state_changed" \| "webhook_endpoint_disabled" \| "domain_verification_lost" \| "domain_verified" \| "appeal_decided" \| "onboarding" \| "api_key_leaked" \| "dmarc_unaligned_source" \| "welcome" \| "billing" \| "support" \| "trial"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-notifications-preferences — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-notifications-read # POST /notifications/read Mark notifications read. With no ids, every open row on the account is marked — the bell’s "Mark all read". ## Request ```bash curl -sS -X POST https://api.agentisend.com/notifications/read \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "read": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/notifications/read', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/notifications/read' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: notifications. Generated from `openapi.json`; the anchor `post-notifications-read` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `ids` | `array` | no | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `read` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-notifications-read — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-notifications-id-read # POST /notifications/{id}/read Mark one notification read. Reading it never resolves it — the condition ends the row, not the reader. ## Request ```bash curl -sS -X POST https://api.agentisend.com/notifications/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/read \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "body": "example", "console_path": "example", "dedupe_key": "example", "first_seen_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_seen_at": "2026-09-04T09:14:00.000Z", "occurrences": -9007199254740991, "read_at": "2026-09-04T09:14:00.000Z", "resolved_at": "2026-09-04T09:14:00.000Z", "state": "open", "title": "example", "type": "budget_exhausted" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/notifications/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/read', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/notifications/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/read' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: notifications. Generated from `openapi.json`; the anchor `post-notifications-id-read` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `body` | `string` | yes | | | `console_path` | `string` | yes | | | `dedupe_key` | `string` | yes | | | `first_seen_at` | `string` | yes | | | `id` | `string` | yes | | | `last_seen_at` | `string` | yes | | | `occurrences` | `integer` | yes | | | `read_at` | `string \| null` | yes | | | `resolved_at` | `string \| null` | yes | | | `state` | `"open" \| "resolved"` | yes | | | `title` | `string` | yes | | | `type` | `"budget_exhausted" \| "kill_switch_engaged" \| "approvals_pending" \| "trust_state_changed" \| "webhook_endpoint_disabled" \| "domain_verification_lost" \| "domain_verified" \| "appeal_decided" \| "onboarding" \| "api_key_leaked" \| "dmarc_unaligned_source" \| "welcome" \| "billing" \| "support" \| "trial"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-notifications-id-read — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-oauth-grants # GET /oauth/grants Every assistant connection on this account, newest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/oauth/grants \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/oauth/grants', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/oauth/grants' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: oauth. Generated from `openapi.json`; the anchor `get-oauth-grants` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].client_id` | `string` | yes | | | `data[].client_name` | `string \| null` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].last_used_at` | `string \| null` | yes | | | `data[].scopes` | `array` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-oauth-grants — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-oauth-grants-id # DELETE /oauth/grants/{id} Revoke one assistant connection. Tokens and the backing key die immediately. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/oauth/grants/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/oauth/grants/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/oauth/grants/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: oauth. Generated from `openapi.json`; the anchor `delete-oauth-grants-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-oauth-grants-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-openapi-json # GET /openapi.json OpenAPI 3.1 document generated from the same schemas that validate. ## Request ```bash curl -sS -X GET https://api.agentisend.com/openapi.json \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/openapi.json', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/openapi.json' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: meta. Generated from `openapi.json`; the anchor `get-openapi-json` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-openapi-json — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-segments # GET /segments Every segment on the account. ## Request ```bash curl -sS -X GET https://api.agentisend.com/segments \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/segments', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `get-segments` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].rules` | `array` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-segments — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-segments # POST /segments Create a dynamic segment. Rules AND together over properties and status. ## Request ```bash curl -sS -X POST https://api.agentisend.com/segments \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"example"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "rules": [], "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/segments', body: { "name": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `post-segments` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | `string` | yes | A name for the segment list. | | `rules` | `array` | no | Rules that AND together. Omit them and the segment has no members. | | `rules[].field` | `string` | yes | A property name, or status. | | `rules[].op` | `"equals" \| "not_equals" \| "contains" \| "greater_than" \| "less_than" \| "in" \| "exists"` | yes | equals, not_equals, contains, greater_than, less_than, in or exists. | | `rules[].value` | `any` | no | The value to compare. Omitted for exists. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `rules` | `array` | yes | | | `rules[].field` | `string` | yes | A property name, or status. | | `rules[].op` | `"equals" \| "not_equals" \| "contains" \| "greater_than" \| "less_than" \| "in" \| "exists"` | yes | equals, not_equals, contains, greater_than, less_than, in or exists. | | `rules[].value` | `any` | no | The value to compare. Omitted for exists. | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-segments — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-segments-id # GET /segments/{id} One segment. ## Request ```bash curl -sS -X GET https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "rules": [], "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `get-segments-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `rules` | `array` | yes | | | `rules[].field` | `string` | yes | A property name, or status. | | `rules[].op` | `"equals" \| "not_equals" \| "contains" \| "greater_than" \| "less_than" \| "in" \| "exists"` | yes | equals, not_equals, contains, greater_than, less_than, in or exists. | | `rules[].value` | `any` | no | The value to compare. Omitted for exists. | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-segments-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-segments-id # PATCH /segments/{id} Rename or change the rules. Membership re-evaluates immediately. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Buyers"}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "rules": [], "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "name": "Buyers" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"Buyers"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `patch-segments-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | `string` | no | A new name. Omit it to keep the current one. | | `rules` | `array` | no | Replace the rules. Membership is evaluated again immediately. | | `rules[].field` | `string` | yes | A property name, or status. | | `rules[].op` | `"equals" \| "not_equals" \| "contains" \| "greater_than" \| "less_than" \| "in" \| "exists"` | yes | equals, not_equals, contains, greater_than, less_than, in or exists. | | `rules[].value` | `any` | no | The value to compare. Omitted for exists. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `rules` | `array` | yes | | | `rules[].field` | `string` | yes | A property name, or status. | | `rules[].op` | `"equals" \| "not_equals" \| "contains" \| "greater_than" \| "less_than" \| "in" \| "exists"` | yes | equals, not_equals, contains, greater_than, less_than, in or exists. | | `rules[].value` | `any` | no | The value to compare. Omitted for exists. | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-segments-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-segments-id # DELETE /segments/{id} Delete a segment. Contacts are untouched. Refused while a broadcast that has not been sent or archived uses it. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `delete-segments-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`segment_in_use`](https://agentisend.com/docs/errors#segment_in_use) (409) — A broadcast that has not been sent or archived still sends to this segment. **Fix:** Archive each broadcast named in the message with POST /broadcasts/:id/archive, or give it another segment with PATCH /broadcasts/:id, then delete the segment again. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-segments-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-segments-id-contacts # GET /segments/{id}/contacts Contacts in this segment. A segment without rules has no members. ## Request ```bash curl -sS -X GET https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/contacts' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: contacts. Generated from `openapi.json`; the anchor `get-segments-id-contacts` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional - `email` query · `string` · optional - `q` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].first_name` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].last_name` | `string \| null` | yes | | | `data[].object` | `string` | yes | | | `data[].properties` | `object` | yes | | | `data[].property_types` | `object` | yes | | | `data[].status` | `string` | yes | | | `data[].unsubscribed` | `boolean` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-segments-id-contacts — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-segments-id-members # GET /segments/{id}/members The segment evaluated RIGHT NOW — live member ids, never a snapshot. ## Request ```bash curl -sS -X GET https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/members \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "member_ids": [], "total": -9007199254740991, "truncated": false } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/members', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/segments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/members' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: segments. Generated from `openapi.json`; the anchor `get-segments-id-members` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `member_ids` | `array` | yes | | | `total` | `integer` | yes | | | `truncated` | `boolean` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-segments-id-members — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-status # GET /status Public per-component health. Every component reports what it actually checked; one that cannot be checked says so instead of claiming green. ## Request ```bash curl -sS -X GET https://api.agentisend.com/status \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "components": [], "status": "operational", "time": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/status', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/status' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: meta. Generated from `openapi.json`; the anchor `get-status` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `components` | `array` | yes | | | `components[].detail` | `string` | yes | | | `components[].name` | `string` | yes | | | `components[].state` | `"operational" \| "degraded" \| "down" \| "unknown"` | yes | | | `status` | `"operational" \| "degraded" \| "outage"` | yes | | | `time` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-status — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-status-history # GET /status/history Daily uptime per component for 90 days, in minutes. From the first sample, a minute with no reading counts as down, and 3 or more minutes down are an outage. ## Request ```bash curl -sS -X GET https://api.agentisend.com/status/history \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "components": [], "from": "example", "to": "example", "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/status/history', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/status/history' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: meta. Generated from `openapi.json`; the anchor `get-status-history` is the id the console's error `fix` links point at. ## Parameters - `days` query · `integer` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `components` | `array` | yes | | | `components[].availability` | `number \| null` | yes | | | `components[].days` | `array` | yes | | | `components[].name` | `string` | yes | | | `components[].outages` | `array` | yes | | | `from` | `string` | yes | | | `to` | `string` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-status-history — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-support # GET /support Support requests on this account, newest activity first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/support \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/support', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `get-support` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].has_unread_reply` | `boolean` | yes | | | `data[].id` | `string` | yes | | | `data[].last_message_at` | `string` | yes | | | `data[].last_message_preview` | `string` | yes | | | `data[].message_count` | `integer` | yes | | | `data[].ref` | `integer` | yes | | | `data[].ref_label` | `string` | yes | | | `data[].status` | `"open" \| "waiting_on_us" \| "waiting_on_customer" \| "resolved" \| "closed"` | yes | | | `data[].status_label` | `string` | yes | | | `data[].subject` | `string` | yes | | | `data[].topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-support — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support # POST /support Open a support request. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"message":"example","subject":"example","topic":"sending"}' ``` ```json Response 201 { "can_reopen": false, "closed_at": "2026-09-04T09:14:00.000Z", "created_at": "2026-09-04T09:14:00.000Z", "csat_score": -9007199254740991, "has_unread_reply": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_message_at": "2026-09-04T09:14:00.000Z", "last_message_preview": "example", "message_count": -9007199254740991, "messages": [], "ref": -9007199254740991, "ref_label": "example", "related_id": "example", "related_type": "example", "resolved_at": "2026-09-04T09:14:00.000Z", "status": "open", "status_label": "example", "subject": "example", "topic": "sending", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support', body: { "message": "example", "subject": "example", "topic": "sending" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"message":"example","subject":"example","topic":"sending"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachment_ids` | `array` | no | | | `message` | `string` | yes | | | `related_id` | `string \| null` | no | | | `related_type` | `"domain" \| "email" \| "api_key" \| "webhook" \| null` | no | | | `subject` | `string` | yes | | | `topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `can_reopen` | `boolean` | yes | | | `closed_at` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `csat_score` | `integer \| null` | yes | | | `has_unread_reply` | `boolean` | yes | | | `id` | `string` | yes | | | `last_message_at` | `string` | yes | | | `last_message_preview` | `string` | yes | | | `message_count` | `integer` | yes | | | `messages` | `array` | yes | | | `messages[].attachments` | `array` | yes | | | `messages[].author_name` | `string` | yes | | | `messages[].author_type` | `"customer" \| "operator" \| "system"` | yes | | | `messages[].body_html` | `string \| null` | yes | | | `messages[].body_text` | `string` | yes | | | `messages[].channel` | `"form" \| "email" \| "mcp" \| "admin"` | yes | | | `messages[].created_at` | `string` | yes | | | `messages[].id` | `string` | yes | | | `messages[].ticket_id` | `string` | yes | | | `messages[].visibility` | `"public" \| "internal" \| "system"` | yes | | | `ref` | `integer` | yes | | | `ref_label` | `string` | yes | | | `related_id` | `string \| null` | yes | | | `related_type` | `string \| null` | yes | | | `resolved_at` | `string \| null` | yes | | | `status` | `"open" \| "waiting_on_us" \| "waiting_on_customer" \| "resolved" \| "closed"` | yes | | | `status_label` | `string` | yes | | | `subject` | `string` | yes | | | `topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_rate_limited`](https://agentisend.com/docs/errors#support_rate_limited) (429) — Too many support requests from this account just now. **Fix:** Wait and try again. You can open 5 new requests an hour and send 30 replies an hour. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-support-attachments-id-download # GET /support/attachments/{id}/download Download an attachment on a request this account owns. ## Request ```bash curl -sS -X GET https://api.agentisend.com/support/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/download \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 with an empty body ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/support/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/download', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/attachments/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/download' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `get-support-attachments-id-download` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `410` — This resource is no longer available. Codes: support_attachment_expired. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_attachment_expired`](https://agentisend.com/docs/errors#support_attachment_expired) (410) — This file has expired. Attachments are kept for 30 days. **Fix:** Ask the person who uploaded it to send the file again on the request. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-support-attachments-id-download — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-support-config # GET /support/config Topics, hours and attachment limits for opening a support request. ## Request ```bash curl -sS -X GET https://api.agentisend.com/support/config \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "attachment_limits": { "max_bytes_per_file": -9007199254740991, "max_bytes_per_message": -9007199254740991, "max_files_per_message": -9007199254740991 }, "hours_label": "example", "response_time_label": "example", "scale_response_time_label": "example", "topics": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/support/config', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/config' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `get-support-config` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachment_limits` | `object` | yes | | | `attachment_limits.max_bytes_per_file` | `integer` | yes | | | `attachment_limits.max_bytes_per_message` | `integer` | yes | | | `attachment_limits.max_files_per_message` | `integer` | yes | | | `hours_label` | `string` | yes | | | `response_time_label` | `string` | yes | | | `scale_response_time_label` | `string` | yes | | | `topics` | `array` | yes | | | `topics[].id` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `topics[].label` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. --- Source: https://agentisend.com/docs/api/get-support-config — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support-uploads # POST /support/uploads Stage files to attach to a support message. JSON base64; 5 files, 10 MB each, 25 MB total. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support/uploads \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"files":[{"content_base64":"example","filename":"example","mime_type":"example"}]}' ``` ```json Response 201 { "files": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support/uploads', body: { "files": [ { "content_base64": "example", "filename": "example", "mime_type": "example" } ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/uploads' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"files":[{"content_base64":"example","filename":"example","mime_type":"example"}]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support-uploads` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `files` | `array` | yes | | | `files[].content_base64` | `string` | yes | | | `files[].filename` | `string` | yes | | | `files[].mime_type` | `string` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `files` | `array` | yes | | | `files[].filename` | `string` | yes | | | `files[].id` | `string` | yes | | | `files[].mime_type` | `string` | yes | | | `files[].size_bytes` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_upload_rejected`](https://agentisend.com/docs/errors#support_upload_rejected) (400) — That file cannot be attached. **Fix:** Attach a screenshot, PDF, CSV or log file up to 10 MB. Up to 5 files, 25 MB in total, per message. - [`support_upload_too_large`](https://agentisend.com/docs/errors#support_upload_too_large) (413) — That file is larger than 10 MB, or the files together are larger than 25 MB. **Fix:** Remove a file or send a smaller one. Each file must be 10 MB or smaller, and the message 25 MB in total. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support-uploads — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-support-ref # GET /support/{ref} One support request and its public thread. ## Request ```bash curl -sS -X GET https://api.agentisend.com/support/example \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "can_reopen": false, "closed_at": "2026-09-04T09:14:00.000Z", "created_at": "2026-09-04T09:14:00.000Z", "csat_score": -9007199254740991, "has_unread_reply": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_message_at": "2026-09-04T09:14:00.000Z", "last_message_preview": "example", "message_count": -9007199254740991, "messages": [], "ref": -9007199254740991, "ref_label": "example", "related_id": "example", "related_type": "example", "resolved_at": "2026-09-04T09:14:00.000Z", "status": "open", "status_label": "example", "subject": "example", "topic": "sending", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/support/example', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/example' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `get-support-ref` is the id the console's error `fix` links point at. ## Parameters - `ref` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `can_reopen` | `boolean` | yes | | | `closed_at` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `csat_score` | `integer \| null` | yes | | | `has_unread_reply` | `boolean` | yes | | | `id` | `string` | yes | | | `last_message_at` | `string` | yes | | | `last_message_preview` | `string` | yes | | | `message_count` | `integer` | yes | | | `messages` | `array` | yes | | | `messages[].attachments` | `array` | yes | | | `messages[].author_name` | `string` | yes | | | `messages[].author_type` | `"customer" \| "operator" \| "system"` | yes | | | `messages[].body_html` | `string \| null` | yes | | | `messages[].body_text` | `string` | yes | | | `messages[].channel` | `"form" \| "email" \| "mcp" \| "admin"` | yes | | | `messages[].created_at` | `string` | yes | | | `messages[].id` | `string` | yes | | | `messages[].ticket_id` | `string` | yes | | | `messages[].visibility` | `"public" \| "internal" \| "system"` | yes | | | `ref` | `integer` | yes | | | `ref_label` | `string` | yes | | | `related_id` | `string \| null` | yes | | | `related_type` | `string \| null` | yes | | | `resolved_at` | `string \| null` | yes | | | `status` | `"open" \| "waiting_on_us" \| "waiting_on_customer" \| "resolved" \| "closed"` | yes | | | `status_label` | `string` | yes | | | `subject` | `string` | yes | | | `topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-support-ref — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support-ref-csat # POST /support/{ref}/csat Rate a resolved support request, 1 to 5. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support/example/csat \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"score":1}' ``` ```json Response 200 { "ok": true } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support/example/csat', body: { "score": 1 }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/example/csat' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"score":1}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support-ref-csat` is the id the console's error `fix` links point at. ## Parameters - `ref` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `comment` | `string \| null` | no | | | `score` | `integer` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `ok` | `boolean` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_closed`](https://agentisend.com/docs/errors#support_closed) (409) — This request is closed, so a reply cannot be added to it. **Fix:** Start a new request from Support in the console. If this one was resolved in the last 14 days, reopen it first. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support-ref-csat — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support-ref-messages # POST /support/{ref}/messages Reply on a support request. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support/example/messages \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"message":"example"}' ``` ```json Response 201 { "attachments": [], "author_name": "example", "author_type": "customer", "body_html": "example", "body_text": "example", "channel": "form", "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "ticket_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "visibility": "public" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support/example/messages', body: { "message": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/example/messages' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"message":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support-ref-messages` is the id the console's error `fix` links point at. ## Parameters - `ref` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachment_ids` | `array` | no | | | `message` | `string` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `attachments` | `array` | yes | | | `attachments[].download_url` | `string` | no | | | `attachments[].expired` | `boolean` | yes | | | `attachments[].filename` | `string` | yes | | | `attachments[].id` | `string` | yes | | | `attachments[].is_image` | `boolean` | yes | | | `attachments[].mime_type` | `string` | yes | | | `attachments[].size_bytes` | `integer` | yes | | | `author_name` | `string` | yes | | | `author_type` | `"customer" \| "operator" \| "system"` | yes | | | `body_html` | `string \| null` | yes | | | `body_text` | `string` | yes | | | `channel` | `"form" \| "email" \| "mcp" \| "admin"` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `ticket_id` | `string` | yes | | | `visibility` | `"public" \| "internal" \| "system"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_closed`](https://agentisend.com/docs/errors#support_closed) (409) — This request is closed, so a reply cannot be added to it. **Fix:** Start a new request from Support in the console. If this one was resolved in the last 14 days, reopen it first. - [`support_rate_limited`](https://agentisend.com/docs/errors#support_rate_limited) (429) — Too many support requests from this account just now. **Fix:** Wait and try again. You can open 5 new requests an hour and send 30 replies an hour. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support-ref-messages — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support-ref-reopen # POST /support/{ref}/reopen Reopen a resolved request within 14 days. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support/example/reopen \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "can_reopen": false, "closed_at": "2026-09-04T09:14:00.000Z", "created_at": "2026-09-04T09:14:00.000Z", "csat_score": -9007199254740991, "has_unread_reply": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_message_at": "2026-09-04T09:14:00.000Z", "last_message_preview": "example", "message_count": -9007199254740991, "messages": [], "ref": -9007199254740991, "ref_label": "example", "related_id": "example", "related_type": "example", "resolved_at": "2026-09-04T09:14:00.000Z", "status": "open", "status_label": "example", "subject": "example", "topic": "sending", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support/example/reopen', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/example/reopen' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support-ref-reopen` is the id the console's error `fix` links point at. ## Parameters - `ref` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `can_reopen` | `boolean` | yes | | | `closed_at` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `csat_score` | `integer \| null` | yes | | | `has_unread_reply` | `boolean` | yes | | | `id` | `string` | yes | | | `last_message_at` | `string` | yes | | | `last_message_preview` | `string` | yes | | | `message_count` | `integer` | yes | | | `messages` | `array` | yes | | | `messages[].attachments` | `array` | yes | | | `messages[].author_name` | `string` | yes | | | `messages[].author_type` | `"customer" \| "operator" \| "system"` | yes | | | `messages[].body_html` | `string \| null` | yes | | | `messages[].body_text` | `string` | yes | | | `messages[].channel` | `"form" \| "email" \| "mcp" \| "admin"` | yes | | | `messages[].created_at` | `string` | yes | | | `messages[].id` | `string` | yes | | | `messages[].ticket_id` | `string` | yes | | | `messages[].visibility` | `"public" \| "internal" \| "system"` | yes | | | `ref` | `integer` | yes | | | `ref_label` | `string` | yes | | | `related_id` | `string \| null` | yes | | | `related_type` | `string \| null` | yes | | | `resolved_at` | `string \| null` | yes | | | `status` | `"open" \| "waiting_on_us" \| "waiting_on_customer" \| "resolved" \| "closed"` | yes | | | `status_label` | `string` | yes | | | `subject` | `string` | yes | | | `topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_closed`](https://agentisend.com/docs/errors#support_closed) (409) — This request is closed, so a reply cannot be added to it. **Fix:** Start a new request from Support in the console. If this one was resolved in the last 14 days, reopen it first. - [`support_reopen_expired`](https://agentisend.com/docs/errors#support_reopen_expired) (409) — This request can no longer be reopened. **Fix:** A request can be reopened within 14 days of being marked resolved. Start a new request from Support in the console. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support-ref-reopen — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-support-ref-resolve # POST /support/{ref}/resolve Mark a support request resolved. ## Request ```bash curl -sS -X POST https://api.agentisend.com/support/example/resolve \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 200 { "can_reopen": false, "closed_at": "2026-09-04T09:14:00.000Z", "created_at": "2026-09-04T09:14:00.000Z", "csat_score": -9007199254740991, "has_unread_reply": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_message_at": "2026-09-04T09:14:00.000Z", "last_message_preview": "example", "message_count": -9007199254740991, "messages": [], "ref": -9007199254740991, "ref_label": "example", "related_id": "example", "related_type": "example", "resolved_at": "2026-09-04T09:14:00.000Z", "status": "open", "status_label": "example", "subject": "example", "topic": "sending", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/support/example/resolve', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/support/example/resolve' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: support. Generated from `openapi.json`; the anchor `post-support-ref-resolve` is the id the console's error `fix` links point at. ## Parameters - `ref` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `can_reopen` | `boolean` | yes | | | `closed_at` | `string \| null` | yes | | | `created_at` | `string` | yes | | | `csat_score` | `integer \| null` | yes | | | `has_unread_reply` | `boolean` | yes | | | `id` | `string` | yes | | | `last_message_at` | `string` | yes | | | `last_message_preview` | `string` | yes | | | `message_count` | `integer` | yes | | | `messages` | `array` | yes | | | `messages[].attachments` | `array` | yes | | | `messages[].author_name` | `string` | yes | | | `messages[].author_type` | `"customer" \| "operator" \| "system"` | yes | | | `messages[].body_html` | `string \| null` | yes | | | `messages[].body_text` | `string` | yes | | | `messages[].channel` | `"form" \| "email" \| "mcp" \| "admin"` | yes | | | `messages[].created_at` | `string` | yes | | | `messages[].id` | `string` | yes | | | `messages[].ticket_id` | `string` | yes | | | `messages[].visibility` | `"public" \| "internal" \| "system"` | yes | | | `ref` | `integer` | yes | | | `ref_label` | `string` | yes | | | `related_id` | `string \| null` | yes | | | `related_type` | `string \| null` | yes | | | `resolved_at` | `string \| null` | yes | | | `status` | `"open" \| "waiting_on_us" \| "waiting_on_customer" \| "resolved" \| "closed"` | yes | | | `status_label` | `string` | yes | | | `subject` | `string` | yes | | | `topic` | `"sending" \| "domains" \| "deliverability" \| "guardrails_and_limits" \| "trust_and_appeals" \| "webhooks" \| "api_sdk_mcp" \| "billing" \| "account_and_security" \| "other"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`support_closed`](https://agentisend.com/docs/errors#support_closed) (409) — This request is closed, so a reply cannot be added to it. **Fix:** Start a new request from Support in the console. If this one was resolved in the last 14 days, reopen it first. - [`support_ticket_not_found`](https://agentisend.com/docs/errors#support_ticket_not_found) (404) — That request does not exist. **Fix:** Open Support in the console and pick a request from the list, or start a new one. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-support-ref-resolve — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-suppressions # GET /suppressions Every suppressed address or domain for this account (global platform rows included). ## Request ```bash curl -sS -X GET https://api.agentisend.com/suppressions \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/suppressions', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `get-suppressions` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `origin` query · `"bounce" | "complaint" | "manual"` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].level` | `"address" \| "domain" \| "global"` | yes | | | `data[].origin` | `string` | yes | | | `data[].platform` | `boolean` | yes | | | `data[].source_id` | `string \| null` | yes | | | `data[].stream` | `"transactional" \| "marketing" \| null` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-suppressions — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-suppressions # POST /suppressions Suppress an address or a whole domain (send "@example.com"). Idempotent — an existing row is returned. ## Request ```bash curl -sS -X POST https://api.agentisend.com/suppressions \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"example"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "level": "address", "origin": "example", "platform": false, "source_id": "example", "stream": "transactional" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/suppressions', body: { "email": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"email":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `post-suppressions` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | yes | An address, or @example.com to suppress a whole domain. | | `level` | `"address" \| "domain"` | no | address or domain. Inferred from the value when omitted. | | `origin` | `"bounce" \| "complaint" \| "manual"` | no | Defaults to manual. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `id` | `string` | yes | | | `level` | `"address" \| "domain" \| "global"` | yes | | | `origin` | `string` | yes | | | `platform` | `boolean` | yes | | | `source_id` | `string \| null` | yes | | | `stream` | `"transactional" \| "marketing" \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-suppressions — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-suppressions-batch-add # POST /suppressions/batch/add Suppress up to 500 addresses in one call. Each item succeeds or fails on its own — read data[i].status. ## Request ```bash curl -sS -X POST https://api.agentisend.com/suppressions/batch/add \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"emails":["example"]}' ``` ```json Response 200 { "data": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/suppressions/batch/add', body: { "emails": [ "example" ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions/batch/add' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"emails":["example"]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `post-suppressions-batch-add` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `emails` | `array` | yes | Addresses to change. At most 500. | | `level` | `"address" \| "domain"` | no | address or domain, applied to every item. Inferred when omitted. | | `origin` | `"bounce" \| "complaint" \| "manual"` | no | Defaults to manual. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].email` | `string` | yes | | | `data[].error` | `object` | no | | | `data[].id` | `string` | no | | | `data[].index` | `integer` | yes | | | `data[].status` | `"added" \| "removed" \| "not_found" \| "rejected"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-suppressions-batch-add — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-suppressions-batch-remove # POST /suppressions/batch/remove Lift up to 500 suppressions by address. An address that was not suppressed reads not_found, not an error. ## Request ```bash curl -sS -X POST https://api.agentisend.com/suppressions/batch/remove \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"emails":["example"]}' ``` ```json Response 200 { "data": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/suppressions/batch/remove', body: { "emails": [ "example" ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions/batch/remove' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"emails":["example"]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `post-suppressions-batch-remove` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `emails` | `array` | yes | Addresses to change. At most 500. | | `level` | `"address" \| "domain"` | no | address or domain, applied to every item. Inferred when omitted. | | `origin` | `"bounce" \| "complaint" \| "manual"` | no | Defaults to manual. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].email` | `string` | yes | | | `data[].error` | `object` | no | | | `data[].id` | `string` | no | | | `data[].index` | `integer` | yes | | | `data[].status` | `"added" \| "removed" \| "not_found" \| "rejected"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-suppressions-batch-remove — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-suppressions-id # GET /suppressions/{id} One suppression, by its id or by the address. A platform row is included and marked platform. ## Request ```bash curl -sS -X GET https://api.agentisend.com/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "level": "address", "origin": "example", "platform": false, "source_id": "example", "stream": "transactional" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `get-suppressions-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `id` | `string` | yes | | | `level` | `"address" \| "domain" \| "global"` | yes | | | `origin` | `string` | yes | | | `platform` | `boolean` | yes | | | `source_id` | `string \| null` | yes | | | `stream` | `"transactional" \| "marketing" \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-suppressions-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-suppressions-id # DELETE /suppressions/{id} Remove one suppression row. A hard bounce you have fixed can be cleared with an API key; an unsubscribe or a spam complaint is a person’s to lift, in the console. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/suppressions/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: suppressions. Generated from `openapi.json`; the anchor `delete-suppressions-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`human_action_required`](https://agentisend.com/docs/errors#human_action_required) (403) — This is a person’s decision, so an API key cannot make it. **Fix:** Ask whoever runs this account to do it in the console. Scoping the key differently does not change the answer, and retrying fails the same way. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-suppressions-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-team-invites # GET /team/invites Invitations that have not been accepted, cancelled or expired. ## Request ```bash curl -sS -X GET https://api.agentisend.com/team/invites \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/team/invites', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/invites' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `get-team-invites` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].expires_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].invited_by` | `string \| null` | yes | | | `data[].invited_by_email` | `string \| null` | yes | | | `data[].role` | `"owner" \| "admin" \| "viewer"` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-team-invites — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-team-invites # POST /team/invites Invite an address at a role. The mail carries a link that only works while signed in as that address. ## Request ```bash curl -sS -X POST https://api.agentisend.com/team/invites \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"customer@example.com"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "invited_by": "example", "invited_by_email": "example", "role": "owner" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/team/invites', body: { "email": "customer@example.com" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/invites' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"email":"customer@example.com"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `post-team-invites` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | no | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `expires_at` | `string` | yes | | | `id` | `string` | yes | | | `invited_by` | `string \| null` | yes | | | `invited_by_email` | `string \| null` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`already_in_account`](https://agentisend.com/docs/errors#already_in_account) (409) — This address already belongs to an account. **Fix:** Leave the current account first, or ask the inviter to send the invitation to an address that has no account. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invite_limit_reached`](https://agentisend.com/docs/errors#invite_limit_reached) (429) — This account has sent as many invitations as it may for now: 10 a day, and 3 to one address in 7 days. **Fix:** Wait the seconds given and invite again. A cancelled invitation still counts for 24 hours. Someone who already has an invitation can use the link in it. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`seat_limit_reached`](https://agentisend.com/docs/errors#seat_limit_reached) (422) — This plan has no seat left for another member. **Fix:** Remove a member with DELETE /team/members/:id, cancel a pending invite with DELETE /team/invites/:id, or move to a plan with more seats. Seats are never billed per seat. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-team-invites — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-team-invites-id # DELETE /team/invites/{id} Cancel a pending invitation. The link in the email stops working immediately. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/team/invites/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "cancelled": true, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/team/invites/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/invites/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `delete-team-invites-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `cancelled` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invite_not_valid`](https://agentisend.com/docs/errors#invite_not_valid) (422) — This invitation is expired, cancelled, or already accepted. **Fix:** Ask an owner or admin to send a new one with POST /team/invites. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-team-invites-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-team-me # GET /team/me Your membership on this account: your role, and the seats the plan allows. ## Request ```bash curl -sS -X GET https://api.agentisend.com/team/me \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "email": "example", "role": "owner", "seats": { "billed_per_seat": false, "limit": -9007199254740991, "plan": "example", "used": -9007199254740991 }, "user_id": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/team/me', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/me' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `get-team-me` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string \| null` | yes | | | `role` | `"owner" \| "admin" \| "viewer" \| null` | yes | | | `seats` | `object` | yes | | | `seats.billed_per_seat` | `boolean` | yes | | | `seats.limit` | `integer` | yes | | | `seats.plan` | `string` | yes | | | `seats.used` | `integer` | yes | | | `user_id` | `string \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-team-me — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-team-members # GET /team/members Everyone on this account and the role each one holds. Owner, admin, viewer — three roles, and seats are never billed per seat. ## Request ```bash curl -sS -X GET https://api.agentisend.com/team/members \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/team/members', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/members' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `get-team-members` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].email` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].is_you` | `boolean` | yes | | | `data[].name` | `string \| null` | yes | | | `data[].role` | `"owner" \| "admin" \| "viewer"` | yes | | | `data[].user_id` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-team-members — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-team-members # POST /team/members Add someone to this account. Membership begins when they accept, so this returns the pending invitation — the same call as POST /team/invites. ## Request ```bash curl -sS -X POST https://api.agentisend.com/team/members \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"customer@example.com"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "expires_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "invited_by": "example", "invited_by_email": "example", "role": "owner" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/team/members', body: { "email": "customer@example.com" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/members' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"email":"customer@example.com"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `post-team-members` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `email` | `string` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | no | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `expires_at` | `string` | yes | | | `id` | `string` | yes | | | `invited_by` | `string \| null` | yes | | | `invited_by_email` | `string \| null` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`already_in_account`](https://agentisend.com/docs/errors#already_in_account) (409) — This address already belongs to an account. **Fix:** Leave the current account first, or ask the inviter to send the invitation to an address that has no account. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invite_limit_reached`](https://agentisend.com/docs/errors#invite_limit_reached) (429) — This account has sent as many invitations as it may for now: 10 a day, and 3 to one address in 7 days. **Fix:** Wait the seconds given and invite again. A cancelled invitation still counts for 24 hours. Someone who already has an invitation can use the link in it. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`seat_limit_reached`](https://agentisend.com/docs/errors#seat_limit_reached) (422) — This plan has no seat left for another member. **Fix:** Remove a member with DELETE /team/members/:id, cancel a pending invite with DELETE /team/invites/:id, or move to a plan with more seats. Seats are never billed per seat. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-team-members — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-team-members-id # PATCH /team/members/{id} Change a member’s role. The last owner cannot be demoted. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"role":"owner"}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "email": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "is_you": false, "name": "example", "role": "owner", "user_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "role": "owner" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"role":"owner"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `patch-team-members-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `role` | `"owner" \| "admin" \| "viewer"` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `email` | `string` | yes | | | `id` | `string` | yes | | | `is_you` | `boolean` | yes | | | `name` | `string \| null` | yes | | | `role` | `"owner" \| "admin" \| "viewer"` | yes | | | `user_id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`last_owner_required`](https://agentisend.com/docs/errors#last_owner_required) (422) — An account must keep at least one owner. **Fix:** Promote another member to owner with PATCH /team/members/:id first, then retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-team-members-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-team-members-id # DELETE /team/members/{id} Remove a member. Their sends and keys stay; only their access ends. The last owner cannot be removed. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "removed": true } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/team/members/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: team. Generated from `openapi.json`; the anchor `delete-team-members-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `removed` | `boolean` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`last_owner_required`](https://agentisend.com/docs/errors#last_owner_required) (422) — An account must keep at least one owner. **Fix:** Promote another member to owner with PATCH /team/members/:id first, then retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`session_required`](https://agentisend.com/docs/errors#session_required) (401) — You are signed out. **Fix:** Sign in to the console, then retry. API keys cannot call this route. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-team-members-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-templates # GET /templates List this account templates, newest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/templates \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/templates', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `get-templates` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].current_version_number` | `integer \| null` | yes | | | `data[].draft_content` | `object \| object \| null` | yes | | | `data[].draft_subject` | `string \| null` | yes | | | `data[].draft_variables` | `array \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].status` | `"draft" \| "published"` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-templates — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-templates # POST /templates Create a template draft. ## Request ```bash curl -sS -X POST https://api.agentisend.com/templates \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"content":{"blocks":[{"body":"example","kind":"text"}],"mode":"block"},"name":"example","subject":"example"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "current_version_number": -9007199254740991, "draft_content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "draft_subject": "example", "draft_variables": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "draft", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/templates', body: { "content": { "blocks": [ { "body": "example", "kind": "text" } ], "mode": "block" }, "name": "example", "subject": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"content":{"blocks":[{"body":"example","kind":"text"}],"mode":"block"},"name":"example","subject":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `post-templates` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | yes | The template body: markdown, html, or blocks. | | `name` | `string` | yes | A name for the template list. | | `subject` | `string` | yes | Subject of the message this template sends. | | `variables` | `array` | no | Placeholders the body uses. | | `variables[].default` | `string` | no | Used when the render call omits this name. | | `variables[].name` | `string` | yes | Placeholder name, without the braces. | | `variables[].required` | `boolean` | no | A missing required value fails the render, unless preview is true. | | `variables[].type` | `"string" \| "number" \| "boolean"` | yes | string, number or boolean. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version_number` | `integer \| null` | yes | | | `draft_content` | `object \| object \| null` | yes | | | `draft_subject` | `string \| null` | yes | | | `draft_variables` | `array \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `"draft" \| "published"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`template_name_taken`](https://agentisend.com/docs/errors#template_name_taken) (409) — A template with this name already exists on this account. **Fix:** Choose another name, or edit the existing template with PATCH /templates/:id. GET /templates lists them with their ids. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-templates — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-templates-id # GET /templates/{id} One template. ## Request ```bash curl -sS -X GET https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version_number": -9007199254740991, "draft_content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "draft_subject": "example", "draft_variables": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "draft", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `get-templates-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version_number` | `integer \| null` | yes | | | `draft_content` | `object \| object \| null` | yes | | | `draft_subject` | `string \| null` | yes | | | `draft_variables` | `array \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `"draft" \| "published"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-templates-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-templates-id # PATCH /templates/{id} Edit the draft. Published templates are immutable. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"subject":"Your receipt"}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "current_version_number": -9007199254740991, "draft_content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "draft_subject": "example", "draft_variables": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "draft", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "subject": "Your receipt" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"subject":"Your receipt"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `patch-templates-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | no | Replace the draft body. | | `subject` | `string` | no | Replace the draft subject. | | `variables` | `array` | no | Replace the placeholder list. | | `variables[].default` | `string` | no | Used when the render call omits this name. | | `variables[].name` | `string` | yes | Placeholder name, without the braces. | | `variables[].required` | `boolean` | no | A missing required value fails the render, unless preview is true. | | `variables[].type` | `"string" \| "number" \| "boolean"` | yes | string, number or boolean. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version_number` | `integer \| null` | yes | | | `draft_content` | `object \| object \| null` | yes | | | `draft_subject` | `string \| null` | yes | | | `draft_variables` | `array \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `"draft" \| "published"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-templates-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-templates-id # DELETE /templates/{id} Delete a template and its versions. Sent mail keeps its body and template reference. Refused while a broadcast that has not been sent uses it. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `delete-templates-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`template_in_use`](https://agentisend.com/docs/errors#template_in_use) (409) — A broadcast that has not been sent yet still uses this template. **Fix:** Archive each broadcast named in the message with POST /broadcasts/:id/archive, then delete the template again. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-templates-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-templates-id-diff # GET /templates/{id}/diff Structured diff between two versions, or between a version and the draft. ## Request ```bash curl -sS -X GET https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/diff?from=draft&to=draft \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "changes": [], "from_version_number": -9007199254740991, "template_id": "example", "to_version_number": -9007199254740991, "unchanged": false } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/diff', query: { from: 'draft' to: 'draft' }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/diff?from=draft&to=draft' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `get-templates-id-diff` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `from` query · `string | integer` · required - `to` query · `string | integer` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `changes` | `array` | yes | | | `changes[].after` | `any` | no | | | `changes[].before` | `any` | no | | | `changes[].kind` | `"added" \| "removed" \| "changed"` | yes | | | `changes[].path` | `string` | yes | | | `from_version_number` | `integer` | yes | | | `template_id` | `string` | yes | | | `to_version_number` | `integer` | yes | | | `unchanged` | `boolean` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-templates-id-diff — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-templates-id-duplicate # POST /templates/{id}/duplicate Copy a template into a new editable draft. The copy carries no version history. ## Request ```bash curl -sS -X POST https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/duplicate \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "current_version_number": -9007199254740991, "draft_content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "draft_subject": "example", "draft_variables": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "draft", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/duplicate', body: {}, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/duplicate' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `post-templates-id-duplicate` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | `string` | no | Name of the copy. Omit it to reuse the source name. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `current_version_number` | `integer \| null` | yes | | | `draft_content` | `object \| object \| null` | yes | | | `draft_subject` | `string \| null` | yes | | | `draft_variables` | `array \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `status` | `"draft" \| "published"` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`template_name_taken`](https://agentisend.com/docs/errors#template_name_taken) (409) — A template with this name already exists on this account. **Fix:** Choose another name, or edit the existing template with PATCH /templates/:id. GET /templates lists them with their ids. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-templates-id-duplicate — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-templates-id-publish # POST /templates/{id}/publish Snapshot the draft as an immutable published version. ## Request ```bash curl -sS -X POST https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/publish \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "template": { "created_at": "2026-09-04T09:14:00.000Z", "current_version_number": -9007199254740991, "draft_content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "draft_subject": "example", "draft_variables": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "status": "draft", "updated_at": "2026-09-04T09:14:00.000Z" }, "version": { "content": { "mode": "markdown", "source": "Thanks — the details are attached." }, "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "rolled_back_from": -9007199254740991, "status": "draft", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "variables": [], "version_number": -9007199254740991 } } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/publish', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/publish' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `post-templates-id-publish` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `template` | `object` | yes | | | `template.created_at` | `string` | yes | | | `template.current_version_number` | `integer \| null` | yes | | | `template.draft_content` | `object \| object \| null` | yes | | | `template.draft_subject` | `string \| null` | yes | | | `template.draft_variables` | `array \| null` | yes | | | `template.id` | `string` | yes | | | `template.name` | `string` | yes | | | `template.status` | `"draft" \| "published"` | yes | | | `template.updated_at` | `string` | yes | | | `version` | `object` | yes | | | `version.content` | `object \| object` | yes | | | `version.created_at` | `string` | yes | | | `version.id` | `string` | yes | | | `version.rolled_back_from` | `integer \| null` | yes | | | `version.status` | `"draft" \| "published"` | yes | | | `version.subject` | `string` | yes | | | `version.template_id` | `string` | yes | | | `version.variables` | `array` | yes | | | `version.version_number` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-templates-id-publish — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-templates-id-render # POST /templates/{id}/render Render a version with variables (defaults to the current published one; pass "draft" for the working copy). Returns the HTML, the subject and, for markdown, the plain-text part. Unknown variables fail with the names listed; a missing required one fails too unless preview is true, which shows its placeholder (such as {{first_name}}) and lists it in missing_variables. ## Request ```bash curl -sS -X POST https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/render \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"preview":true}' ``` ```json Response 200 { "missing_variables": [], "rendered": "example", "subject": "example", "text": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/render', body: { "preview": true }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/render' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"preview":true}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `post-templates-id-render` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `preview` | `boolean` | no | true shows a missing required placeholder instead of refusing the render. | | `values` | `object` | no | Placeholder values for this render. | | `variables` | `object` | no | Same as values. values wins if both are sent. | | `version_number` | `string \| integer` | no | A published version number, or draft. Omit it for the current published version. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `missing_variables` | `array` | yes | | | `rendered` | `string` | yes | | | `subject` | `string` | yes | | | `text` | `string \| null` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-templates-id-render — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-templates-id-rollback # POST /templates/{id}/rollback Start a new draft from an older version. History is never rewritten; the live version stays until that draft is published. ## Request ```bash curl -sS -X POST https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rollback \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"to_version":1}' ``` ```json Response 201 { "content": { "blocks": [ { "body": "example", "kind": "text" } ], "mode": "block" }, "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "rolled_back_from": -9007199254740991, "status": "draft", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "variables": [], "version_number": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rollback', body: { "to_version": 1 }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rollback' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"to_version":1}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `post-templates-id-rollback` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `to_version` | `integer` | yes | The published version number to copy into a new draft. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `rolled_back_from` | `integer \| null` | yes | | | `status` | `"draft" \| "published"` | yes | | | `subject` | `string` | yes | | | `template_id` | `string` | yes | | | `variables` | `array` | yes | | | `variables[].default` | `string` | no | Used when the render call omits this name. | | `variables[].name` | `string` | yes | Placeholder name, without the braces. | | `variables[].required` | `boolean` | no | A missing required value fails the render, unless preview is true. | | `variables[].type` | `"string" \| "number" \| "boolean"` | yes | string, number or boolean. | | `version_number` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-templates-id-rollback — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-templates-id-versions # GET /templates/{id}/versions Every immutable version, oldest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `get-templates-id-versions` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].content` | `object \| object` | yes | | | `data[].created_at` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].rolled_back_from` | `integer \| null` | yes | | | `data[].status` | `"draft" \| "published"` | yes | | | `data[].subject` | `string` | yes | | | `data[].template_id` | `string` | yes | | | `data[].variables` | `array` | yes | | | `data[].version_number` | `integer` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-templates-id-versions — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-templates-id-versions-n # GET /templates/{id}/versions/{n} One version. ## Request ```bash curl -sS -X GET https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions/1 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "content": { "blocks": [ { "body": "example", "kind": "text" } ], "mode": "block" }, "created_at": "2026-09-04T09:14:00.000Z", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "rolled_back_from": -9007199254740991, "status": "draft", "subject": "example", "template_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "variables": [], "version_number": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions/1', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/templates/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/versions/1' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: templates. Generated from `openapi.json`; the anchor `get-templates-id-versions-n` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `n` path · `integer` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `content` | `object \| object` | yes | | | `created_at` | `string` | yes | | | `id` | `string` | yes | | | `rolled_back_from` | `integer \| null` | yes | | | `status` | `"draft" \| "published"` | yes | | | `subject` | `string` | yes | | | `template_id` | `string` | yes | | | `variables` | `array` | yes | | | `variables[].default` | `string` | no | Used when the render call omits this name. | | `variables[].name` | `string` | yes | Placeholder name, without the braces. | | `variables[].required` | `boolean` | no | A missing required value fails the render, unless preview is true. | | `variables[].type` | `"string" \| "number" \| "boolean"` | yes | string, number or boolean. | | `version_number` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-templates-id-versions-n — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-topics # GET /topics Every subscription topic on the account, newest first. ## Request ```bash curl -sS -X GET https://api.agentisend.com/topics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/topics', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/topics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: topics. Generated from `openapi.json`; the anchor `get-topics` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].default_subscribed` | `boolean` | yes | | | `data[].description` | `string \| null` | yes | | | `data[].id` | `string` | yes | | | `data[].name` | `string` | yes | | | `data[].updated_at` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-topics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-topics # POST /topics Create a subscription topic. default_subscribed=false makes it opt-in: silence means no. ## Request ```bash curl -sS -X POST https://api.agentisend.com/topics \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"example"}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "default_subscribed": false, "description": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/topics', body: { "name": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/topics' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: topics. Generated from `openapi.json`; the anchor `post-topics` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `default_subscribed` | `boolean` | no | true sends this topic unless the contact opts out. false means silence is no. | | `description` | `string` | no | Shown with the topic when a contact chooses. | | `name` | `string` | yes | A name for the topic list. Unique on this account. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `default_subscribed` | `boolean` | yes | | | `description` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-topics — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-topics-id # GET /topics/{id} One topic. ## Request ```bash curl -sS -X GET https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "default_subscribed": false, "description": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: topics. Generated from `openapi.json`; the anchor `get-topics-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `default_subscribed` | `boolean` | yes | | | `description` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-topics-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-topics-id # PATCH /topics/{id} Rename a topic or change its default. Changing the default never rewrites an answer a contact already gave. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Product news"}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "default_subscribed": false, "description": "example", "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "name": "example", "updated_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "name": "Product news" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"name":"Product news"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: topics. Generated from `openapi.json`; the anchor `patch-topics-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `default_subscribed` | `boolean` | no | Whether a contact who has never answered receives this topic. | | `description` | `string \| null` | no | A new description. Null clears it. | | `name` | `string` | no | A new name. Omit it to keep the current one. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `default_subscribed` | `boolean` | yes | | | `description` | `string \| null` | yes | | | `id` | `string` | yes | | | `name` | `string` | yes | | | `updated_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-topics-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-topics-id # DELETE /topics/{id} Delete a topic and every recorded answer about it. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/topics/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: topics. Generated from `openapi.json`; the anchor `delete-topics-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-topics-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-trust-appeal # POST /trust/appeal File an appeal against the current standing. The reason is recorded verbatim; a human answers by sla_deadline_at. ## Request ```bash curl -sS -X POST https://api.agentisend.com/trust/appeal \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"reason":"examplexxx"}' ``` ```json Response 201 { "history": [], "next_review_at": "2026-09-04T09:14:00.000Z", "reason_codes": [], "reasons": [], "sla_deadline_at": "2026-09-04T09:14:00.000Z", "state": "ok", "streams": { "marketing": { "bounce_rate": 1, "bounced": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "sent": -9007199254740991, "state": "ok" }, "transactional": { "bounce_rate": 1, "bounced": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "sent": -9007199254740991, "state": "ok" } }, "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/trust/appeal', body: { "reason": "examplexxx" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/trust/appeal' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"reason":"examplexxx"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: trust. Generated from `openapi.json`; the anchor `post-trust-appeal` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `reason` | `string` | yes | | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `history` | `array` | yes | | | `history[].occurred_at` | `string` | yes | | | `history[].reason` | `string \| null` | yes | | | `history[].type` | `string` | yes | | | `next_review_at` | `string \| null` | yes | | | `reason_codes` | `array` | yes | | | `reasons` | `array` | yes | | | `reasons[].code` | `string` | yes | | | `reasons[].message` | `string` | yes | | | `reasons[].metric` | `"bounce" \| "complaint" \| null` | yes | | | `reasons[].samples` | `array` | yes | | | `reasons[].since` | `string` | yes | | | `reasons[].stream` | `"transactional" \| "marketing" \| null` | yes | | | `reasons[].threshold` | `number \| null` | yes | | | `reasons[].value` | `number \| null` | yes | | | `reasons[].window` | `integer` | yes | | | `sla_deadline_at` | `string \| null` | yes | | | `state` | `"ok" \| "warning" \| "throttled" \| "paused"` | yes | | | `streams` | `object` | yes | | | `streams.marketing` | `object` | yes | | | `streams.transactional` | `object` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-trust-appeal — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-trust-remediation # GET /trust/remediation The remediation checklist ticks for this account. Per account, not per browser — the work one person does is done for everyone on it. ## Request ```bash curl -sS -X GET https://api.agentisend.com/trust/remediation \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "items": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/trust/remediation', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/trust/remediation' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: trust. Generated from `openapi.json`; the anchor `get-trust-remediation` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `items` | `array` | yes | | | `items[].done_at` | `string \| null` | yes | | | `items[].key` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-trust-remediation — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-trust-remediation # POST /trust/remediation Tick or untick one remediation item. Returns the whole checklist. ## Request ```bash curl -sS -X POST https://api.agentisend.com/trust/remediation \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"done":false,"key":"example"}' ``` ```json Response 200 { "items": [] } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/trust/remediation', body: { "done": false, "key": "example" }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/trust/remediation' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"done":false,"key":"example"}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: trust. Generated from `openapi.json`; the anchor `post-trust-remediation` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `done` | `boolean` | yes | | | `key` | `string` | yes | | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `items` | `array` | yes | | | `items[].done_at` | `string \| null` | yes | | | `items[].key` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-trust-remediation — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-trust-standing # GET /trust/standing This account’s standing, machine-readable. An agent can query it and back off before enforcement does it for them. ## Request ```bash curl -sS -X GET https://api.agentisend.com/trust/standing \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "history": [], "next_review_at": "2026-09-04T09:14:00.000Z", "reason_codes": [], "reasons": [], "sla_deadline_at": "2026-09-04T09:14:00.000Z", "state": "ok", "streams": { "marketing": { "bounce_rate": 1, "bounced": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "sent": -9007199254740991, "state": "ok" }, "transactional": { "bounce_rate": 1, "bounced": -9007199254740991, "complained": -9007199254740991, "complaint_rate": 1, "sent": -9007199254740991, "state": "ok" } }, "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/trust/standing', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/trust/standing' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: trust. Generated from `openapi.json`; the anchor `get-trust-standing` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `history` | `array` | yes | | | `history[].occurred_at` | `string` | yes | | | `history[].reason` | `string \| null` | yes | | | `history[].type` | `string` | yes | | | `next_review_at` | `string \| null` | yes | | | `reason_codes` | `array` | yes | | | `reasons` | `array` | yes | | | `reasons[].code` | `string` | yes | | | `reasons[].message` | `string` | yes | | | `reasons[].metric` | `"bounce" \| "complaint" \| null` | yes | | | `reasons[].samples` | `array` | yes | | | `reasons[].since` | `string` | yes | | | `reasons[].stream` | `"transactional" \| "marketing" \| null` | yes | | | `reasons[].threshold` | `number \| null` | yes | | | `reasons[].value` | `number \| null` | yes | | | `reasons[].window` | `integer` | yes | | | `sla_deadline_at` | `string \| null` | yes | | | `state` | `"ok" \| "warning" \| "throttled" \| "paused"` | yes | | | `streams` | `object` | yes | | | `streams.marketing` | `object` | yes | | | `streams.transactional` | `object` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-trust-standing — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-trust-thresholds # GET /trust/thresholds The published enforcement thresholds and the ladder they drive. Same constants the ladder acts on, so nothing that draws a line has to hard-code one. ## Request ```bash curl -sS -X GET https://api.agentisend.com/trust/thresholds \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "ladder": [], "metrics": { "bounce": { "pause": 1, "throttle": 1, "warn": 1 }, "complaint": { "pause": 1, "throttle": 1, "warn": 1 } }, "min_sample": -9007199254740991, "throttled_sends_per_minute": -9007199254740991, "window_days": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/trust/thresholds', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/trust/thresholds' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: trust. Generated from `openapi.json`; the anchor `get-trust-thresholds` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `ladder` | `array<"ok" \| "warning" \| "throttled" \| "paused">` | yes | | | `metrics` | `object` | yes | | | `metrics.bounce` | `object` | yes | | | `metrics.complaint` | `object` | yes | | | `min_sample` | `integer` | yes | | | `throttled_sends_per_minute` | `integer` | yes | | | `window_days` | `integer` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. --- Source: https://agentisend.com/docs/api/get-trust-thresholds — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-usage # GET /usage This period usage, per key: budget, consumed, remaining, rate window, last used. The bill, made legible. ## Request ```bash curl -sS -X GET https://api.agentisend.com/usage \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "account": { "bounced_30d": -9007199254740991, "complained_30d": -9007199254740991, "sent_24h": -9007199254740991, "sent_30d": -9007199254740991 }, "keys": [], "period_started_at": "2026-09-04T09:14:00.000Z" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/usage', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/usage' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: usage. Generated from `openapi.json`; the anchor `get-usage` is the id the console's error `fix` links point at. ## Parameters This operation takes no parameters. ## Responses - `200` — Success - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `account` | `object` | yes | | | `account.bounced_30d` | `integer` | yes | | | `account.complained_30d` | `integer` | yes | | | `account.sent_24h` | `integer` | yes | | | `account.sent_30d` | `integer` | yes | | | `keys` | `array` | yes | | | `keys[].budget_per_period` | `integer \| null` | yes | | | `keys[].consumed_in_period` | `integer` | yes | | | `keys[].consumed_in_window` | `integer` | yes | | | `keys[].id` | `string` | yes | | | `keys[].last_used_at` | `string \| null` | yes | | | `keys[].name` | `string` | yes | | | `keys[].paused` | `boolean` | yes | | | `keys[].period` | `"hourly" \| "daily" \| "monthly"` | yes | | | `keys[].period_started_at` | `string` | yes | | | `keys[].rate_ceiling_per_minute` | `integer \| null` | yes | | | `keys[].remaining` | `integer \| null` | yes | | | `keys[].resets_at` | `string` | yes | | | `keys[].used_percent` | `number \| null` | yes | | | `period_started_at` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. --- Source: https://agentisend.com/docs/api/get-usage — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-webhooks # GET /webhooks List endpoints. Secrets are never returned after creation. ## Request ```bash curl -sS -X GET https://api.agentisend.com/webhooks \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/webhooks', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `get-webhooks` is the id the console's error `fix` links point at. ## Parameters - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional - `before` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].created_at` | `string` | yes | | | `data[].disabled` | `boolean` | yes | | | `data[].events` | `array` | yes | | | `data[].id` | `string` | yes | | | `data[].last_delivery_status` | `"pending" \| "retrying" \| "delivered" \| "dead_lettered" \| null` | yes | | | `data[].payload_format` | `"native" \| "resend"` | yes | | | `data[].svix_compat` | `boolean` | yes | | | `data[].updated_at` | `string` | yes | | | `data[].url` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`invalid_parameter`](https://agentisend.com/docs/errors#invalid_parameter) (422) — A parameter has an invalid value. **Fix:** Correct the named parameter and retry. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-webhooks — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-webhooks # POST /webhooks Register an endpoint. The signing secret is returned exactly once. ## Request ```bash curl -sS -X POST https://api.agentisend.com/webhooks \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"url":"https://yourapp.com/hooks/agentisend","events":["email.delivered","email.bounced"]}' ``` ```json Response 201 { "created_at": "2026-09-04T09:14:00.000Z", "disabled": false, "events": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_delivery_status": "pending", "object": "webhook", "payload_format": "native", "secret": "example", "signing_secret": "example", "svix_compat": false, "updated_at": "2026-09-04T09:14:00.000Z", "url": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/webhooks', body: { "url": "https://yourapp.com/hooks/agentisend", "events": [ "email.delivered", "email.bounced" ] }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"url":"https://yourapp.com/hooks/agentisend","events":["email.delivered","email.bounced"]}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `post-webhooks` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `endpoint` | `string` | no | Same as url. url wins if both are sent. | | `events` | `array` | no | Event types to deliver. * subscribes to every type, including ones added later. | | `payload_format` | `"native" \| "resend"` | no | native is this API’s envelope. resend is the envelope a Resend receiver already parses. | | `svix_compat` | `boolean` | no | Also sign each delivery the way a Svix receiver already verifies. Off unless set. | | `url` | `string` | no | https URL that receives the events. | ## Responses - `201` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `422` — A field is well formed but was refused. Codes: missing_required_field, invalid_from_address, invalid_parameter, invalid_attachment, invalid_region, tracking_subdomain_unverified, tracking_subdomain_cannot_be_removed, domain_field_immutable, open_tracking_on_transactional, header_replaced, html_clipped_by_gmail, domain_blocklisted, mailbox_provider_domain, onboarding_shape_refused, dkim_key_mismatch, domain_check_window_expired, spf_conflict, spf_lookup_limit, review_sandbox_recipient_only, suppressed_recipient, content_refused, recipient_blocklisted, last_owner_required, seat_limit_reached, invite_not_valid, key_budget_exceeds_plan, domain_limit_reached, webhook_endpoint_limit_reached. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 201 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `disabled` | `boolean` | yes | | | `events` | `array` | yes | | | `id` | `string` | yes | | | `last_delivery_status` | `"pending" \| "retrying" \| "delivered" \| "dead_lettered" \| null` | yes | | | `object` | `string` | yes | | | `payload_format` | `"native" \| "resend"` | yes | | | `secret` | `string` | yes | Signing secret, shown once. Store it. Later calls do not return it. | | `signing_secret` | `string` | yes | Same value as secret. The name a receiver already reads. | | `svix_compat` | `boolean` | yes | | | `updated_at` | `string` | yes | | | `url` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. - [`webhook_endpoint_limit_reached`](https://agentisend.com/docs/errors#webhook_endpoint_limit_reached) (422) — This account already has 20 webhook endpoints, the most one account can hold. **Fix:** Delete an endpoint you no longer use with DELETE /webhooks/:id, or send more event types to one you keep — an endpoint takes a list of events. --- Source: https://agentisend.com/docs/api/post-webhooks — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-webhooks-stripe # POST /webhooks/stripe Stripe → AgentiSend: signature-verified, deduplicated by event id. ## Request ```bash curl -sS -X POST https://api.agentisend.com/webhooks/stripe \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "event_id": "example", "event_type": "example", "received": true, "status": "applied" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/webhooks/stripe', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/stripe' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: billing. Generated from `openapi.json`; the anchor `post-webhooks-stripe` is the id the console's error `fix` links point at. ## Parameters - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. - `503` — A dependency is unavailable for a moment. Codes: dns_unreachable, service_unavailable, billing_not_configured, rate_limiter_unavailable, sending_paused_everywhere. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `event_id` | `string` | yes | | | `event_type` | `string` | yes | | | `received` | `boolean` | yes | | | `status` | `"applied" \| "ignored" \| "duplicate"` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`billing_not_configured`](https://agentisend.com/docs/errors#billing_not_configured) (503) — Purchases are unavailable right now. **Fix:** GET /billing/plan still works, and the account stays on Free. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`service_unavailable`](https://agentisend.com/docs/errors#service_unavailable) (503) — The API is temporarily unavailable — a dependency failed transiently. **Fix:** Retry after the seconds given in Retry-After. If it persists beyond a few minutes, check the public status page (GET /status) for the affected component. - [`stripe_signature_invalid`](https://agentisend.com/docs/errors#stripe_signature_invalid) (400) — The signature on this webhook did not verify. **Fix:** Only the billing service calls POST /webhooks/stripe. Use the signing secret for this endpoint in this mode, and deliver the body unmodified. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-webhooks-stripe — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-webhooks-id # GET /webhooks/{id} Fetch one endpoint. ## Request ```bash curl -sS -X GET https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "disabled": false, "events": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_delivery_status": "pending", "payload_format": "native", "svix_compat": false, "updated_at": "2026-09-04T09:14:00.000Z", "url": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `get-webhooks-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `disabled` | `boolean` | yes | | | `events` | `array` | yes | | | `id` | `string` | yes | | | `last_delivery_status` | `"pending" \| "retrying" \| "delivered" \| "dead_lettered" \| null` | yes | | | `payload_format` | `"native" \| "resend"` | yes | | | `svix_compat` | `boolean` | yes | | | `updated_at` | `string` | yes | | | `url` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-webhooks-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/patch-webhooks-id # PATCH /webhooks/{id} Update url, subscribed events, or the disabled flag. ## Request ```bash curl -sS -X PATCH https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"disabled":false}' ``` ```json Response 200 { "created_at": "2026-09-04T09:14:00.000Z", "disabled": false, "events": [], "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "last_delivery_status": "pending", "payload_format": "native", "svix_compat": false, "updated_at": "2026-09-04T09:14:00.000Z", "url": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'PATCH', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', body: { "disabled": false }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} payload = json.dumps({"disabled":false}).encode() headers['Content-Type'] = 'application/json' request = urllib.request.Request(url, data=payload, headers=headers, method='PATCH') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `patch-webhooks-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Request body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `disabled` | `boolean` | no | true stops delivery without deleting the endpoint. | | `endpoint` | `string` | no | Same as url. url wins if both are sent. | | `events` | `array` | no | Replace the event list. * subscribes to every type. | | `payload_format` | `"native" \| "resend"` | no | native is this API’s envelope. resend is the envelope a Resend receiver already parses. | | `svix_compat` | `boolean` | no | Also sign each delivery the way a Svix receiver already verifies. Off unless set. | | `url` | `string` | no | A new https URL. The previous URL stops receiving events. | ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `created_at` | `string` | yes | | | `disabled` | `boolean` | yes | | | `events` | `array` | yes | | | `id` | `string` | yes | | | `last_delivery_status` | `"pending" \| "retrying" \| "delivered" \| "dead_lettered" \| null` | yes | | | `payload_format` | `"native" \| "resend"` | yes | | | `svix_compat` | `boolean` | yes | | | `updated_at` | `string` | yes | | | `url` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/patch-webhooks-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/delete-webhooks-id # DELETE /webhooks/{id} Delete an endpoint and its queued deliveries. ## Request ```bash curl -sS -X DELETE https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "deleted": false, "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'DELETE', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='DELETE') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `delete-webhooks-id` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `deleted` | `boolean` | yes | | | `id` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/delete-webhooks-id — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-webhooks-id-dead-letters # GET /webhooks/{id}/dead-letters Deliveries this endpoint exhausted every retry on, with the payload to inspect. ## Request ```bash curl -sS -X GET https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/dead-letters \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/dead-letters', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/dead-letters' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `get-webhooks-id-dead-letters` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].attempts` | `integer` | yes | | | `data[].created_at` | `string` | yes | | | `data[].delivery_id` | `string \| null` | yes | | | `data[].event_id` | `string` | yes | | | `data[].event_type` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].last_response_body` | `string \| null` | yes | | | `data[].last_status_code` | `integer \| null` | yes | | | `data[].occurred_at` | `string` | yes | | | `data[].payload` | `object` | yes | | | `data[].reason` | `string` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-webhooks-id-dead-letters — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/get-webhooks-id-deliveries # GET /webhooks/{id}/deliveries Every delivery to this endpoint, with each attempt and what the receiver answered. ## Request ```bash curl -sS -X GET https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/deliveries \ -H "Authorization: Bearer $AGENTISEND_API_KEY" ``` ```json Response 200 { "data": [], "has_more": false, "next_cursor": "example", "object": "list" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'GET', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/deliveries', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/deliveries' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='GET') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `get-webhooks-id-deliveries` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `id` query · `string` · optional - `event_type` query · `"email.queued" | "email.sent" | "email.delivered" | "email.delivery_delayed" | "email.bounced" | "email.complained" | "email.opened" | "email.clicked" | "email.failed" | "email.scheduled" | "email.canceled" | "email.suppressed" | "domain.created" | "domain.verified" | "domain.failed" | "domain.updated" | …` · optional - `status` query · `"pending" | "retrying" | "delivered" | "dead_lettered"` · optional - `since` query · `string` · optional - `until` query · `string` · optional - `limit` query · `integer` · optional - `cursor` query · `string` · optional - `after` query · `string` · optional ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `data` | `array` | yes | | | `data[].attempts` | `array` | yes | | | `data[].event_id` | `string` | yes | | | `data[].event_type` | `string` | yes | | | `data[].id` | `string` | yes | | | `data[].occurred_at` | `string` | yes | | | `data[].payload` | `object` | yes | | | `data[].status` | `"pending" \| "retrying" \| "delivered" \| "dead_lettered"` | yes | | | `has_more` | `boolean` | yes | | | `next_cursor` | `string \| null` | yes | | | `object` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_cursor`](https://agentisend.com/docs/errors#invalid_cursor) (400) — This page cursor is no longer valid. **Fix:** Call the list again without a cursor, or pass the next_cursor from a page you still have. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/get-webhooks-id-deliveries — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-webhooks-id-replay # POST /webhooks/{id}/replay Re-send past events to this endpoint, by time range and/or a single event id. ## Request ```bash curl -sS -X POST https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/replay?since=2026-09-04T09:14:00Z&dry_run=true \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "count": -9007199254740991 } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/replay', query: { since: '2026-09-04T09:14:00Z' dry_run: 'true' }, }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/replay?since=2026-09-04T09:14:00Z&dry_run=true' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `post-webhooks-id-replay` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `since` query · `string` · optional - `until` query · `string` · optional - `event_type` query · `"email.queued" | "email.sent" | "email.delivered" | "email.delivery_delayed" | "email.bounced" | "email.complained" | "email.opened" | "email.clicked" | "email.failed" | "email.scheduled" | "email.canceled" | "email.suppressed" | "domain.created" | "domain.verified" | "domain.failed" | "domain.updated" | …` · optional - `event_id` query · `string` · optional - `dry_run` query · `string | string | boolean` · optional - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-webhooks-id-replay — the HTML at that URL and this file are one document, generated from one source. # https://agentisend.com/docs/api/post-webhooks-id-rotate-secret # POST /webhooks/{id}/rotate-secret Mint a new signing secret. Returned once. The previous secret keeps verifying for 24 hours, and deliveries in that window are signed with both. ## Request ```bash curl -sS -X POST https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate-secret \ -H "Authorization: Bearer $AGENTISEND_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ```json Response 200 { "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42", "object": "webhook", "previous_secret_expires_at": "2026-09-04T09:14:00.000Z", "rotated_at": "2026-09-04T09:14:00.000Z", "secret": "example", "signing_secret": "example" } ``` ```js import { AgentiSend } from 'agentisend'; const client = new AgentiSend(process.env.AGENTISEND_API_KEY); const result = await client.request({ method: 'POST', path: '/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate-secret', }); ``` ```python import json, os, urllib.request url = 'https://api.agentisend.com/webhooks/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate-secret' headers = {'Authorization': 'Bearer ' + os.environ['AGENTISEND_API_KEY']} request = urllib.request.Request(url, headers=headers, method='POST') print(urllib.request.urlopen(request).read().decode()) ``` Tag: webhooks. Generated from `openapi.json`; the anchor `post-webhooks-id-rotate-secret` is the id the console's error `fix` links point at. ## Parameters - `id` path · `string` · required - `Idempotency-Key` header · `string` · optional — Makes this call safe to retry. Send the same key with the same body and the original response is replayed instead of the work happening twice. Keys are 1-256 characters and are remembered for 7 days. While the first attempt is still running, a second call with that key returns 409 idempotency_in_flight (Resend calls this concurrent_idempotent_requests); the same key with a different body returns 409 idempotency_payload_mismatch (Resend: invalid_idempotent_request). Resend-Idempotency-Key is accepted as the same header. - `Resend-Idempotency-Key` header · `string` · optional — Alias of Idempotency-Key. Idempotency-Key wins if both are sent. ## Responses - `200` — Success - `400` — The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required. - `401` — No usable credential was sent. Codes: missing_api_key, session_required, mfa_required. - `403` — The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, trust_paused, kill_switch_active. - `404` — Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found. - `409` — The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_in_use, segment_in_use, contact_resubscribe_required, domain_verified_elsewhere, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict. - `413` — The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large. - `415` — The request body is not JSON. Codes: unsupported_media_type. - `429` — A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited. - `500` — Something failed on our side. Codes: internal_server_error. ### Response headers - `ratelimit-limit` — Messages this API key may spend in one 60-second window. - `ratelimit-remaining` — Messages left in the current window. - `ratelimit-reset` — Seconds until the current window resets and the budget refills. ## 200 body | Field | Type | Required | Notes | | --- | --- | --- | --- | | `id` | `string` | yes | | | `object` | `string` | yes | | | `previous_secret_expires_at` | `string` | yes | | | `rotated_at` | `string` | yes | | | `secret` | `string` | yes | | | `signing_secret` | `string` | yes | | ## Errors The codes this operation can answer with, and what to do about each. Every one arrives with its code, message, fix and docs_url. - [`csrf_origin_rejected`](https://agentisend.com/docs/errors#csrf_origin_rejected) (403) — This request came from a page on another site, and it changes data. **Fix:** Call the API with an API key (Authorization: Bearer …) instead of a session cookie, or make the request from the console. Create a key in the console under Settings, API keys. - [`idempotency_in_flight`](https://agentisend.com/docs/errors#idempotency_in_flight) (409) — A request with this Idempotency-Key is still in progress. **Fix:** Wait and retry with the same Idempotency-Key to receive the original response. - [`idempotency_payload_mismatch`](https://agentisend.com/docs/errors#idempotency_payload_mismatch) (409) — Same Idempotency-Key was used with a different payload. **Fix:** Reuse the exact same body for retries, or send a new Idempotency-Key for a new request. - [`insufficient_role`](https://agentisend.com/docs/errors#insufficient_role) (403) — Your role on this account cannot make this change. **Fix:** Ask an owner to make the change, or to raise your role with PATCH /team/members/:id. - [`internal_server_error`](https://agentisend.com/docs/errors#internal_server_error) (500, internal_server_error) — Unexpected error. **Fix:** Retry ONCE after a short pause, with the same Idempotency-Key so the retry cannot double-send. If it fails again, stop retrying and report the x-request-id from the response — that id is what identifies this exact failure in support. - [`invalid_api_key`](https://agentisend.com/docs/errors#invalid_api_key) (403, invalid_api_key) — API key is invalid or revoked. **Fix:** Create a new key with POST /api-keys; deleted keys cannot be restored. - [`invalid_idempotency_key`](https://agentisend.com/docs/errors#invalid_idempotency_key) (400) — Idempotency-Key must be 1-256 characters. **Fix:** Send a non-empty Idempotency-Key header of at most 256 characters. - [`mfa_required`](https://agentisend.com/docs/errors#mfa_required) (401) — This session has not completed two-factor authentication. **Fix:** Finish signing in at https://console.agentisend.com/verify with a code from your authenticator app, or one of your recovery codes. Manage the second factor in the console under Settings, Security. - [`missing_api_key`](https://agentisend.com/docs/errors#missing_api_key) (401, missing_api_key) — Missing API key in authorization header. **Fix:** Create an API key at https://console.agentisend.com/api-keys and send "Authorization: Bearer as_...". MCP clients can connect with OAuth instead of a key. - [`not_found`](https://agentisend.com/docs/errors#not_found) (404, not_found) — Endpoint or resource does not exist. **Fix:** List that resource on this account and use an id from the list. For a domain, GET /domains accepts the id or the domain name. A path that is not a route is a typo in the URL. - [`payload_too_large`](https://agentisend.com/docs/errors#payload_too_large) (413) — Request body is larger than this endpoint accepts. **Fix:** Send a smaller body. Most endpoints accept 1 MB. Sends (POST /emails, /emails/batch, replies) and template, broadcast and automation edits accept 50 MB, which fits 40 MB of attachments after base64. /mcp accepts 1 MB per JSON-RPC call. - [`rate_limit_exceeded`](https://agentisend.com/docs/errors#rate_limit_exceeded) (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. **Fix:** Back off and retry honoring the Retry-After header. - [`restricted_api_key`](https://agentisend.com/docs/errors#restricted_api_key) (403, restricted_api_key) — This API key is restricted to sending only. **Fix:** Use a full_access key (POST /api-keys with permission=full_access) for management endpoints. - [`unsupported_media_type`](https://agentisend.com/docs/errors#unsupported_media_type) (415) — This endpoint does not accept that content type. **Fix:** Send the body as JSON with `Content-Type: application/json`. - [`validation_error`](https://agentisend.com/docs/errors#validation_error) (400, domain_not_verified, invalid_parameter, validation_error) — Error in one or more fields. **Fix:** Correct the fields listed in the error details and retry the request. --- Source: https://agentisend.com/docs/api/post-webhooks-id-rotate-secret — the HTML at that URL and this file are one document, generated from one source.