Skip to content
Browse the docs

POST /emails/{id}/share

Make a link anyone can open to read one sent or received email, with no sign-in.

It stops working after expires_in (at most 48 hours; default 48 hours). The page shows the message read-only: no script runs, no image or link in it loads.

Request

The same call in curl, Node and Python. A path id in the sample is a placeholder.

curl

curl -sS -X POST https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/share \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'

Node

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/share',
  body: {},
});

Python

import json, os, urllib.request

url = 'https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/share'
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: emails. Generated from openapi.json; the anchor post-emails-id-share 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

FieldTypeRequiredNotes
expires_instringnoHow long the link stays valid, such as "10m", "2 hours" or "1 day". Default 48h. At most 48 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_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, 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.

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

FieldTypeRequiredNotes
idstringyesThe email the link opens.
objectstringyes
urlstringyesThe link. Anyone who has it can read the email until it expires.

Response example

200
{
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "object": "email",
  "url": "https://yourapp.com/hooks/agentisend"
}

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 (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 (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 (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 (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 (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 (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 (400) — Idempotency-Key must be 1-256 characters. Fix: Send a non-empty Idempotency-Key header of at most 256 characters.
  • invalid_parameter (422) — A parameter has an invalid value. Fix: Correct the named parameter and retry.
  • 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 (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 (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 (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 (429, rate_ceiling_exceeded, rate_limit_exceeded) — Too many requests. Fix: Back off and retry honoring the Retry-After header.
  • 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 (415) — This endpoint does not accept that content type. Fix: Send the body as JSON with `Content-Type: application/json`.
  • 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.