Enroll a trainee in a journey
POST/api/public/journeys/{journeyId}/enroll
Enroll one trainee into an active journey. Identify them with traineeId (their active coaching period is used) or with escortId to pick a specific coaching period. A trainee already enrolled in another journey returns 409 unless replaceExisting is true. Enrollments are limited to one per second per coach, so space out loops that enroll many trainees.
Authentication
Requires an API key, sent as Authorization: Bearer cp_live_....
API keys carry scopes. Get the catalog of scopes and webhook events lists every scope.
Path parameters
| Name | Type | Description |
|---|---|---|
journeyIdrequired | string |
Header parameters
| Name | Type | Description |
|---|---|---|
Idempotency-Key | string | Optional. Send a unique key (e.g. a UUID) to make this POST safe to retry. The same key within 24h returns the original result instead of creating a duplicate. |
Request body
application/json, required
| Name | Type | Description |
|---|---|---|
traineeId | string | The trainee to enroll, resolved to their active coaching period. Send this or escortId. |
escortId | string | The coaching period to enroll. Send this or traineeId when you need a specific one. |
startDateShiftDays | integer | Shift the journey start by this many days. Negative values start it in the past, so earlier steps fire immediately. |
startAtStepId | string | Begin at this step instead of the first one. |
replaceExisting | boolean | Cancel the trainee's current enrollment in another journey instead of returning 409. |
Request examples
curl --request POST \
--url 'https://api.coach-platform.com/api/public/journeys/<journeyId>/enroll' \
--header 'Authorization: Bearer cp_live_...' \
--header 'Content-Type: application/json' \
--data '{
"traineeId": "<string>"
}'const response = await fetch('https://api.coach-platform.com/api/public/journeys/<journeyId>/enroll', {
method: 'POST',
headers: {
Authorization: 'Bearer cp_live_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"traineeId": "<string>"
}),
});
const data = await response.json();Responses
201 Created
{
"data": {},
"warnings": [
{
"field": "<string>",
"message": "<string>"
}
]
}Response fields (4)
| Name | Type | Description |
|---|---|---|
data | object | |
warnings | object[] | Non-fatal problems with follow-up writes. The resource was created, but each listed field was not applied. |
warnings[].field | string | |
warnings[].message | string |
Error responses
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict429Too Many Requests500Internal Server Error
These statuses share the same response body.
{
"error": {
"code": "<string>",
"message": "<string>",
"fix": "<string>",
"details": {},
"retryAfterMs": 123
}
}Error fields (6)
| Name | Type | Description |
|---|---|---|
error | object | |
error.code | string | |
error.message | string | |
error.fix | string | null | |
error.details | object | null | |
error.retryAfterMs | number | null |
More Journeys endpoints
This page is also available as Markdown. Browse it in the interactive explorer or download the OpenAPI spec.