# Enrollment

URL: /business/nouns/enrollment · Id: `noun:enrollment`

> An Enrollment is one person’s run through one Sequence: the current step, when the next fires, the branches taken, and why it ended.

An Enrollment is one person’s run through one [Sequence](/business/nouns/sequence): the current step, when the next fires, the branches taken, and why it ended.

## Properties
| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | `string` | Yes | Where the run stands. |
| `step` | `string` | Yes | The Sequence step the person is on. |
| `nextAt` | `datetime` | No | When the next step fires; empty while paused or exited. |
| `branches` | `string[]` | No | The branches taken so far, in order. |
| `exitReason` | `string` | No | Why the run ended. |

## Object
```json
{
  "$id": "https://api.sb/petpantry.shop/enrollments/enrollment_1",
  "$type": "Enrollment",
  "status": "active",
  "step": "Example step",
  "nextAt": "2026-10-22T12:00:00Z",
  "branches": [
    "Example branches"
  ],
  "exitReason": "replied"
}
```

## Relationships
- <a id="rel-follows"></a>An Enrollment **follows** one [Sequence](/business/nouns/sequence): the [Sequence](/business/nouns/sequence) whose steps this Enrollment walks, one step at a time. `follows`, inverse [`enrollments`](/business/nouns/sequence#rel-enrollments).
- <a id="rel-runs-for"></a>An Enrollment **runs for** one [Contact](/business/nouns/contact): the [Contact](/business/nouns/contact) this run belongs to; pausing one Contact’s nurture pauses this Enrollment. `runsFor`, inverse [`enrollments`](/business/nouns/contact#rel-enrollments).

## Lifecycle

| State | Meaning | Moves to |
| --- | --- | --- |
| `active` (first) | The Contact is on a step, and the next one fires at `nextAt`. | `paused` by [Enrollment.pause](/business/nouns/enrollment/pause); `exited` by [Enrollment.cancel](/business/nouns/enrollment/cancel); `exited` on `Message.created` when the enrolled Contact replies; `exited` on [`Order.placed`](/business/events/Order.placed) when the buyer is the enrolled Contact; `exited` on [`Contact.unsubscribed`](/business/events/Contact.unsubscribed) when the Contact is the enrolled one; `exited` on [`Contact.suppressed`](/business/events/Contact.suppressed) when the Contact is the enrolled one; `exited` on [`Enrollment.finished`](/business/nouns/enrollment#enrollmentfinished) |
| `paused` | No step fires, and `nextAt` stays empty until it resumes. | `active` by [Enrollment.resume](/business/nouns/enrollment/resume); `exited` by [Enrollment.cancel](/business/nouns/enrollment/cancel); `exited` on [`Contact.suppressed`](/business/events/Contact.suppressed) when the Contact is the enrolled one |
| `exited` | Ended, with its `exitReason`; enrolling the Contact again starts a new Enrollment. | None: it ends here. |

## Verbs
| Verb | Description | Subject | Event | Class |
| --- | --- | --- | --- | --- |
| [Enrollment.cancel](/business/nouns/enrollment/cancel) | Cancel ends one Contact’s run through a Sequence for good, with the reason it records as `exitReason`. | [Prospector](/agents/sales/prospector) | [`Enrollment.canceled`](/business/events/Enrollment.canceled) | Two-way: `try`, `send`, `do` |
| [Enrollment.pause](/business/nouns/enrollment/pause) | Pause stops one Contact’s run through a Sequence at its current step, without ending it. | [Prospector](/agents/sales/prospector) | [`Enrollment.paused`](/business/events/Enrollment.paused) | Two-way: `try`, `send`, `do` |
| [Enrollment.resume](/business/nouns/enrollment/resume) | Resume restarts a paused run at the step it stopped on and sets when that step fires. | [Prospector](/agents/sales/prospector) | [`Enrollment.resumed`](/business/events/Enrollment.resumed) | Two-way: `try`, `send`, `do` |
| <a id="create"></a>[Enrollment.create](/business/nouns/enrollment/create) | Creates an Enrollment. Inherited from [Noun](/business/nouns/noun). | None. | `Enrollment.created` | Two-way: `try`, `send`, `do` |
| <a id="get"></a>[Enrollment.get](/business/nouns/enrollment/get) | Returns one Enrollment by id. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="list"></a>[Enrollment.list](/business/nouns/enrollment/list) | Returns Enrollments, newest first, one page at a time. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="update"></a>[Enrollment.update](/business/nouns/enrollment/update) | Changes the given properties of an Enrollment. Inherited from [Noun](/business/nouns/noun). | None. | `Enrollment.updated` | Two-way: `try`, `send`, `do` |
| <a id="delete"></a>[Enrollment.delete](/business/nouns/enrollment/delete) | Deletes an Enrollment; its history is kept. Inherited from [Noun](/business/nouns/noun). | None. | `Enrollment.deleted` | One-way: `send`, `do` |

## Events
Events no Verb emits. Each Verb’s Event is in the Verbs table above; every Event is delivered in the same shape.

### Enrollment.finished
A Contact passed the last step of a Sequence with no exit Event, so the run ends with `exitReason` `finished`. Raised by the runtime.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | Yes | `Enrollment.finished`. |
| `at` | `datetime` | Yes | When it happened. |
| `seq` | `integer` | No | Its position in the namespace, one more than the Event before; any seq is a cursor into the history. |
| `data` | `json` | Yes | The Thing as the Action left it. |
| `data.enrollment` | [Enrollment](/business/nouns/enrollment) | Yes | The Enrollment as the change left it. |
| `data.enrollment.status` | `string` | Yes | Where the run stands. |
| `data.enrollment.step` | `string` | Yes | The Sequence step the person is on. |
| `data.enrollment.nextAt` | `datetime` | No | When the next step fires; empty while paused or exited. |
| `data.enrollment.branches` | `string[]` | No | The branches taken so far, in order. |
| `data.enrollment.exitReason` | `string` | No | Why the run ended. |
| `data.previous.status` | `string` | Yes | The `status` before this Event: `active`. |

```json
{
  "$id": "https://api.sb/petpantry.shop/events/event_1",
  "$type": "Event",
  "name": "Enrollment.finished",
  "at": "2026-10-22T12:00:00Z",
  "data": {
    "enrollment": {
      "$id": "https://api.sb/petpantry.shop/enrollments/enrollment_1",
      "$type": "Enrollment",
      "status": "exited",
      "step": "Example step",
      "nextAt": "2026-10-22T12:00:00Z",
      "branches": [
        "Example branches"
      ],
      "exitReason": "replied"
    },
    "previous": {
      "status": "active"
    }
  },
  "seq": 1
}
```

## Permissions
Which Access level may call each Verb. One-way Verbs wait their delay window.

| Operation | `owner` | `admin` | `member` | `viewer` |
| --- | --- | --- | --- | --- |
| `Enrollment.create` | Yes | Yes | Yes | No |
| `Enrollment.get` | Yes | Yes | Yes | Yes |
| `Enrollment.list` | Yes | Yes | Yes | Yes |
| `Enrollment.update` | Yes | Yes | Yes | No |
| `Enrollment.delete` | Yes | Yes | Yes | No |
| `Enrollment.cancel` | Yes | Yes | Yes | No |
| `Enrollment.pause` | Yes | Yes | Yes | No |
| `Enrollment.resume` | Yes | Yes | Yes | No |

## Call it

**Ask**

```text
Pause the latest enrollment.
```

**API**

```bash
curl -X POST https://api.sb/kilnbakery.com/enrollments/enrollment_1/pause \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

```json
{
  "api": "https://api.sb/kilnbakery.com",
  "enrollment": {
    "$id": "https://api.sb/kilnbakery.com/enrollments/enrollment_1",
    "$type": "Enrollment",
    "status": "active",
    "step": "Example step"
  },
  "action": {
    "$id": "https://api.sb/kilnbakery.com/actions/action_1",
    "operation": "Enrollment.pause",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/kilnbakery.com/actions/action_1"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const enrollment = await $.Enrollment.pause({ enrollment: 'enrollment_1' })
```

**CLI**

```bash
npx startup-builder do Enrollment.pause --json '{"enrollment":"enrollment_1"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Enrollment.pause({ enrollment: 'enrollment_1' })"
  }
}
```

## Example
A trial user of a budgeting app enters the onboarding [Sequence](/business/nouns/sequence). After she links a bank account the Enrollment takes the `linked` branch, and it ends with exit reason `purchased` on day 9.