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

# client.automations()

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

## Methods

Emails and other steps that run by themselves for each contact, such as a welcome series or a birthday note: build a draft from a starter or your own trigger and steps, publish, pause, resume and archive it, send a test, read its versions and statistics, and enroll contacts or take them out.

### `automations().list`

List one page of the automations in the workspace

```java
Page list(RequestOptions options)
```

Returns one page of the automations the caller can reach, the most recently saved first, without their definitions or settings. Paging is keyset: `limit` takes 1 to 100 and defaults to 50, and `nextCursor` goes back as `cursor` while `hasMore` is true. `listAll` and `iterate` do that walk for you.

Each automation carries its `status`, `triggerKind`, how many steps and emails the draft holds, `hasUnpublishedChanges`, `publishedVersion` and `counts`: the contacts in it now, and the ones that completed or left in all its time, counted at the moment of the read. A paused automation says why in `pausedReason`.

Read one with `get` for the draft `definition`, the `published` one, the `settings` and the `problems` that would stop a publish.

Scopes: `automations:read`.

**Parameters**

- `options.status` (`String`): Only automations in this state: `draft`, `live`, `paused` or `archived`.
- `options.limit` (`int`): Rows per page, a whole number from 1 to 100. The server defaults to 50.
- `options.cursor` (`String`): The `nextCursor` from the previous page, passed back exactly as it came. One that names no automation is a 400 `invalid_cursor`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A `Page` of maps with `items`, `hasMore` and `nextCursor`. Each item has `id`, `name`, `description`, `status`, `triggerKind`, `stepCount`, `emailCount`, `hasUnpublishedChanges`, `publishedVersion`, `pausedReason`, `lastError`, `counts`, `createdBy`, `publishedAt`, `pausedAt`, `archivedAt`, `createdAt` and `updatedAt`.

**Example**

```java
Page page = client.automations().list(RequestOptions.of("status", "live"));

for (Map<String, Object> automation : page) {
    System.out.println(automation.get("name") + " " + automation.get("triggerKind") + " " + automation.get("counts"));
}

if (page.hasMore()) {
    System.out.println("Next page: " + page.nextCursor());
}
```

**Notes**

- An app a member connected lists only the automations that member made. An API key and an app the owner connected list every automation in the workspace.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations`](https://openemail.uk/docs/api/reference/automations#get-automations); TypeScript [`automations.list()`](https://openemail.uk/docs/sdk/reference/automations#list); Python [`automations.list()`](https://openemail.uk/docs/python/reference/automations#list); Ruby [`automations.list`](https://openemail.uk/docs/ruby/reference/automations#list); PHP [`automations->list`](https://openemail.uk/docs/php/reference/automations#list); Go [`Automations.List`](https://openemail.uk/docs/go/reference/automations#list); C# [`Automations.ListAsync`](https://openemail.uk/docs/csharp/reference/automations#list); CLI [`openemail automations list`](https://openemail.uk/docs/cli/reference/automations#automations-list).

### `automations().listAll`

Collect every automation you can reach into one list

```java
List<Map<String, Object>> listAll(RequestOptions options)
```

Follows `nextCursor` from page to page and returns every automation the caller can reach, the most recently saved first, in the shape `list` returns. `limit` sets the page size of each request, not the total.

Scopes: `automations:read`.

**Parameters**

- `options.status` (`String`): Only automations in this state: `draft`, `live`, `paused` or `archived`.
- `options.limit` (`int`): Page size per request, from 1 to 100, defaulting to 50 on the server.
- `options.cursor` (`String`): A `nextCursor` from an earlier page to start after.
- `options.apiKey` (`String`): Overrides the client's API key for every page of this walk.

**Returns**

A list of maps holding every automation across all pages, each shaped like an item of `list`.

**Example**

```java
List<Map<String, Object>> automations = client.automations().listAll();

for (Map<String, Object> automation : automations) {
    if ("paused".equals(automation.get("status"))) {
        System.out.println(automation.get("name") + " " + automation.get("pausedReason"));
    }
}
```

**Notes**

- A failure on any page throws out of the whole call.

Also available in: API [`GET /automations`](https://openemail.uk/docs/api/reference/automations#get-automations); TypeScript [`automations.listAll()`](https://openemail.uk/docs/sdk/reference/automations#listAll); Python [`automations.list_all()`](https://openemail.uk/docs/python/reference/automations#listAll); Ruby [`automations.list_all`](https://openemail.uk/docs/ruby/reference/automations#listAll); PHP [`automations->listAll`](https://openemail.uk/docs/php/reference/automations#listAll); Go [`Automations.ListAll`](https://openemail.uk/docs/go/reference/automations#listAll); C# [`Automations.ListAllAsync`](https://openemail.uk/docs/csharp/reference/automations#listAll).

### `automations().iterate`

Stream the automations you can reach one at a time

```java
PagedIterable iterate(RequestOptions options)
```

Returns a `PagedIterable` that yields automations one by one, the most recently saved first, and requests the next page only once the current one is drained. Breaking out of the loop stops the requests.

Scopes: `automations:read`.

**Parameters**

- `options.status` (`String`): Only automations in this state: `draft`, `live`, `paused` or `archived`.
- `options.limit` (`int`): Page size per request, from 1 to 100, defaulting to 50 on the server.
- `options.cursor` (`String`): A `nextCursor` from an earlier page to start after.
- `options.apiKey` (`String`): Overrides the client's API key for every page of this walk.

**Returns**

A `PagedIterable` that yields one automation map per step.

**Example**

```java
for (Map<String, Object> automation : client.automations().iterate()) {
    if (Boolean.TRUE.equals(automation.get("hasUnpublishedChanges"))) {
        System.out.println("unpublished edits: " + automation.get("name"));
    }
}
```

**Notes**

- The `PagedIterable` is lazy, so an abandoned loop costs only the pages you consumed.

Also available in: API [`GET /automations`](https://openemail.uk/docs/api/reference/automations#get-automations); TypeScript [`automations.iterate()`](https://openemail.uk/docs/sdk/reference/automations#iterate); Python [`automations.iterate()`](https://openemail.uk/docs/python/reference/automations#iterate); Ruby [`automations.iterate`](https://openemail.uk/docs/ruby/reference/automations#iterate); PHP [`automations->iterate`](https://openemail.uk/docs/php/reference/automations#iterate); Go [`Automations.Iterate`](https://openemail.uk/docs/go/reference/automations#iterate); C# [`Automations.IterateAsync`](https://openemail.uk/docs/csharp/reference/automations#iterate).

### `automations().create`

Create an automation as a draft

```java
Map<String, Object> create(Map<String, Object> body, RequestOptions options)
```

Makes a draft automation and returns it whole, in the shape `get` returns. Its trigger and steps come from `definition` when you send one, from the starter named in `starter` when you do not, and otherwise the draft starts empty. `settings` changes any of the defaults.

A draft may be incomplete: `problems` in the answer lists what is still missing, such as a template or a from address a starter leaves for you. Nothing runs until `publish`, which needs a complete draft and `emails:send`.

Scopes: `automations:write`.

**Parameters**

- `body.name` (`String`, required): What the workspace calls the automation, trimmed, 1 to 120 characters. Contacts never see it, and it need not be unique.
- `body.description` (`String or null`): A note for the workspace, at most 500 characters. Contacts never see it.
- `body.starter` (`String`): Begin from a starter, by the `slug` `listStarters` returns: `welcome-series`, `trial-follow-up`, `birthday` or `win-back`. Ignored when `definition` is sent. An unknown slug is 422 `invalid_automation`.
- `body.definition` (`Map<String, Object>`): The trigger and the steps, in the shape `get` returns as `definition`. `trigger` says what starts the automation: `audience_joined` with `audienceId` and `includeImported`, `form_submitted` with `formId`, `event` with `eventName` and `filters`, `date` with `field`, `audienceId` and `offsetDays`, or `manual`. `entry` is the key of the first step, and `steps` holds every step: `send_email`, `wait`, `branch`, `add_to_audience`, `remove_from_audience`, `update_field`, `webhook` or `exit`. Each step has a unique `key` of 3 to 24 lowercase letters and digits starting with a letter, and names the next step by key in `next`, or in `yes` and `no` for a branch. Null ends the path. Paths never join or loop, and a definition holds at most 50 steps. Leave it out to use `starter` or an empty draft.
- `body.settings.timezone` (`String`): The IANA time zone the sending window and waits until a day and time are read in, such as `Europe/London`. Defaults to `UTC`.
- `body.settings.sendWindow` (`Map<String, Object> or null`): When emails may go out: `days` of the week, where 0 is Sunday, and `startMinute` to `endMinute` of the day, counted from midnight. An email due outside it waits for the window to open. Null, the default, sends at any time.
- `body.settings.reentryDays` (`int or null`): How many days after a contact finishes before they may enter again, from 1 to 3650. Null, the default, lets each contact through once only.
- `body.settings.exitOnLeave` (`boolean`): Take a contact out when they leave the audience that started the automation. Defaults to true.
- `body.settings.listAudienceId` (`String or null`): The audience an unsubscribe from one of these emails is recorded in. Null, the default, uses the audience that starts the automation, or the built-in audience of every contact when no audience starts it. An id that is not an audience of the workspace is 422 `invalid_automation`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with the fields an item of `list` has and `status` `draft`, plus `definition`, `published`, which is null, `settings` and `problems`.

**Example**

```java
Map<String, Object> automation = client.automations().create(Body.of(
    "name", "Welcome series",
    "starter", "welcome-series",
    "settings", Body.of("timezone", "Europe/London")
));

System.out.println(automation.get("id") + " " + automation.get("status") + " " + automation.get("problems"));
```

**Notes**

- A value of the wrong type or length is 422 `invalid_parameter` with `param` naming it, and a key the body does not take is 422 `unknown_parameter`. A definition that breaks a rule of its structure, such as two steps with one key or two paths into one step, is 422 `invalid_automation`, and the `body()` of the exception lists each one in `problems`, under `error`.
- A workspace holds a limited number of automations, drafts included, and support can raise that for a workspace that needs more. The next one past the limit is 422 `workspace_limit_reached`.
- Not retried automatically, and nothing deduplicates by name, so a retry after a lost response can leave two drafts. List them and delete the spare.

Also available in: API [`POST /automations`](https://openemail.uk/docs/api/reference/automations#post-automations); TypeScript [`automations.create()`](https://openemail.uk/docs/sdk/reference/automations#create); Python [`automations.create()`](https://openemail.uk/docs/python/reference/automations#create); Ruby [`automations.create`](https://openemail.uk/docs/ruby/reference/automations#create); PHP [`automations->create`](https://openemail.uk/docs/php/reference/automations#create); Go [`Automations.Create`](https://openemail.uk/docs/go/reference/automations#create); C# [`Automations.CreateAsync`](https://openemail.uk/docs/csharp/reference/automations#create); CLI [`openemail automations create`](https://openemail.uk/docs/cli/reference/automations#automations-create).

### `automations().listStarters`

List the ready-made automations to start from

```java
List<Map<String, Object>> listStarters(RequestOptions options)
```

Returns the starting points the app offers when somebody makes an automation: a welcome series, a trial follow-up, a birthday note and a win-back. Each comes with its whole `definition`, so you can read it, change it and send it to `create`, or pass its `slug` to `create` as `starter`.

A starter leaves the audience, the templates and the from address as empty strings for you to fill in. The list is the same for every workspace and is not paginated.

Scopes: `automations:read`.

**Parameters**

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

**Returns**

A list of maps, each with `slug`, `name`, `description` and `definition`.

**Example**

```java
List<Map<String, Object>> starters = client.automations().listStarters();

for (Map<String, Object> starter : starters) {
    System.out.println(starter.get("slug") + " " + starter.get("description"));
}
```

**Notes**

- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/starters`](https://openemail.uk/docs/api/reference/automations#get-automations-starters); TypeScript [`automations.listStarters()`](https://openemail.uk/docs/sdk/reference/automations#listStarters); Python [`automations.list_starters()`](https://openemail.uk/docs/python/reference/automations#listStarters); Ruby [`automations.list_starters`](https://openemail.uk/docs/ruby/reference/automations#listStarters); PHP [`automations->listStarters`](https://openemail.uk/docs/php/reference/automations#listStarters); Go [`Automations.ListStarters`](https://openemail.uk/docs/go/reference/automations#listStarters); C# [`Automations.ListStartersAsync`](https://openemail.uk/docs/csharp/reference/automations#listStarters); CLI [`openemail automations list-starters`](https://openemail.uk/docs/cli/reference/automations#automations-list-starters).

### `automations().get`

Retrieve an automation with its definition and settings

```java
Map<String, Object> get(String id, RequestOptions options)
```

Returns the whole automation: the draft `definition` you edit, `published`, the definition of the version that is running, `settings`, fresh `counts` and `problems`.

`problems` is what is wrong with the draft at the moment of the read, each with a `code`, the `path` of the field, the `stepKey`, a `message` and `blocking`, which is false for a warning. An empty list means the draft is ready, though `publish` checks more: that every template can be sent and that the caller may send from every from address.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with `id`, `name`, `description`, `status`, `triggerKind`, `stepCount`, `emailCount`, `hasUnpublishedChanges`, `publishedVersion`, `pausedReason`, `lastError`, `counts`, `createdBy`, `publishedAt`, `pausedAt`, `archivedAt`, `createdAt` and `updatedAt`, plus `definition`, `published`, `settings` and `problems`.

**Example**

```java
Map<String, Object> automation = client.automations().get("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(automation.get("status") + " " + automation.get("definition"));
System.out.println(automation.get("problems"));
```

**Notes**

- An id that names no automation the caller can reach is 404 `automation_not_found`, whether it does not exist or belongs to another workspace.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/{id}`](https://openemail.uk/docs/api/reference/automations#get-automations-id); TypeScript [`automations.get()`](https://openemail.uk/docs/sdk/reference/automations#get); Python [`automations.get()`](https://openemail.uk/docs/python/reference/automations#get); Ruby [`automations.get`](https://openemail.uk/docs/ruby/reference/automations#get); PHP [`automations->get`](https://openemail.uk/docs/php/reference/automations#get); Go [`Automations.Get`](https://openemail.uk/docs/go/reference/automations#get); C# [`Automations.GetAsync`](https://openemail.uk/docs/csharp/reference/automations#get); CLI [`openemail automations get`](https://openemail.uk/docs/cli/reference/automations#automations-get).

### `automations().update`

Change the draft, the settings or the name of an automation

```java
Map<String, Object> update(String id, Map<String, Object> patch, RequestOptions options)
```

A partial update that returns the automation whole. `definition` replaces the draft, and a live automation keeps running its published version until you `publish` again, so an edit never changes the path of a contact who is halfway through. `settings` is merged field by field and takes effect at once.

Read the automation, change it and send `expectedUpdatedAt` with the `updatedAt` you read. If someone saved it in between, the call is refused with 409 `version_conflict` instead of writing over their change.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `patch.name` (`String`): New name, trimmed, 1 to 120 characters.
- `patch.description` (`String or null`): New note, at most 500 characters. Null clears it.
- `patch.definition` (`Map<String, Object>`): The new draft, whole. The trigger and the steps, in the shape `get` returns as `definition`. `trigger` says what starts the automation: `audience_joined` with `audienceId` and `includeImported`, `form_submitted` with `formId`, `event` with `eventName` and `filters`, `date` with `field`, `audienceId` and `offsetDays`, or `manual`. `entry` is the key of the first step, and `steps` holds every step: `send_email`, `wait`, `branch`, `add_to_audience`, `remove_from_audience`, `update_field`, `webhook` or `exit`. Each step has a unique `key` of 3 to 24 lowercase letters and digits starting with a letter, and names the next step by key in `next`, or in `yes` and `no` for a branch. Null ends the path. Paths never join or loop, and a definition holds at most 50 steps.
- `patch.settings.timezone` (`String`): The IANA time zone the sending window and waits until a day and time are read in, such as `Europe/London`. Defaults to `UTC`.
- `patch.settings.sendWindow` (`Map<String, Object> or null`): When emails may go out: `days` of the week, where 0 is Sunday, and `startMinute` to `endMinute` of the day, counted from midnight. An email due outside it waits for the window to open. Null, the default, sends at any time.
- `patch.settings.reentryDays` (`int or null`): How many days after a contact finishes before they may enter again, from 1 to 3650. Null, the default, lets each contact through once only.
- `patch.settings.exitOnLeave` (`boolean`): Take a contact out when they leave the audience that started the automation. Defaults to true.
- `patch.settings.listAudienceId` (`String or null`): The audience an unsubscribe from one of these emails is recorded in. Null, the default, uses the audience that starts the automation, or the built-in audience of every contact when no audience starts it. An id that is not an audience of the workspace is 422 `invalid_automation`.
- `patch.expectedUpdatedAt` (`String`): The `updatedAt` you read, as an ISO 8601 instant. When the automation was saved since, the call is refused with 409 `version_conflict` and nothing is written.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as it is after the save, with a new `updatedAt` and, when the draft changed, `hasUnpublishedChanges` true on a published automation.

**Example**

```java
Map<String, Object> current = client.automations().get("aut_5c1e9a7b3d2f48e6a0b4c7d1");

Map<String, Object> saved = client.automations().update("aut_5c1e9a7b3d2f48e6a0b4c7d1", Body.of(
    "settings", Body.of("sendWindow", Body.of("days", List.of(1, 2, 3, 4, 5), "startMinute", 540, "endMinute", 1020)),
    "expectedUpdatedAt", current.get("updatedAt")
));

System.out.println(saved.get("settings") + " " + saved.get("updatedAt"));
```

**Notes**

- An archived automation cannot be changed and answers 409 `automation_archived`.
- A value of the wrong type or length is 422 `invalid_parameter`, a key the patch does not take is 422 `unknown_parameter`, and a definition that breaks a rule of its structure is 422 `invalid_automation`, with `problems` under `error` in the `body()` of the exception.
- Retried automatically on network failure and retryable statuses, since saving the same patch twice leaves the same automation. With `expectedUpdatedAt`, a retry after a lost response answers 409 `version_conflict`: read the automation to see that your change is there.

Also available in: API [`PATCH /automations/{id}`](https://openemail.uk/docs/api/reference/automations#patch-automations-id); TypeScript [`automations.update()`](https://openemail.uk/docs/sdk/reference/automations#update); Python [`automations.update()`](https://openemail.uk/docs/python/reference/automations#update); Ruby [`automations.update`](https://openemail.uk/docs/ruby/reference/automations#update); PHP [`automations->update`](https://openemail.uk/docs/php/reference/automations#update); Go [`Automations.Update`](https://openemail.uk/docs/go/reference/automations#update); C# [`Automations.UpdateAsync`](https://openemail.uk/docs/csharp/reference/automations#update); CLI [`openemail automations update`](https://openemail.uk/docs/cli/reference/automations#automations-update).

### `automations().delete`

Delete an automation with its versions and history

```java
Map<String, Object> delete(String id, RequestOptions options)
```

Deletes the automation with its versions, its enrollments and its statistics. Contacts in it stop at once and get nothing more. The emails it already sent stay in `emails().list`.

There is no undo. To retire an automation and keep its history, use `archive`.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with `object` set to `automation`, `id` and `deleted` set to true.

**Example**

```java
Map<String, Object> removed = client.automations().delete("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(removed.get("id") + " " + removed.get("deleted"));
```

**Notes**

- An OAuth access token needs a verification code for this call, and is refused with 403 `step_up_required` until the app has verified one in the last 60 minutes. `isStepUpRequired()` on the exception says so. An API key is never asked for a code.
- The SDK does not retry a delete. A 404 on your own second attempt after a lost response means the first one worked.

Also available in: API [`DELETE /automations/{id}`](https://openemail.uk/docs/api/reference/automations#delete-automations-id); TypeScript [`automations.delete()`](https://openemail.uk/docs/sdk/reference/automations#delete); Python [`automations.delete()`](https://openemail.uk/docs/python/reference/automations#delete); Ruby [`automations.delete`](https://openemail.uk/docs/ruby/reference/automations#delete); PHP [`automations->delete`](https://openemail.uk/docs/php/reference/automations#delete); Go [`Automations.Delete`](https://openemail.uk/docs/go/reference/automations#delete); C# [`Automations.DeleteAsync`](https://openemail.uk/docs/csharp/reference/automations#delete); CLI [`openemail automations delete`](https://openemail.uk/docs/cli/reference/automations#automations-delete).

### `automations().publish`

Publish the draft and turn the automation on

```java
Map<String, Object> publish(String id, RequestOptions options)
```

Saves the draft as the next version and sets the automation `live`, so its trigger starts taking contacts in. Contacts already in it stay on the version they entered on. Publishing a paused automation turns it back on. It takes no body.

The draft has to be complete: a trigger, at least one step, every email with a published template that declares `unsubscribeUrl` and a from address the caller may send as, and every audience, form and webhook it names still there. Anything else is 422 `invalid_automation`, and the `body()` of the exception lists every problem that blocks it in `problems`, under `error`.

The automation sends as whoever published it. When that API key is revoked, expires or is turned off, the automation pauses itself with `pausedReason` `key_revoked`.

Scopes: `automations:write`, `emails:send`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as `get` returns it, with `status` `live`, a new `publishedAt`, the `publishedVersion` that is now running and `hasUnpublishedChanges` false.

**Example**

```java
Map<String, Object> automation = client.automations().publish("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(automation.get("status") + " " + automation.get("publishedVersion") + " " + automation.get("publishedAt"));
```

**Notes**

- A plan covers a number of live automations: 1 on Free, 10 on Starter and 50 on Business, with no limit on Enterprise. One more is 403 `automation_limit_reached`. Pause one, or upgrade.
- An archived automation answers 409 `automation_archived`.
- Publishing a draft that has not changed since the last publish keeps the same version number.
- Retried automatically on network failure and retryable statuses, since publishing the same draft twice leaves the same live version.

Also available in: API [`POST /automations/{id}/publish`](https://openemail.uk/docs/api/reference/automations#post-automations-id-publish); TypeScript [`automations.publish()`](https://openemail.uk/docs/sdk/reference/automations#publish); Python [`automations.publish()`](https://openemail.uk/docs/python/reference/automations#publish); Ruby [`automations.publish`](https://openemail.uk/docs/ruby/reference/automations#publish); PHP [`automations->publish`](https://openemail.uk/docs/php/reference/automations#publish); Go [`Automations.Publish`](https://openemail.uk/docs/go/reference/automations#publish); C# [`Automations.PublishAsync`](https://openemail.uk/docs/csharp/reference/automations#publish); CLI [`openemail automations publish`](https://openemail.uk/docs/cli/reference/automations#automations-publish).

### `automations().pause`

Stop a live automation without losing anybody

```java
Map<String, Object> pause(String id, RequestOptions options)
```

Stops a live automation. Nobody new enters, and everyone in it stays where they are and moves on when it is resumed. The `automation.paused` webhook event fires. Pausing a paused automation changes nothing. It takes no body.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as `get` returns it, with `status` `paused`, `pausedReason` `manual` and `pausedAt` set.

**Example**

```java
Map<String, Object> automation = client.automations().pause("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(automation.get("status") + " " + automation.get("pausedReason") + " " + automation.get("counts"));
```

**Notes**

- A draft that was never published answers 409 `automation_not_published`, and an archived automation 409 `automation_archived`.
- Retried automatically on network failure and retryable statuses, since pausing twice leaves the same paused automation.

Also available in: API [`POST /automations/{id}/pause`](https://openemail.uk/docs/api/reference/automations#post-automations-id-pause); TypeScript [`automations.pause()`](https://openemail.uk/docs/sdk/reference/automations#pause); Python [`automations.pause()`](https://openemail.uk/docs/python/reference/automations#pause); Ruby [`automations.pause`](https://openemail.uk/docs/ruby/reference/automations#pause); PHP [`automations->pause`](https://openemail.uk/docs/php/reference/automations#pause); Go [`Automations.Pause`](https://openemail.uk/docs/go/reference/automations#pause); C# [`Automations.PauseAsync`](https://openemail.uk/docs/csharp/reference/automations#pause); CLI [`openemail automations pause`](https://openemail.uk/docs/cli/reference/automations#automations-pause).

### `automations().resume`

Turn a paused automation back on

```java
Map<String, Object> resume(String id, RequestOptions options)
```

Turns a paused automation back on with the version it was running, without publishing the draft. Contacts that were held move on, and from now on it sends as the caller. Resuming a live automation changes nothing. It takes no body.

The published version is checked again first, exactly as `publish` checks a draft. An automation OpenEmail paused, because its from address, its templates or an audience went away, stays paused with 422 `invalid_automation` until what stopped it is fixed.

Scopes: `automations:write`, `emails:send`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as `get` returns it, with `status` `live` and `pausedReason`, `pausedAt` and `lastError` cleared.

**Example**

```java
Map<String, Object> automation = client.automations().resume("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(automation.get("status") + " " + automation.get("publishedVersion"));
```

**Notes**

- An automation with no published version answers 409 `automation_not_published`, an archived one 409 `automation_archived`, and a plan that covers no more live automations 403 `automation_limit_reached`.
- Retried automatically on network failure and retryable statuses, since resuming twice leaves the same live automation.

Also available in: API [`POST /automations/{id}/resume`](https://openemail.uk/docs/api/reference/automations#post-automations-id-resume); TypeScript [`automations.resume()`](https://openemail.uk/docs/sdk/reference/automations#resume); Python [`automations.resume()`](https://openemail.uk/docs/python/reference/automations#resume); Ruby [`automations.resume`](https://openemail.uk/docs/ruby/reference/automations#resume); PHP [`automations->resume`](https://openemail.uk/docs/php/reference/automations#resume); Go [`Automations.Resume`](https://openemail.uk/docs/go/reference/automations#resume); C# [`Automations.ResumeAsync`](https://openemail.uk/docs/csharp/reference/automations#resume); CLI [`openemail automations resume`](https://openemail.uk/docs/cli/reference/automations#automations-resume).

### `automations().archive`

Retire an automation for good and keep its history

```java
Map<String, Object> archive(String id, RequestOptions options)
```

Retires an automation. Everyone in it leaves with the exit reason `archived`, nobody enters again, and it can no longer be changed, published or resumed. Its versions, enrollments and statistics stay readable. Archiving an archived automation changes nothing. It takes no body.

An automation with many contacts in it empties in the background over the next minutes. To start again from its steps, use `duplicate`.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as `get` returns it, with `status` `archived` and `archivedAt` set.

**Example**

```java
Map<String, Object> automation = client.automations().archive("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(automation.get("status") + " " + automation.get("archivedAt"));
```

**Notes**

- There is no way back from archived. To stop an automation for a while, use `pause`.
- Retried automatically on network failure and retryable statuses, since archiving twice leaves the same archived automation.

Also available in: API [`POST /automations/{id}/archive`](https://openemail.uk/docs/api/reference/automations#post-automations-id-archive); TypeScript [`automations.archive()`](https://openemail.uk/docs/sdk/reference/automations#archive); Python [`automations.archive()`](https://openemail.uk/docs/python/reference/automations#archive); Ruby [`automations.archive`](https://openemail.uk/docs/ruby/reference/automations#archive); PHP [`automations->archive`](https://openemail.uk/docs/php/reference/automations#archive); Go [`Automations.Archive`](https://openemail.uk/docs/go/reference/automations#archive); C# [`Automations.ArchiveAsync`](https://openemail.uk/docs/csharp/reference/automations#archive); CLI [`openemail automations archive`](https://openemail.uk/docs/cli/reference/automations#automations-archive).

### `automations().duplicate`

Copy an automation into a new draft

```java
Map<String, Object> duplicate(String id, RequestOptions options)
```

Makes a new draft with the same draft definition and settings, named after the original with (copy) on the end. The copy has no versions, no contacts and no statistics, and it works on an archived automation too. It takes no body.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the copy as `get` returns an automation, with its own `id` and `status` `draft`.

**Example**

```java
Map<String, Object> copy = client.automations().duplicate("aut_5c1e9a7b3d2f48e6a0b4c7d1");

System.out.println(copy.get("id") + " " + copy.get("name") + " " + copy.get("status"));
```

**Notes**

- A workspace that already holds the most automations it may answers 422 `workspace_limit_reached`.
- Not retried automatically, so a retry after a lost response can leave two copies. List them and delete the spare.

Also available in: API [`POST /automations/{id}/duplicate`](https://openemail.uk/docs/api/reference/automations#post-automations-id-duplicate); TypeScript [`automations.duplicate()`](https://openemail.uk/docs/sdk/reference/automations#duplicate); Python [`automations.duplicate()`](https://openemail.uk/docs/python/reference/automations#duplicate); Ruby [`automations.duplicate`](https://openemail.uk/docs/ruby/reference/automations#duplicate); PHP [`automations->duplicate`](https://openemail.uk/docs/php/reference/automations#duplicate); Go [`Automations.Duplicate`](https://openemail.uk/docs/go/reference/automations#duplicate); C# [`Automations.DuplicateAsync`](https://openemail.uk/docs/csharp/reference/automations#duplicate); CLI [`openemail automations duplicate`](https://openemail.uk/docs/cli/reference/automations#automations-duplicate).

### `automations().sendTest`

Send yourself the email of one step

```java
Map<String, Object> sendTest(String id, Map<String, Object> body, RequestOptions options)
```

Sends the email of one step of the draft to one address, so you can read it before publishing. Contact values are filled from a sample contact, values that come from an event are left empty, and the subject starts with [Test]. It counts toward the monthly sends, is not tracked and enrolls nobody.

Scopes: `automations:write`, `emails:send`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `body.stepKey` (`String`, required): The `key` of the email step to send, from the draft `definition`.
- `body.to` (`String`): Where the test goes. Left out, it goes to the account email of the person the key or app acts for: the workspace owner for an API key.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with `automationId`, `emailId`, the email as `emails().get` returns it, `to` and `stepKey`.

**Example**

```java
Map<String, Object> test = client.automations().sendTest("aut_5c1e9a7b3d2f48e6a0b4c7d1", Body.of(
    "stepKey", "welcome",
    "to", "ada@example.com"
));

System.out.println(test.get("emailId") + " " + test.get("to"));
```

**Notes**

- A `stepKey` that names no step, a step that is not an email, or a template that cannot be sent is 422 `invalid_automation` with `param` `stepKey`.
- The from address of the step has to be one the caller may send as, or the call is refused with 403 `from_address_forbidden`. A domain that cannot send yet is 409 `domain_not_sendable`, and a plan with no sends left is 429 `send_quota_exceeded`.
- Not retried automatically, because a retry after a lost response would send the test twice.

Also available in: API [`POST /automations/{id}/test`](https://openemail.uk/docs/api/reference/automations#post-automations-id-test); TypeScript [`automations.sendTest()`](https://openemail.uk/docs/sdk/reference/automations#sendTest); Python [`automations.send_test()`](https://openemail.uk/docs/python/reference/automations#sendTest); Ruby [`automations.send_test`](https://openemail.uk/docs/ruby/reference/automations#sendTest); PHP [`automations->sendTest`](https://openemail.uk/docs/php/reference/automations#sendTest); Go [`Automations.SendTest`](https://openemail.uk/docs/go/reference/automations#sendTest); C# [`Automations.SendTestAsync`](https://openemail.uk/docs/csharp/reference/automations#sendTest); CLI [`openemail automations send-test`](https://openemail.uk/docs/cli/reference/automations#automations-send-test).

### `automations().listVersions`

List the published versions of an automation

```java
List<Map<String, Object>> listVersions(String id, RequestOptions options)
```

Returns every published version, the newest first, each with its whole definition. `current` marks the one that is running. A publish that changed the definition adds a version, and each contact stays on the version they entered on. A draft that was never published has none. The list is not paginated.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A list of maps, each with `id`, `automationId`, `version`, `definition`, `current`, `createdBy` and `createdAt`.

**Example**

```java
List<Map<String, Object>> versions = client.automations().listVersions("aut_5c1e9a7b3d2f48e6a0b4c7d1");

for (Map<String, Object> version : versions) {
    System.out.println(version.get("version") + " " + version.get("current") + " " + version.get("createdAt"));
}
```

**Notes**

- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/{id}/versions`](https://openemail.uk/docs/api/reference/automations#get-automations-id-versions); TypeScript [`automations.listVersions()`](https://openemail.uk/docs/sdk/reference/automations#listVersions); Python [`automations.list_versions()`](https://openemail.uk/docs/python/reference/automations#listVersions); Ruby [`automations.list_versions`](https://openemail.uk/docs/ruby/reference/automations#listVersions); PHP [`automations->listVersions`](https://openemail.uk/docs/php/reference/automations#listVersions); Go [`Automations.ListVersions`](https://openemail.uk/docs/go/reference/automations#listVersions); C# [`Automations.ListVersionsAsync`](https://openemail.uk/docs/csharp/reference/automations#listVersions); CLI [`openemail automations list-versions`](https://openemail.uk/docs/cli/reference/automations#automations-list-versions).

### `automations().restoreVersion`

Copy an earlier version back into the draft

```java
Map<String, Object> restoreVersion(String id, int version, RequestOptions options)
```

Copies the definition of an earlier version into the draft, replacing what the draft holds. Nothing that is running changes until you `publish`. It takes no body.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `version` (`int`, required): The number of the version, from `listVersions`. A whole number from 1 up.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the automation as `get` returns it, with the version in `definition`, and `hasUnpublishedChanges` true when it differs from the one that is running.

**Example**

```java
Map<String, Object> automation = client.automations().restoreVersion("aut_5c1e9a7b3d2f48e6a0b4c7d1", 2);

System.out.println(automation.get("hasUnpublishedChanges") + " " + automation.get("definition"));
```

**Notes**

- A version the automation does not have is 404 `automation_not_found` with `param` `version`, and an archived automation is 409 `automation_archived`.
- Retried automatically on network failure and retryable statuses, since restoring the same version twice leaves the same draft.

Also available in: API [`POST /automations/{id}/versions/{version}/restore`](https://openemail.uk/docs/api/reference/automations#post-automations-id-versions-version-restore); TypeScript [`automations.restoreVersion()`](https://openemail.uk/docs/sdk/reference/automations#restoreVersion); Python [`automations.restore_version()`](https://openemail.uk/docs/python/reference/automations#restoreVersion); Ruby [`automations.restore_version`](https://openemail.uk/docs/ruby/reference/automations#restoreVersion); PHP [`automations->restoreVersion`](https://openemail.uk/docs/php/reference/automations#restoreVersion); Go [`Automations.RestoreVersion`](https://openemail.uk/docs/go/reference/automations#restoreVersion); C# [`Automations.RestoreVersionAsync`](https://openemail.uk/docs/csharp/reference/automations#restoreVersion); CLI [`openemail automations restore-version`](https://openemail.uk/docs/cli/reference/automations#automations-restore-version).

### `automations().stats`

Read how an automation has performed

```java
Map<String, Object> stats(String id, RequestOptions options)
```

Returns the numbers of an automation over a window: `totals` for the whole automation, `steps` with the same numbers step by step, and `series` with a point for each UTC day on which something happened. The window defaults to the last 30 days and reaches back at most 366 days before `until`.

The steps are those of the published version, or of the draft when nothing is published. `totals.active` and the `waiting` of each step are counted at the moment of the read, whatever the window. Opens are a floor, because many mail apps hide them.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.since` (`Instant or String`): Where the window starts, as an `Instant` or an ISO 8601 string. Left out, 30 days before `until`.
- `options.until` (`Instant or String`): Where the window ends, as an `Instant` or an ISO 8601 string. Left out, now. It has to be later than `since`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with `automationId`, `since`, `until`, `totals` (`entered`, `active`, `completed`, `exited`, `sent`, `delivered`, `opened`, `clicked`, `bounced`, `complained` and `unsubscribed`), `steps` and `series`.

**Example**

```java
Map<String, Object> stats = client.automations().stats("aut_5c1e9a7b3d2f48e6a0b4c7d1", RequestOptions.of("since", Instant.parse("2026-09-01T00:00:00Z")));

System.out.println(stats.get("totals"));
System.out.println(stats.get("steps"));
```

**Notes**

- A time that is not an ISO 8601 instant, or an `until` that is not after `since`, is 422 `invalid_parameter`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/{id}/stats`](https://openemail.uk/docs/api/reference/automations#get-automations-id-stats); TypeScript [`automations.stats()`](https://openemail.uk/docs/sdk/reference/automations#stats); Python [`automations.stats()`](https://openemail.uk/docs/python/reference/automations#stats); Ruby [`automations.stats`](https://openemail.uk/docs/ruby/reference/automations#stats); PHP [`automations->stats`](https://openemail.uk/docs/php/reference/automations#stats); Go [`Automations.Stats`](https://openemail.uk/docs/go/reference/automations#stats); C# [`Automations.StatsAsync`](https://openemail.uk/docs/csharp/reference/automations#stats); CLI [`openemail automations stats`](https://openemail.uk/docs/cli/reference/automations#automations-stats).

### `automations().listEnrollments`

List one page of the contacts in an automation

```java
Page listEnrollments(String id, RequestOptions options)
```

Returns one page of everyone who is in the automation or has been, the most recent entry first. Each enrollment says who the `contact` is, the `stepKey` they are at, whether they are `waiting` and for which event, what holds a step that is due in `heldFor`, when they move next in `nextRunAt`, and how it ended in `exitReason`.

`limit` takes 1 to 200 and defaults to 50. Pass `nextCursor` back as `cursor`, with the same filters, while `hasMore` is true. `listAllEnrollments` and `iterateEnrollments` do that walk for you.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.status` (`String`): Only enrollments in this state: `active`, `completed` or `exited`.
- `options.stepKey` (`String`): Only contacts at the step with this `key`.
- `options.q` (`String`): Only contacts whose address or name contains this text, compared without case, up to 200 characters.
- `options.limit` (`int`): Rows per page, a whole number from 1 to 200. The server defaults to 50.
- `options.cursor` (`String`): The `nextCursor` from the previous page, passed back exactly as it came. One that names no enrollment of this automation is a 400 `invalid_cursor`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A `Page` of maps with `items`, `hasMore` and `nextCursor`. Each item has `id`, `automationId`, `version`, `contact`, `status`, `source`, `stepKey`, `waiting`, `waitingForEvent`, `heldFor`, `nextRunAt`, `exitReason`, `lastError`, `startedAt`, `finishedAt` and `updatedAt`.

**Example**

```java
Page page = client.automations().listEnrollments("aut_5c1e9a7b3d2f48e6a0b4c7d1", RequestOptions.of("status", "active"));

for (Map<String, Object> enrollment : page) {
    System.out.println(enrollment.get("contact") + " " + enrollment.get("stepKey") + " " + enrollment.get("nextRunAt"));
}
```

**Notes**

- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/{id}/enrollments`](https://openemail.uk/docs/api/reference/automations#get-automations-id-enrollments); TypeScript [`automations.listEnrollments()`](https://openemail.uk/docs/sdk/reference/automations#listEnrollments); Python [`automations.list_enrollments()`](https://openemail.uk/docs/python/reference/automations#listEnrollments); Ruby [`automations.list_enrollments`](https://openemail.uk/docs/ruby/reference/automations#listEnrollments); PHP [`automations->listEnrollments`](https://openemail.uk/docs/php/reference/automations#listEnrollments); Go [`Automations.ListEnrollments`](https://openemail.uk/docs/go/reference/automations#listEnrollments); C# [`Automations.ListEnrollmentsAsync`](https://openemail.uk/docs/csharp/reference/automations#listEnrollments); CLI [`openemail automations list-enrollments`](https://openemail.uk/docs/cli/reference/automations#automations-list-enrollments).

### `automations().listAllEnrollments`

Collect every enrollment of an automation into one list

```java
List<Map<String, Object>> listAllEnrollments(String id, RequestOptions options)
```

Follows `nextCursor` from page to page and returns every enrollment that matches, the most recent entry first, in the shape `listEnrollments` returns. `limit` sets the page size of each request, not the total. An automation can hold a great many enrollments, so prefer `iterateEnrollments` when you do not need them all in memory.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.status` (`String`): Only enrollments in this state: `active`, `completed` or `exited`.
- `options.stepKey` (`String`): Only contacts at the step with this `key`.
- `options.q` (`String`): Only contacts whose address or name contains this text, compared without case, up to 200 characters.
- `options.limit` (`int`): Page size per request, from 1 to 200, defaulting to 50 on the server.
- `options.cursor` (`String`): A `nextCursor` from an earlier page to start after.
- `options.apiKey` (`String`): Overrides the client's API key for every page of this walk.

**Returns**

A list of maps holding every matching enrollment across all pages, each shaped like an item of `listEnrollments`.

**Example**

```java
List<Map<String, Object>> exited = client.automations().listAllEnrollments("aut_5c1e9a7b3d2f48e6a0b4c7d1", RequestOptions.create().set("status", "exited").limit(200));
long unsubscribed = exited.stream().filter(enrollment -> "unsubscribed".equals(enrollment.get("exitReason"))).count();

System.out.println(unsubscribed + " of " + exited.size() + " left by unsubscribing");
```

**Notes**

- A failure on any page throws out of the whole call.

Also available in: API [`GET /automations/{id}/enrollments`](https://openemail.uk/docs/api/reference/automations#get-automations-id-enrollments); TypeScript [`automations.listAllEnrollments()`](https://openemail.uk/docs/sdk/reference/automations#listAllEnrollments); Python [`automations.list_all_enrollments()`](https://openemail.uk/docs/python/reference/automations#listAllEnrollments); Ruby [`automations.list_all_enrollments`](https://openemail.uk/docs/ruby/reference/automations#listAllEnrollments); PHP [`automations->listAllEnrollments`](https://openemail.uk/docs/php/reference/automations#listAllEnrollments); Go [`Automations.ListAllEnrollments`](https://openemail.uk/docs/go/reference/automations#listAllEnrollments); C# [`Automations.ListAllEnrollmentsAsync`](https://openemail.uk/docs/csharp/reference/automations#listAllEnrollments).

### `automations().iterateEnrollments`

Stream the enrollments of an automation one at a time

```java
PagedIterable iterateEnrollments(String id, RequestOptions options)
```

Returns a `PagedIterable` that yields enrollments one by one, the most recent entry first, and requests the next page only once the current one is drained. Breaking out of the loop stops the requests.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `options.status` (`String`): Only enrollments in this state: `active`, `completed` or `exited`.
- `options.stepKey` (`String`): Only contacts at the step with this `key`.
- `options.q` (`String`): Only contacts whose address or name contains this text, compared without case, up to 200 characters.
- `options.limit` (`int`): Page size per request, from 1 to 200, defaulting to 50 on the server.
- `options.cursor` (`String`): A `nextCursor` from an earlier page to start after.
- `options.apiKey` (`String`): Overrides the client's API key for every page of this walk.

**Returns**

A `PagedIterable` that yields one enrollment map per step.

**Example**

```java
for (Map<String, Object> enrollment : client.automations().iterateEnrollments("aut_5c1e9a7b3d2f48e6a0b4c7d1", RequestOptions.of("status", "active"))) {
    if (enrollment.get("heldFor") != null) {
        System.out.println(enrollment.get("contact") + " held for " + enrollment.get("heldFor"));
    }
}
```

**Notes**

- The `PagedIterable` is lazy, so an abandoned loop costs only the pages you consumed.

Also available in: API [`GET /automations/{id}/enrollments`](https://openemail.uk/docs/api/reference/automations#get-automations-id-enrollments); TypeScript [`automations.iterateEnrollments()`](https://openemail.uk/docs/sdk/reference/automations#iterateEnrollments); Python [`automations.iterate_enrollments()`](https://openemail.uk/docs/python/reference/automations#iterateEnrollments); Ruby [`automations.iterate_enrollments`](https://openemail.uk/docs/ruby/reference/automations#iterateEnrollments); PHP [`automations->iterateEnrollments`](https://openemail.uk/docs/php/reference/automations#iterateEnrollments); Go [`Automations.IterateEnrollments`](https://openemail.uk/docs/go/reference/automations#iterateEnrollments); C# [`Automations.IterateEnrollmentsAsync`](https://openemail.uk/docs/csharp/reference/automations#iterateEnrollments).

### `automations().getEnrollment`

Retrieve one contact's way through an automation

```java
Map<String, Object> getEnrollment(String id, String enrollmentId, RequestOptions options)
```

Returns one enrollment with `runs`: what each step did for the contact, oldest first, up to 200. A run has the `stepKey`, the `kind` of step, an `outcome` such as `sent`, `waited`, `yes`, `no`, `skipped` or `failed`, the `emailId` a send step produced and a `detail` that says why a step was skipped or failed.

Scopes: `automations:read`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `enrollmentId` (`String`, required): Enrollment id such as `aen_2b8d4f6a1c3e5079b6d8f0a2`, from `listEnrollments`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map with `id`, `automationId`, `version`, `contact`, `status`, `source`, `stepKey`, `waiting`, `waitingForEvent`, `heldFor`, `nextRunAt`, `exitReason`, `lastError`, `startedAt`, `finishedAt` and `updatedAt`, plus `runs`.

**Example**

```java
Map<String, Object> enrollment = client.automations().getEnrollment("aut_5c1e9a7b3d2f48e6a0b4c7d1", "aen_2b8d4f6a1c3e5079b6d8f0a2");

System.out.println(enrollment.get("status") + " " + enrollment.get("stepKey"));
System.out.println(enrollment.get("runs"));
```

**Notes**

- An enrollment id that is not in this automation is 404 `automation_enrollment_not_found`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /automations/{id}/enrollments/{enrollmentId}`](https://openemail.uk/docs/api/reference/automations#get-automations-id-enrollments-enrollmentid); TypeScript [`automations.getEnrollment()`](https://openemail.uk/docs/sdk/reference/automations#getEnrollment); Python [`automations.get_enrollment()`](https://openemail.uk/docs/python/reference/automations#getEnrollment); Ruby [`automations.get_enrollment`](https://openemail.uk/docs/ruby/reference/automations#getEnrollment); PHP [`automations->getEnrollment`](https://openemail.uk/docs/php/reference/automations#getEnrollment); Go [`Automations.GetEnrollment`](https://openemail.uk/docs/go/reference/automations#getEnrollment); C# [`Automations.GetEnrollmentAsync`](https://openemail.uk/docs/csharp/reference/automations#getEnrollment); CLI [`openemail automations get-enrollment`](https://openemail.uk/docs/cli/reference/automations#automations-get-enrollment).

### `automations().enroll`

Put a contact into a live automation

```java
Map<String, Object> enroll(String id, Map<String, Object> body, RequestOptions options)
```

Puts one contact into a live automation at its first step, whatever its trigger is. Name the contact with `email` or `contactId`, never both. The contact has to exist already: save one with `contacts().create` first. `data` gives the steps the values they would otherwise read from an event.

A contact is in an automation once at a time, and comes back in only after `settings.reentryDays`. An address on the suppression list, or one that unsubscribed from the audience the automation sends through, is refused.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `body.email` (`String`): The contact, by email address. Send this or `contactId`.
- `body.contactId` (`String`): The contact, by id, as an event or another enrollment carries it. Send this or `email`.
- `body.data` (`Map<String, Object>`): Values the steps can read wherever a value comes from the event, such as an order number for an email. At most 50 keys and 4 KB of JSON.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the enrollment shaped like an item of `listEnrollments`, with `status` `active`, `source` `api` and `nextRunAt` now. The first step runs within about a minute.

**Example**

```java
Map<String, Object> enrollment = client.automations().enroll("aut_5c1e9a7b3d2f48e6a0b4c7d1", Body.of(
    "email", "ada@example.com",
    "data", Body.of("plan", "team")
));

System.out.println(enrollment.get("id") + " " + enrollment.get("status") + " " + enrollment.get("nextRunAt"));
```

**Notes**

- An automation that is a draft, paused or archived answers 409 `automation_not_live`. A contact who is in it, or finished it too recently, answers 409 `already_enrolled`, and a suppressed or unsubscribed address 409 `contact_unreachable`. An address or id nobody has is 404 `contact_not_found`.
- Sending neither or both of `email` and `contactId` is 422 `invalid_parameter`.
- Not retried automatically. After a lost response, a second attempt that answers 409 `already_enrolled` means the first one worked.

Also available in: API [`POST /automations/{id}/enrollments`](https://openemail.uk/docs/api/reference/automations#post-automations-id-enrollments); TypeScript [`automations.enroll()`](https://openemail.uk/docs/sdk/reference/automations#enroll); Python [`automations.enroll()`](https://openemail.uk/docs/python/reference/automations#enroll); Ruby [`automations.enroll`](https://openemail.uk/docs/ruby/reference/automations#enroll); PHP [`automations->enroll`](https://openemail.uk/docs/php/reference/automations#enroll); Go [`Automations.Enroll`](https://openemail.uk/docs/go/reference/automations#enroll); C# [`Automations.EnrollAsync`](https://openemail.uk/docs/csharp/reference/automations#enroll); CLI [`openemail automations enroll`](https://openemail.uk/docs/cli/reference/automations#automations-enroll).

### `automations().exitEnrollment`

Take a contact out of an automation

```java
Map<String, Object> exitEnrollment(String id, String enrollmentId, RequestOptions options)
```

Ends an active enrollment at once with the exit reason `removed`. The contact gets nothing more from this automation, and stays in the contacts and in their audiences. It takes no body.

Scopes: `automations:write`.

**Parameters**

- `id` (`String`, required): Automation id such as `aut_5c1e9a7b3d2f48e6a0b4c7d1`.
- `enrollmentId` (`String`, required): Enrollment id such as `aen_2b8d4f6a1c3e5079b6d8f0a2`, from `listEnrollments`.
- `options.apiKey` (`String`): Overrides the client's API key for this call only.

**Returns**

A map, the enrollment shaped like an item of `listEnrollments`, with `status` `exited`, `exitReason` `removed` and `finishedAt` set.

**Example**

```java
Map<String, Object> enrollment = client.automations().exitEnrollment("aut_5c1e9a7b3d2f48e6a0b4c7d1", "aen_2b8d4f6a1c3e5079b6d8f0a2");

System.out.println(enrollment.get("status") + " " + enrollment.get("exitReason") + " " + enrollment.get("finishedAt"));
```

**Notes**

- An enrollment that already completed or left answers 409 `automation_enrollment_finished`.
- Not retried automatically. After a lost response, a second attempt that answers 409 `automation_enrollment_finished` means the first one worked.

Also available in: API [`POST /automations/{id}/enrollments/{enrollmentId}/exit`](https://openemail.uk/docs/api/reference/automations#post-automations-id-enrollments-enrollmentid-exit); TypeScript [`automations.exitEnrollment()`](https://openemail.uk/docs/sdk/reference/automations#exitEnrollment); Python [`automations.exit_enrollment()`](https://openemail.uk/docs/python/reference/automations#exitEnrollment); Ruby [`automations.exit_enrollment`](https://openemail.uk/docs/ruby/reference/automations#exitEnrollment); PHP [`automations->exitEnrollment`](https://openemail.uk/docs/php/reference/automations#exitEnrollment); Go [`Automations.ExitEnrollment`](https://openemail.uk/docs/go/reference/automations#exitEnrollment); C# [`Automations.ExitEnrollmentAsync`](https://openemail.uk/docs/csharp/reference/automations#exitEnrollment); CLI [`openemail automations exit-enrollment`](https://openemail.uk/docs/cli/reference/automations#automations-exit-enrollment).
