---
title: "client.sending"
description: "Every method in this namespace: its signature, its parameters, what it returns and an example."
url: "https://openemail.uk/docs/ruby/reference/sending"
area: "Ruby"
category: "Reference"
---

# client.sending

Every method in this namespace: its signature, its parameters, what it returns and an example.

## Methods

How mail leaves the workspace: the two lanes it travels in, `transactional` for app mail and `broadcast` for newsletters, each with its bounce and complaint numbers, the switch that resumes a paused lane, and the dedicated IPs of a workspace that bought one.

### `sending.list_streams`

List the sending lanes

```ruby
list_streams(api_key: nil) -> Hash
```

Returns the two lanes mail travels in, `transactional` for app mail such as password resets, receipts and codes, and `broadcast` for newsletters, each with its state and its numbers for the last 7 days: `recipients`, `bounced` and `complained`, the two rates, and the `limits` the broadcast lane is held to. The lanes have their own queues and their own reputation, so a newsletter never holds up or harms app mail.

The broadcast lane pauses itself when more than 4% of its recipients bounced or more than 0.2% reported the mail as spam over those 7 days, once it reached enough recipients to judge. A paused lane says when and why in `pausedAt` and `pausedReason`, and app mail keeps going out. The count starts again when a lane is resumed, which `resumedAt` gives.

Scopes: `emails:read`.

**Parameters**

- `api_key` (`String`): Overrides the client's API key for this call only.

**Returns**

A Hash with one Hash per lane in `data`: `stream`, `status`, `pausedAt`, `pausedReason`, `resumedAt`, `window` and `limits`.

**Example**

```ruby
lanes = client.sending.list_streams

lanes[:data].each do |lane|
  puts "#{lane[:stream]} #{lane[:status]} #{lane[:window][:bounceRate]} #{lane[:window][:complaintRate]}"
end
```

**Notes**

- Only the broadcast lane pauses. The transactional lane is always `active`.
- A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's `max_retries:`, and on a 429 only when it carries a `Retry-After` of a minute or less.

Also available in: API [`GET /sending/streams`](https://openemail.uk/docs/api/reference/sending#get-sending-streams); TypeScript [`sending.listStreams()`](https://openemail.uk/docs/sdk/reference/sending#listStreams); Python [`sending.list_streams()`](https://openemail.uk/docs/python/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).

### `sending.resume_stream`

Resume a paused lane

```ruby
resume_stream(stream, api_key: nil) -> Hash
```

Resumes the broadcast lane after it was paused for too many bounces or complaints, as Resume does on the Analytics page of the app. Broadcasts and messages that were on hold continue at once, and the 7 day count starts again from now, so clean the audience first: a lane resumed onto the same list pauses again.

Only the workspace owner may do it: an API key acts for the owner, and an access token that acts for a member is 403 `owner_only`.

Scopes: `domains:write`.

**Parameters**

- `stream` (`String`, required): The lane to resume, `broadcast`. The transactional lane never pauses.
- `api_key` (`String`): Overrides the client's API key for this call only.

**Returns**

A Hash with the lane, now with `status` `active` and `resumedAt` set.

**Example**

```ruby
lane = client.sending.resume_stream("broadcast")

puts lane[:status], lane[:resumedAt]
```

**Notes**

- With an OAuth access token it asks for a verification code: until the app has verified one, it is refused with 403 `step_up_required`. An API key is never asked.
- A lane that is not paused is 409 `stream_not_paused`.
- The SDK does not retry it.

Also available in: API [`POST /sending/streams/{stream}/resume`](https://openemail.uk/docs/api/reference/sending#post-sending-streams-stream-resume); TypeScript [`sending.resumeStream()`](https://openemail.uk/docs/sdk/reference/sending#resumeStream); Python [`sending.resume_stream()`](https://openemail.uk/docs/python/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).

### `sending.list_dedicated_ips`

List dedicated IPs

```ruby
list_dedicated_ips(api_key: nil) -> Hash
```

Returns the dedicated sending IPs of the workspace, bought as an add-on with `billing.start_add_on_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, so nothing is held back while it warms. `status` is `warming` until then and `ready` after.

A workspace without the add-on gets an empty `data` Array and sends through the shared IPs.

Scopes: `domains:read`.

**Parameters**

- `api_key` (`String`): Overrides the client's API key for this call only.

**Returns**

A Hash with one Hash per IP in `data`: `ip`, `status`, `pool`, `poolStatus`, `warmupPercent`, `assignedAt`, `readyAt` and `checkedAt`.

**Example**

```ruby
addresses = client.sending.list_dedicated_ips

addresses[:data].each do |address|
  puts "#{address[:ip]} #{address[:status]} #{address[:warmupPercent]}%"
end
```

**Notes**

- The warm-up is read from the sending service every few minutes, and `checkedAt` says when.
- A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's `max_retries:`, and on a 429 only when it carries a `Retry-After` of a minute or less.

Also available in: API [`GET /sending/dedicated-ips`](https://openemail.uk/docs/api/reference/sending#get-sending-dedicated-ips); TypeScript [`sending.listDedicatedIps()`](https://openemail.uk/docs/sdk/reference/sending#listDedicatedIps); Python [`sending.list_dedicated_ips()`](https://openemail.uk/docs/python/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).

### `sending.get_dedicated_ip`

Read a dedicated IP

```ruby
get_dedicated_ip(ip, api_key: nil) -> Hash
```

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

Scopes: `domains:read`.

**Parameters**

- `ip` (`String`, required): The IP address, as `list_dedicated_ips` returns it, such as `203.0.113.24`.
- `api_key` (`String`): Overrides the client's API key for this call only.

**Returns**

A Hash with `ip`, `status`, `pool`, `poolStatus`, `warmupPercent`, `assignedAt`, `readyAt` and `checkedAt`.

**Example**

```ruby
address = client.sending.get_dedicated_ip("203.0.113.24")

puts address[:status], address[:warmupPercent]
```

**Notes**

- An IP that does not belong to the workspace is a 404 `resource_not_found`.
- A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's `max_retries:`, and on a 429 only when it carries a `Retry-After` of a minute or less.

Also available in: API [`GET /sending/dedicated-ips/{ip}`](https://openemail.uk/docs/api/reference/sending#get-sending-dedicated-ips-ip); TypeScript [`sending.getDedicatedIp()`](https://openemail.uk/docs/sdk/reference/sending#getDedicatedIp); Python [`sending.get_dedicated_ip()`](https://openemail.uk/docs/python/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).
