GET /api/v1/sales-slots
Generates a read-only preview of the sales-call slots between two instants,
for at most 31 days. Each slot lists the eligible closers in rotation order, the
closer next in line, and why each other closer is excluded. Slots already
booked are left out for the closer who holds them (already_booked). It creates
no booking and holds nothing.
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Conditional — only with a business role below |
| Requirement | Rule for this endpoint |
|---|---|
| Business role | closer scoped to the organization; setter is refused |
| Resource scope | Organization attached to the API key; a closer sees only his slots |
| Participation | None |
| Resource state | None — without a saved configuration the list is empty |
A closer previews from his own row only: every slot is one of his, and he
is its nextCloser. The team rotation and the other closers' exclusions are
not returned to him.
| Parameter | Type | Required | Description |
|---|---|---|---|
from | ISO 8601 string | yes | Start of the period |
to | ISO 8601 string | yes | End of the period: after from, at most 31 days later |
timeZone | string | no | IANA time zone; when given, it must equal the time zone of the configuration |
| Header | Required | Description |
|---|---|---|
x-api-key | yes | API key created for this organization |
X-Correlation-Id | no | Caller correlation id, returned or generated |
curl "$COHORTE_API_BASE_URL/api/v1/sales-slots?from=2026-09-28T00:00:00.000Z&to=2026-10-05T00:00:00.000Z&timeZone=Europe/Paris" \
-H "x-api-key: $COHORTE_API_KEY"200 OK — the slots of the period, possibly an empty list.400 Bad Request — from or to missing or not a date, to not after from, a period longer than 31 days, an unknown time zone, or a timeZone different from the configuration's; code is invalid_request.401 Unauthorized — missing, unknown or expired key; code is unauthorized.403 Forbidden — the bearer is not OWNER or ADMIN and holds no organization-scoped closer responsibility; code is forbidden.| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | true for a successful request |
data[].id | string | no | Deterministic slot id, stable for the same configuration version, start and closers |
data[].startsAt | ISO 8601 string | no | Call start, in UTC |
data[].endsAt | ISO 8601 string | no | Call end, in UTC |
data[].protectedStartsAt | ISO 8601 string | no | Start including the buffer before the call |
data[].protectedEndsAt | ISO 8601 string | no | End including the buffer after the call |
data[].eligibleClosers[] | array | no | id (rotation entry), userId, name, in rotation order |
data[].nextCloser | object | yes | The first eligible closer in rotation order: id, userId, name |
data[].exclusions[] | array | no | Closers left out of this slot |
data[].exclusions[].closerId | UUID | no | Rotation entry identifier |
data[].exclusions[].closerName | string | no | Closer display name |
data[].exclusions[].reason | string | no | inactive, outside_availability, exception_unavailable, already_booked or daily_capacity_reached |
correlationId | UUID | no | Correlation id for support |
{
"success": true,
"data": [
{
"id": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"startsAt": "2026-09-28T07:15:00.000Z",
"endsAt": "2026-09-28T08:00:00.000Z",
"protectedStartsAt": "2026-09-28T07:00:00.000Z",
"protectedEndsAt": "2026-09-28T08:15:00.000Z",
"eligibleClosers": [
{
"id": "c3f1d8a2-0000-4000-8000-000000000000",
"userId": "11111111-1111-4111-8111-111111111111",
"name": "Sophie Laurent"
}
],
"nextCloser": {
"id": "c3f1d8a2-0000-4000-8000-000000000000",
"userId": "11111111-1111-4111-8111-111111111111",
"name": "Sophie Laurent"
},
"exclusions": [
{
"closerId": "d7a0b3e9-0000-4000-8000-000000000000",
"closerName": "Lucas Moreau",
"reason": "outside_availability"
}
]
}
],
"correlationId": "4c8e7f12-0000-4000-8000-000000000000"
}timeZone or send the configured one: a different value is refused
rather than silently changing the meaning of the local hours.id changes when the configuration is replaced, because it depends
on the configuration version.