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

# Resend

The io.b3os/resend pack: 3 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.

`io.b3os/resend` 1.0.0 · `email`, `messaging`, `notifications` · MIT

Send transactional email through Resend with your own Resend API key and a domain you verified in Resend: plain text or HTML, cc, bcc and reply-to, idempotent retries with an idempotency key. Also check an email's delivery status and list your sending domains.

Every call's result carries `upstream_status` and `timing`: `validate_ms`, `inject_ms`, `render_ms`, `upstream_ms`, `map_ms` and `total_ms`. `upstream` is the service's time; the others are B3OS's own ([call actions](/actions/call)). The snippets below show no timing values, because a fixture records none.

## Connection

`resend`, type `bearer`: Resend API key.

A Resend API key (re_...) with sending access, from resend.com/api-keys.

How to get one: [resend.com](https://resend.com/docs/api-reference/introduction).

The credential is sent only to `api.resend.com`.

Store the credential once as a [vault connection](/vault) for this pack and key, then name its id in a call's `connections`. Leave the key out and B3OS uses the project's newest connection for the pack and key without a `subject` ([connections](/actions/call#connections)).

Hosts it reaches: `api.resend.com`.

## Actions

| Action | Effect | MCP tool | Title |
|---|---|---|---|
| [`send-email`](/actions/catalog/resend#resend-send-email) | irreversible | `resend__send-email` | Send email |
| [`get-email`](/actions/catalog/resend#resend-get-email) | read | `resend__get-email` | Get email status |
| [`list-domains`](/actions/catalog/resend#resend-list-domains) | read | `resend__list-domains` | List sending domains |

send-email

**Send email.** Send one email from an address on a domain verified in your Resend account, as HTML, plain text or both. to, cc and bcc take one address or an array. Pass an idempotency key so a retry does not send twice. Returns the Resend email ID.

Ref `io.b3os/resend/send-email@1.0.0` · effect `irreversible` · connection `resend` · MCP tool `resend__send-email`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/resend/send-email@1",
          "input": {
            "from": "Acme Billing <billing@acme.example>",
            "to": ["ada@example.com"],
            "subject": "Your October invoice",
            "text": "Hi Ada, your invoice for October is attached in the portal.",
            "replyTo": "support@acme.example"
          },
          "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/resend/send-email@1",
      input: {
        from: "Acme Billing <billing@acme.example>",
        to: ["ada@example.com"],
        subject: "Your October invoice",
        text: "Hi Ada, your invoice for October is attached in the portal.",
        replyTo: "support@acme.example",
      },
      connections: { resend: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/resend/send-email@1",
        "input": {
            "from": "Acme Billing <billing@acme.example>",
            "to": ["ada@example.com"],
            "subject": "Your October invoice",
            "text": "Hi Ada, your invoice for October is attached in the portal.",
            "replyTo": "support@acme.example",
        },
        "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "resend__send-email",
        "arguments": {
          "from": "Acme Billing <billing@acme.example>",
          "to": ["ada@example.com"],
          "subject": "Your October invoice",
          "text": "Hi Ada, your invoice for October is attached in the portal.",
          "replyTo": "support@acme.example"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs resend` on the local server or `?packs=resend` on the remote URL, and the agent calls `resend__send-email` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Send email (documented response shape, example values). From the bundle's `fixtures/send-email.json`, not a live call.

```json
{"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794", "status": "success"}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 401 | no | Resend rejected the API key; check the connection. |
| `forbidden` | 403 | no | built from the service's response |
| `not_found` | 404 | no | built from the service's response |
| `rate_limited` | 429 | yes | built from the service's response |
| `invalid_request` | 400, 422 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

get-email

**Get email status.** One sent email by Resend ID: sender, recipients, subject, creation time and its last delivery event (sent, delivered, delivery_delayed, bounced, complained, opened, clicked, ...).

Ref `io.b3os/resend/get-email@1.0.0` · effect `read` · connection `resend` · MCP tool `resend__get-email`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/resend/get-email@1",
          "input": {"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"},
          "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/resend/get-email@1",
      input: { id: "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794" },
      connections: { resend: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/resend/get-email@1",
        "input": {"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"},
        "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "resend__get-email",
        "arguments": {"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"}
      }
    }
    ```

    Expose the pack as tools with `--packs resend` on the local server or `?packs=resend` on the remote URL, and the agent calls `resend__get-email` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get email status (documented response shape, example values). From the bundle's `fixtures/get-email.json`, not a live call.

```json
{
  "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794",
  "from": "Acme Billing <billing@acme.example>",
  "to": ["ada@example.com"],
  "subject": "Your October invoice",
  "created_at": "2026-10-26 09:12:44.123456+00",
  "last_event": "delivered"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 401 | no | Resend rejected the API key; check the connection. |
| `forbidden` | 403 | no | built from the service's response |
| `not_found` | 404 | no | built from the service's response |
| `rate_limited` | 429 | yes | built from the service's response |
| `invalid_request` | 400, 422 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

list-domains

**List sending domains.** Domains in the Resend account with their verification status (verified, pending, failed, ...) and region. send-email only works from verified domains.

Ref `io.b3os/resend/list-domains@1.0.0` · effect `read` · connection `resend` · MCP tool `resend__list-domains`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/resend/list-domains@1",
          "input": {},
          "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/resend/list-domains@1",
      input: {},
      connections: { resend: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/resend/list-domains@1",
        "input": {},
        "connections": {"resend": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "resend__list-domains", "arguments": {}}
    }
    ```

    Expose the pack as tools with `--packs resend` on the local server or `?packs=resend` on the remote URL, and the agent calls `resend__list-domains` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List sending domains (documented response shape, example values). From the bundle's `fixtures/list-domains.json`, not a live call.

```json
{
  "domains": [
    {
      "id": "d91cd9bd-1176-453e-8fc1-35364d380206",
      "name": "acme.example",
      "status": "verified",
      "region": "us-east-1",
      "created_at": "2026-04-26 20:21:26.347412+00"
    },
    {
      "id": "1c7b4b2a-6a51-4b5e-9a35-1f0f2b5d7c11",
      "name": "mail.acme.example",
      "status": "pending",
      "region": "eu-west-1",
      "created_at": "2026-10-20 10:02:11.000000+00"
    }
  ]
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 401 | no | Resend rejected the API key; check the connection. |
| `forbidden` | 403 | no | built from the service's response |
| `not_found` | 404 | no | built from the service's response |
| `rate_limited` | 429 | yes | built from the service's response |
| `invalid_request` | 400, 422 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |