---
title: "Send an email."
method: POST
path: "/emails"
tags: ["emails"]
---

# Send an email.

`POST /emails`

## Request

- Base URL: `https://api.agentisend.com`
- URL: `https://api.agentisend.com/emails`
- Auth: HTTP bearer

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.

## Headers

- `Idempotency-Key` string
- `Resend-Idempotency-Key` string

## Request body

- PostEmailsBody
  - `from` string: Sender. A verified domain, or the onboarding address while a domain is still pending. Optional only when the template has a default sender; a from here overrides it.
  - `to` union, required: Recipients. One address or a list.
    - string
    - string[]
  - `subject` string: Required unless template or template_id names a published template that has a subject. Overrides the template subject when both exist.
  - `cc` union: Copy recipients.
    - string
    - string[]
  - `bcc` union: Blind copy recipients.
    - string
    - string[]
  - `reply_to` union: Reply-To addresses. Overrides the template default when a template is sent.
    - string
    - string[]
  - `replyTo` union: Same as reply_to. reply_to wins if both are sent.
    - string
    - string[]
  - `html` string: HTML body. Provide html, text, or a template.
  - `text` string: Plain-text body. Provide html, text, or a template.
  - `headers` object: Extra headers. Names that this API sets itself are replaced.
  - `tags` union: Tags as an object of name to value, or a list of {name, value}.
    - object
    - object[]
      - `name` string, required: Tag name. Letters, digits, _ and -, up to 256 characters.
      - `value` string, required: Tag value. Same characters, up to 256 characters.
  - `scheduled_at` string: ISO 8601 or a short phrase ("in 1 hour", "tomorrow 9am"). Max 30 days ahead.
  - `scheduledAt` string: Resend Node SDK name for scheduled_at.
  - `timezone` string: 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.
  - `attachments` object[]: Files to attach. At most 100, and 40 MB of base64 content together.
    - `filename` string: File name shown to the recipient.
    - `content` union: Base64 text, a byte array, or a Buffer. Provide content or path.
      - string
      - object
        - `type` 'Buffer', required: Buffer, when the file is a Node buffer sent as JSON.
        - `data` integer[], required: The file bytes, each from 0 to 255.
      - integer[]
    - `path` string, uri: https URL of a hosted file. Fetched when the send is accepted.
    - `content_type` string: Media type, such as application/pdf. No parameters.
    - `contentType` string: Same as content_type. content_type wins if both are sent.
    - `content_id` string: Referenced from HTML as cid: this value, for an inline image.
    - `contentId` string: Same as content_id. content_id wins if both are sent.
  - `topic_id` string, uuid: Subscription topic. Recipients who opted out of it are not sent this message.
  - `topicId` string, uuid: Resend Node SDK name for topic_id.
  - `template_id` string: Id or alias of the published template to render, instead of html or text.
  - `template_values` object: Values for the template placeholders.
  - `template` object: A published template, instead of html or text.
    - `id` string, required: Published template id or alias.
    - `variables` object: Values for the template placeholders. A string or a number per name.
  - `expires_at` string, date-time: When a held send stops waiting for a person. At most 7 days ahead. Ignored when the send is not held.

## Response `201`

Success

- PostEmailsReply
  - `id` string, uuid, required
  - `simulated` boolean, required
  - `warnings` object[], required
    - `code` string, required
    - `message` string, required
    - `fix` string, required

## Other responses

- `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_sending_disabled, 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, staff_review_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_alias_taken, template_in_use, segment_in_use, contact_resubscribe_required, email_still_scheduled, domain_verified_elsewhere, domain_not_claimable, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, portal_change_unavailable, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict, support_reply_too_soon.
- `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, link_domain_listed, 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, support_draft_unavailable.

---

[API](https://skmtc.dev/agentisend/apis/agentisend-api.md) · [All operations](https://skmtc.dev/agentisend/apis/agentisend-api/llms.txt) · [OpenAPI document](https://skmtc.dev/agentisend/apis/agentisend-api/revisions/3066dda62a56?raw)
