Skip to content

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.

Properties

PropertyTypeRequiredDescription
statusstringrequiredWhere the run stands.
stepstringrequiredThe Sequence step the person is on.
nextAtdatetimeWhen the next step fires; empty while paused or exited.
branchesstring[]The branches taken so far, in order.
exitReasonstringWhy 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

  • An Enrollment follows one Sequence: the Sequence whose steps this Enrollment walks, one step at a time. follows, inverse enrollments.
  • An Enrollment runs for one Contact: the Contact this run belongs to; pausing one Contact’s nurture pauses this Enrollment. runsFor, inverse enrollments.

Lifecycle

Enrollment lifecycle: active, paused, exited (ends)active → paused: Enrollment.pauseactive → exited: Enrollment.cancelactive → exited: on Message.createdactive → exited: on Order.placedactive → exited: on Contact.unsubscribedactive → exited: on Contact.suppressedactive → exited: on Enrollment.finishedpaused → active: Enrollment.resumepaused → exited: Enrollment.cancelpaused → exited: on Contact.suppressedactivepausedexited
StateMeaningMoves to
active (first)The Contact is on a step, and the next one fires at nextAt.paused by Enrollment.pause; exited by Enrollment.cancel; exited on Message.created when the enrolled Contact replies; exited on Order.placed when the buyer is the enrolled Contact; exited on Contact.unsubscribed when the Contact is the enrolled one; exited on Contact.suppressed when the Contact is the enrolled one; exited on Enrollment.finished
pausedNo step fires, and nextAt stays empty until it resumes.active by Enrollment.resume; exited by Enrollment.cancel; exited on Contact.suppressed when the Contact is the enrolled one
exitedEnded, with its exitReason; enrolling the Contact again starts a new Enrollment.None: it ends here.

Verbs

  1. createCreates an Enrollment.
    POST /{namespace}/enrollmentsdoEnrollment.created
  2. getReturns one Enrollment by id.
    GET /{namespace}/enrollments/{id}readNo Event
  3. listReturns Enrollments, newest first, one page at a time.
    GET /{namespace}/enrollmentsreadNo Event
  4. updateChanges the given properties of an Enrollment.
    PATCH /{namespace}/enrollments/{id}doEnrollment.updated
  5. deleteDeletes an Enrollment; its history is kept.
    DELETE /{namespace}/enrollments/{id}doEnrollment.deleted
  6. cancelCancel ends one Contact’s run through a Sequence for good, with the reason it records as `exitReason`.
    POST /{namespace}/enrollments/{enrollment}/canceldoEnrollment.canceled
  7. pausePause stops one Contact’s run through a Sequence at its current step, without ending it.
    POST /{namespace}/enrollments/{enrollment}/pausedoEnrollment.paused
  8. resumeResume restarts a paused run at the step it stopped on and sets when that step fires.
    POST /{namespace}/enrollments/{enrollment}/resumedoEnrollment.resumed

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.

FieldTypeRequiredDescription
namestringrequiredEnrollment.finished.
atdatetimerequiredWhen it happened.
seqintegerIts position in the namespace, one more than the Event before; any seq is a cursor into the history.
datajsonrequiredThe Thing as the Action left it.
data.enrollmentEnrollmentrequiredThe Enrollment as the change left it.
data.enrollment.statusstringrequiredWhere the run stands.
data.enrollment.stepstringrequiredThe Sequence step the person is on.
data.enrollment.nextAtdatetimeWhen the next step fires; empty while paused or exited.
data.enrollment.branchesstring[]The branches taken so far, in order.
data.enrollment.exitReasonstringWhy the run ended.
data.previous.statusstringrequiredThe 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.

Operationowneradminmemberviewer
Enrollment.createYesYesYesNo
Enrollment.getYesYesYesYes
Enrollment.listYesYesYesYes
Enrollment.updateYesYesYesNo
Enrollment.deleteYesYesYesNo
Enrollment.cancelYesYesYesNo
Enrollment.pauseYesYesYesNo
Enrollment.resumeYesYesYesNo

Call it

Text
Pause the latest enrollment.

Example

A trial user of a budgeting app enters the onboarding Sequence. After she links a bank account the Enrollment takes the linked branch, and it ends with exit reason purchased on day 9.