---
title: "Sending"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://openemail.uk/docs/api/reference/sending"
area: "API"
category: "Reference"
---

# Sending

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

How mail leaves the workspace. It travels in two lanes, so a newsletter cannot hold up or harm app mail: `transactional` for password resets, receipts and codes, and `broadcast` for newsletters. Each lane has its own queue and its own reputation numbers. The broadcast lane pauses itself when too many of its messages bounce or are reported as spam, and app mail keeps going out. A workspace with the dedicated IP add-on also sends from its own IP address.

### `GET /sending/streams`

List the sending lanes

Both lanes with their state and their numbers for the last 7 days: recipients, bounces and complaints, the rates, and the limits the broadcast lane is held to. A paused lane says when and why. The count starts again when a lane is resumed.

Requires the `emails:read` scope.

- Scopes: `emails:read`.

**Returns**

- `200` `SendingStreamList`: The two lanes.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`sending.listStreams()`](https://openemail.uk/docs/sdk/reference/sending#listStreams); Python [`sending.list_streams()`](https://openemail.uk/docs/python/reference/sending#listStreams); Ruby [`sending.list_streams`](https://openemail.uk/docs/ruby/reference/sending#listStreams); PHP [`sending->listStreams`](https://openemail.uk/docs/php/reference/sending#listStreams); Go [`Sending.ListStreams`](https://openemail.uk/docs/go/reference/sending#listStreams); Java [`sending().listStreams`](https://openemail.uk/docs/java/reference/sending#listStreams); C# [`Sending.ListStreamsAsync`](https://openemail.uk/docs/csharp/reference/sending#listStreams); CLI [`openemail sending list-streams`](https://openemail.uk/docs/cli/reference/sending#sending-list-streams); MCP [`getSendingStreams`](https://openemail.uk/docs/mcp/tools/analytics#getSendingStreams).

### `POST /sending/streams/{stream}/resume`

Resume a paused lane

Resumes the broadcast lane after it was paused for too many bounces or complaints. Broadcasts and messages that were on hold continue at once, and the 7 day count starts again from now, so clean the audience first. Only the workspace owner may do it, and an app acting for a person is asked for a verification code.

Requires the `domains:write` scope.

- Scopes: `domains:write`.
- Asks an OAuth access token for a verification code.

**Path parameters**

- `stream` (`string`, required, one of `"transactional"`, `"broadcast"`): The lane, `transactional` or `broadcast`.

**Returns**

- `200` `SendingStream`: The lane, active again.

**Errors**

- `403`: The key lacks the scope, or may not send as that address. `step_up_required`: the call was made with an OAuth access token that has not been verified in the last 60 minutes. Ask for a code with `POST /security/step-up`, send it to `POST /security/step-up/verify`, then repeat the call. The person can also choose Allow changes for 60 minutes on the app in Account settings, Connected apps, on the OpenEmail website. An API key is never asked for a code.
- `409`: `stream_not_paused`: the lane is not paused, so there is nothing to resume.
- The errors every operation can return: `400`, `401`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`sending.resumeStream()`](https://openemail.uk/docs/sdk/reference/sending#resumeStream); Python [`sending.resume_stream()`](https://openemail.uk/docs/python/reference/sending#resumeStream); Ruby [`sending.resume_stream`](https://openemail.uk/docs/ruby/reference/sending#resumeStream); PHP [`sending->resumeStream`](https://openemail.uk/docs/php/reference/sending#resumeStream); Go [`Sending.ResumeStream`](https://openemail.uk/docs/go/reference/sending#resumeStream); Java [`sending().resumeStream`](https://openemail.uk/docs/java/reference/sending#resumeStream); C# [`Sending.ResumeStreamAsync`](https://openemail.uk/docs/csharp/reference/sending#resumeStream); CLI [`openemail sending resume-stream`](https://openemail.uk/docs/cli/reference/sending#sending-resume-stream); MCP [`resumeSendingStream`](https://openemail.uk/docs/mcp/tools/analytics#resumeSendingStream).

### `GET /sending/dedicated-ips`

List dedicated IPs

The dedicated sending IPs of the workspace, bought as an add-on with `POST /billing/add-ons/checkout`. A new IP is warmed up over several weeks: `warmupPercent` says how far it is, and until it reaches 100 part of the mail still leaves through the shared IPs. A workspace without the add-on gets an empty list and sends through the shared IPs.

Requires the `domains:read` scope.

- Scopes: `domains:read`.

**Returns**

- `200` `DedicatedIpList`: The dedicated IPs.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`sending.listDedicatedIps()`](https://openemail.uk/docs/sdk/reference/sending#listDedicatedIps); Python [`sending.list_dedicated_ips()`](https://openemail.uk/docs/python/reference/sending#listDedicatedIps); Ruby [`sending.list_dedicated_ips`](https://openemail.uk/docs/ruby/reference/sending#listDedicatedIps); PHP [`sending->listDedicatedIps`](https://openemail.uk/docs/php/reference/sending#listDedicatedIps); Go [`Sending.ListDedicatedIPs`](https://openemail.uk/docs/go/reference/sending#listDedicatedIps); Java [`sending().listDedicatedIps`](https://openemail.uk/docs/java/reference/sending#listDedicatedIps); C# [`Sending.ListDedicatedIpsAsync`](https://openemail.uk/docs/csharp/reference/sending#listDedicatedIps); CLI [`openemail sending list-dedicated-ips`](https://openemail.uk/docs/cli/reference/sending#sending-list-dedicated-ips); MCP [`listDedicatedIps`](https://openemail.uk/docs/mcp/tools/analytics#listDedicatedIps).

### `GET /sending/dedicated-ips/{ip}`

Read a dedicated IP

One dedicated IP of the workspace with its status and how far its warm-up has come.

Requires the `domains:read` scope.

- Scopes: `domains:read`.

**Path parameters**

- `ip` (`string`, required): The IP address, as the list returns it.

**Returns**

- `200` `DedicatedIp`: The dedicated IP.

**Errors**

- `404`: `resource_not_found`: the workspace has no dedicated IP with that address.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`sending.getDedicatedIp()`](https://openemail.uk/docs/sdk/reference/sending#getDedicatedIp); Python [`sending.get_dedicated_ip()`](https://openemail.uk/docs/python/reference/sending#getDedicatedIp); Ruby [`sending.get_dedicated_ip`](https://openemail.uk/docs/ruby/reference/sending#getDedicatedIp); PHP [`sending->getDedicatedIp`](https://openemail.uk/docs/php/reference/sending#getDedicatedIp); Go [`Sending.GetDedicatedIP`](https://openemail.uk/docs/go/reference/sending#getDedicatedIp); Java [`sending().getDedicatedIp`](https://openemail.uk/docs/java/reference/sending#getDedicatedIp); C# [`Sending.GetDedicatedIpAsync`](https://openemail.uk/docs/csharp/reference/sending#getDedicatedIp); CLI [`openemail sending get-dedicated-ip`](https://openemail.uk/docs/cli/reference/sending#sending-get-dedicated-ip).

### Objects

#### `DedicatedIp`

`object`

- `object` (`string`, required, one of `"dedicated_ip"`)
- `ip` (`string`, required)
- `status` (`string`, required, one of `"available"`, `"warming"`, `"ready"`, `"released"`): `warming` while the IP is being warmed up, `ready` once all of the workspace's mail leaves through it.
- `pool` (`string`, required, nullable): The pool the IP sends through.
- `poolStatus` (`string`, required, nullable, one of `"pending"`, `"warming"`, `"active"`, `"releasing"`, `"released"`, `"failed"`)
- `warmupPercent` (`integer`, required, at least 0, at most 100)
- `assignedAt` (`string`, required, nullable, format `date-time`)
- `readyAt` (`string`, required, nullable, format `date-time`)
- `checkedAt` (`string`, required, nullable, format `date-time`): When the warm-up was last read.

#### `DedicatedIpList`

`object`

- `object` (`string`, required, one of `"list"`)
- `data` (`DedicatedIp[]`, required)

#### `SendingStream`

`object`

- `object` (`string`, required, one of `"sending_stream"`)
- `stream` (`string`, required, one of `"transactional"`, `"broadcast"`)
- `status` (`string`, required, one of `"active"`, `"paused"`): `paused` holds every new message on the lane until it is resumed. Only the broadcast lane pauses.
- `pausedAt` (`string`, required, nullable, format `date-time`)
- `pausedReason` (`string`, required, nullable, one of `"bounce_rate"`, `"complaint_rate"`): Which limit was passed, or null on an active lane.
- `resumedAt` (`string`, required, nullable, format `date-time`): When the lane was last resumed. The count in `window` starts no earlier than this.
- `window` (`object`, required)
  - `since` (`string`, required, format `date-time`)
  - `until` (`string`, required, format `date-time`)
  - `recipients` (`integer`, required): Recipients the lane handed over for delivery in the window.
  - `bounced` (`integer`, required)
  - `complained` (`integer`, required): Recipients who reported the mail as spam.
  - `bounceRate` (`number`, required): Bounced over recipients, from 0 to 1.
  - `complaintRate` (`number`, required): Complained over recipients, from 0 to 1.
- `limits` (`object`, required)
  - `bounceRate` (`number`, required): The broadcast lane pauses above this bounce rate.
  - `complaintRate` (`number`, required): The broadcast lane pauses above this complaint rate.
  - `minimumRecipients` (`integer`, required): The rates are only judged once the lane reached this many recipients in the window.
  - `windowDays` (`integer`, required)

#### `SendingStreamList`

`object`

- `object` (`string`, required, one of `"list"`)
- `data` (`SendingStream[]`, required)
