# Start a coaching period

`POST https://api.coach-platform.com/api/public/escorts`

Start a new coaching period (escort) for a trainee. The plan ids required depend on escortType: "Training" needs trainingPlanId, "Nutrition" needs nutritionMenuId, "Nutrition and training" needs both, and "Other" needs neither. Create the plan or menu first (POST /training-plans, POST /nutrition-menus) and pass its id here. A trainee may only have one active escort at a time.

- Resource: Escorts
- Authentication: API key in the `Authorization: Bearer cp_live_...` header
- HTML version: https://www.coach-platform.com/docs/api/reference/post-escorts
- OpenAPI spec: https://www.coach-platform.com/openapi.json

## Header parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `Idempotency-Key` | string | No | 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

Content type: `application/json`. Required.

| Field | Type | Required | Description |
|---|---|---|---|
| `traineeId` | string | Yes |   |
| `escortType` | string | Yes | Determines which plan ids are required: Training -> trainingPlanId, Nutrition -> nutritionMenuId, Nutrition and training -> both, Other -> none. Allowed values: `Nutrition`, `Training`, `Nutrition and training`, `Other`. |
| `startDate` | string | Yes | ISO date. |
| `endDate` | string | No | ISO date. Provide this or months. |
| `months` | number | No | Duration in months. Provide this or endDate. |
| `goal` | string | No |   |
| `price` | number | No |   |
| `paymentDate` | string | No |   |
| `paymentMethod` | string | No | Allowed values: `Cash`, `Credit card`, `Bank transfer`, `Other`. |
| `paymentNumber` | number | No |   |
| `escortMeetingType` | string | No | Allowed values: `Online`, `In person`. |
| `onlineEscort` | string | No |   |
| `inPersonEscort` | string | No |   |
| `notes` | string | No | Optional first note on the coaching period. |
| `cardioDays` | number | No |   |
| `cardioTime` | number | No |   |
| `trainingDays` | number | No |   |
| `dailyStepsTarget` | number | No |   |
| `trainingPlanId` | string | No | Assign an existing training plan. Required when escortType is "Training" or "Nutrition and training". |
| `nutritionMenuId` | string | No | Assign an existing nutrition menu. Required when escortType is "Nutrition" or "Nutrition and training". |
| `skipRegistrationForms` | boolean | No | true: the trainee is not asked to fill registration forms in the app during this coaching period. false: the app asks the trainee to fill every active registration form aimed at them that they have not filled yet. Defaults to true when omitted on create. This is the same switch as the registration-forms toggle on the trainee profile. It belongs to this coaching period only, and a link to a specific form sent to the trainee keeps working either way. |

## Responses

| Status | Description |
|---|---|
| `201` Created |  |
| `400` Bad Request |  |
| `401` Unauthorized |  |
| `403` Forbidden |  |
| `404` Not Found |  |
| `409` Conflict |  |
| `429` Too Many Requests |  |
| `500` Internal Server Error |  |

### 201 Created

Content type: `application/json`

| Field | Type | Description |
|---|---|---|
| `data` | object |   |
| `data.id` | string |   |
| `data.coach` | string |   |
| `data.trainee` | object | The escorted trainee. email and phoneNumber are returned only when the key also has the trainees:read scope. |
| `data.trainee.id` | string |   |
| `data.trainee.name` | string |   |
| `data.trainee.email` | string |   |
| `data.trainee.phoneNumber` | string |   |
| `data.status` | string | Allowed values: `pending`, `active`, `canceled`, `completed`, `suspended`. |
| `data.escortType` | string |   |
| `data.startDate` | string<date-time> |   |
| `data.endDate` | string<date-time> \| null | When the coaching period ends. null when the escort runs with no time limit, in which case isUnlimited is true. |
| `data.months` | integer \| null | Duration in months. null when the escort runs with no time limit. |
| `data.isUnlimited` | boolean | True when the escort has no end date. |
| `data.training` | object |   |
| `data.training.activeTrainingPlan` | object \| null |   |
| `data.training.activeTrainingPlan.id` | string |   |
| `data.training.activeTrainingPlan.title` | string |   |
| `data.training.activeTrainingPlan.level` | string |   |
| `data.training.trainingDays` | any |   |
| `data.nutrition` | object |   |
| `data.nutrition.activeNutritionPlan` | object \| null |   |
| `data.nutrition.activeNutritionPlan.id` | string |   |
| `data.nutrition.activeNutritionPlan.title` | string |   |
| `data.nutrition.activeNutritionPlan.level` | string |   |
| `data.skipRegistrationForms` | boolean | true when the trainee is not asked to fill registration forms in the app during this coaching period. Change it with PATCH /escorts/{escortId}. |
| `data.createdAt` | string<date-time> |   |
| `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 |   |

Example:

```json
{
  "data": {
    "id": "<string>",
    "coach": "<string>",
    "trainee": {
      "id": "<string>",
      "name": "<string>",
      "email": "<string>",
      "phoneNumber": "<string>"
    },
    "status": "pending",
    "escortType": "<string>",
    "startDate": "<date-time>",
    "endDate": "<date-time>",
    "months": 123,
    "isUnlimited": true,
    "training": {
      "activeTrainingPlan": {
        "id": "<string>",
        "title": "<string>",
        "level": "<string>"
      },
      "trainingDays": null
    },
    "nutrition": {
      "activeNutritionPlan": {
        "id": "<string>",
        "title": "<string>",
        "level": "<string>"
      }
    },
    "skipRegistrationForms": true,
    "createdAt": "<date-time>"
  },
  "warnings": [
    {
      "field": "<string>",
      "message": "<string>"
    }
  ]
}
```

### Error responses 400, 401, 403, 404, 409, 429, 500

Content type: `application/json`

| Field | Type | Description |
|---|---|---|
| `error` | object |   |
| `error.code` | string |   |
| `error.message` | string |   |
| `error.fix` | string \| null |   |
| `error.details` | object \| null |   |
| `error.retryAfterMs` | number \| null |   |

Example:

```json
{
  "error": {
    "code": "<string>",
    "message": "<string>",
    "fix": "<string>",
    "details": {},
    "retryAfterMs": 123
  }
}
```

## Examples

### cURL

```bash
curl --request POST \
  --url 'https://api.coach-platform.com/api/public/escorts' \
  --header 'Authorization: Bearer cp_live_...' \
  --header 'Content-Type: application/json' \
  --data '{
  "traineeId": "<string>",
  "escortType": "Nutrition",
  "startDate": "<string>"
}'
```

### JavaScript (fetch)

```js
const response = await fetch('https://api.coach-platform.com/api/public/escorts', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer cp_live_...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "traineeId": "<string>",
    "escortType": "Nutrition",
    "startDate": "<string>"
  }),
});

const data = await response.json();
```

## Related endpoints

- [Get a coaching period](https://www.coach-platform.com/docs/api/reference/get-escorts-escort-id/index.md): `GET /api/public/escorts/{escortId}`. Get a coaching period by id.
- [Update a coaching period](https://www.coach-platform.com/docs/api/reference/patch-escorts-escort-id/index.md): `PATCH /api/public/escorts/{escortId}`. Update a coaching period.
- [Cancel a coaching period](https://www.coach-platform.com/docs/api/reference/delete-escorts-escort-id/index.md): `DELETE /api/public/escorts/{escortId}`. Cancel a coaching period.
- Previous: [Cancel a coaching period](https://www.coach-platform.com/docs/api/reference/delete-escorts-escort-id/index.md): `DELETE /api/public/escorts/{escortId}`. Cancel a coaching period.
- Next: [List training plans](https://www.coach-platform.com/docs/api/reference/get-training-plans/index.md): `GET /api/public/training-plans`. List training plans.
