> ## Documentation Index
> Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Email content and sending limits

> Send HTML email, understand new-Organization recipient limits, and retry safely.

Connect a domain with [Build an email agent](https://docs.photon.codes/docs/beta/get-started/email.md), then
use [Send a Message](https://docs.photon.codes/docs/beta/api-client/sdk/projects/send-message.md) for outgoing
email and replies.

## HTML content

Email accepts a `text` content object with `format: "plain"` or `format: "html"`.
Put the body in `text`; HTML does not require a separate content type or an
`html` field. The format describes that content object's body, not the HTTP
request's `Content-Type`, which remains `application/json`.

For example, the body of a send request can be:

```json theme={null}
{
  "spaceId": "YOUR_EMAIL_SPACE_ID",
  "senderId": "YOUR_EMAIL_SENDER_ID",
  "content": {
    "type": "text",
    "format": "html",
    "text": "<p>Hello <strong>Sam</strong>,</p><p>Your order is ready.</p>"
  }
}
```

Replace the IDs with the existing Email Space and its sending User in your
project. For a reply, also include the persisted parent Message's ID as
`parentMessageId`, as explained in the
[email quickstart](https://docs.photon.codes/docs/beta/get-started/email.md#how-the-reply-stays-in-the-conversation).
Supply a stable `Idempotency-Key` header for each logical send.

To provide both plain-text and HTML alternatives for the same email, use:

```json theme={null}
{
  "type": "group",
  "parts": [
    {
      "type": "text",
      "format": "plain",
      "text": "Hello Sam, your order is ready."
    },
    {
      "type": "text",
      "format": "html",
      "text": "<p>Hello <strong>Sam</strong>, your order is ready.</p>"
    }
  ]
}
```

Use that object as the request's `content`. These are two alternatives of one
body, not two messages. Keep their meaning consistent. Markdown is not a native
Email body format; convert it to plain text or HTML before sending. Other
channels have their own supported formats. An extensible shared text format
does not imply every channel supports HTML or message editing.

Email clients may sanitize HTML and render it differently. Do not depend on
scripts or interactive web-page behavior. HTML body support does not mean
arbitrary browser HTML will display unchanged.

## New-Organization recipient limits

New Organizations have these default outgoing Email allowances:

| Rolling window | Default allowance |
| - | - |
| Previous minute | 50 recipients |
| Previous 24 hours | 500 recipients |

The allowances are shared across the Organization's Projects. Count recipients,
not HTTP requests: one accepted email to five recipients uses five units of
these allowances. The windows roll with time; they do not reset at midnight.
An idempotent retry of an already accepted send does not reserve the recipients
again.

These are onboarding safeguards, separate from your plan's included billable
usage. Buying usage is not itself approval to remove the onboarding limits.
An Organization approved through sending review is exempt from these
new-Organization allowances. API request-rate limits, sending throughput,
backlog protection and other sending restrictions still apply. An approved
Organization does not have unlimited sending capacity.

## When a request returns 429

Email can return `429 RATE_LIMITED` for request rate, new-Organization recipient
allowances or a full sending backlog. The public code alone does not identify
which allowance was reached.

1. Wait **at least** the response's `Retry-After` value. If requests keep
   returning 429, increase the delay with bounded exponential backoff and
   jitter while continuing to respect that minimum. Do not retry in a tight
   loop. A short `Retry-After` is not a promise that a recipient allowance
   will be available when that time has passed.
2. Retry the same logical send with the **same `Idempotency-Key` and unchanged
   body**. Keep the key after a timeout or uncertain result too.
3. If the recipient window is still full, a retry can return 429 again. Spread
   the work over time; changing keys or creating another Project does not
   increase an Organization's allowance.
4. For persistent limits or legitimate higher-volume use, contact
   [Photon support](mailto:support@photon.codes). Include your Organization and
   Project IDs, expected recipient volume, sending purpose and any request ID.
   Do not send API keys or tokens. Review approval is separate from an automatic
   retry and does not guarantee a particular throughput.

See [Retries and timeouts](https://docs.photon.codes/docs/beta/api-client/retries-and-timeouts.md) for each
client's retry behavior and limits. A successful acceptance response does not
mean the email has already been delivered; track its asynchronous outcome.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.