Enterprise: the API, webhooks and MCP server are live for schools on the Enterprise plan. The owner allows every key and AI connection. Ask about Enterprise
On this page
API Reference / Lessons
Lessons
Read school lessons or book a single swimmer using prepaid time credits or no charge. Lesson cancellations and reschedules always wait for the owner in Swummy.
Retry-After and X-RateLimit-RemainingPer key or agent connection, on the Enterprise plan.
/v1/lessonsList lessons
Lists lessons in the owner’s lesson directory, excluding unfinished checkouts. Date bounds filter the lesson start time.
Access: lessons:read
Headers
- AuthorizationstringRequired
Bearer <token>: an API key or an agent OAuth access token. App subscription routes require a dedicated app key. - Swum-Versiondate
Pins the response shape. Default:
2026-10-25.
Query parameters
- updated_sincedate-time
Effective update time after an ISO 8601 timestamp with an explicit time zone. Follow every page, including the legacy-record suffix.
- limitinteger
1–200; default 50. Minimum 1. Maximum 200. Default: 50.
- cursorstring
Opaque next_cursor from the previous page. Keep the same filters.
- start_atdate-time
Inclusive start bound.
- end_atdate-time
Inclusive end bound.
- coach_idstring
At most 128 characters.
- location_idstring
At most 128 characters.
Pagination
Keep calling with cursor=next_cursor until next_cursor is null. A filtered page may be short or empty while a next cursor remains.
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/lessons" \
-G \
--data-urlencode 'start_at=2026-11-01T00:00:00Z' \
--data-urlencode 'end_at=2026-11-30T23:59:59Z' \
-H "Authorization: Bearer ${SWUM_API_KEY}"{
"data": [
{
"id": "lesson_example",
"family_id": "family_example",
"coach_id": "owner_example",
"location_id": "pool_example",
"start_at": "2026-11-07T14:00:00.000Z",
"end_at": "2026-11-07T14:30:00.000Z",
"status": "booked",
"swimmer_ids": [
"swimmer_example"
],
"updated_at": null
}
],
"next_cursor": null
}/v1/lessonsBook a lesson
Books using the owner’s existing manual-booking checks. package spends prepaid time-bank minutes; no_charge bills nothing. Saved-card charges, invoice and plan bookings are unavailable.
Access: lessons:write
Headers
- Idempotency-KeystringRequired
Any unique string, like a UUID. Send the same key again and you get the first answer back instead of doing it twice. Keys last 24 hours.
Body
- family_idstring
The family document id. Write bodies also accept parent_uid. At most 128 characters.
- parent_uidstring
Alias for family_id; use one family identifier. At most 128 characters.
- swimmer_idstringRequired
At most 128 characters.
- datedateRequired
YYYY-MM-DD at the selected location.
- timestringRequired
HH:MM or a supported AM/PM time.
- duration_minutesintegerRequired
15–240 minutes. Minimum 15. Maximum 240.
- payment_sourcestringRequired
Prepaid time credits or no-charge only. Saved-card charges are unavailable. Allowed: "package", "no_charge".
- location_idstring
Must resolve to an owner location. At most 128 characters.
- lesson_typestring
Default individual; the current proposal selects one participant. Allowed: "individual", "semi-private". Default: "individual".
Approval and retries
Ask Me First waits for owner approval; API keys and Can Act connections can execute eligible operations directly. Preserve one Idempotency-Key for identical retries. A pending proposal or queued job is not completed work.
Errors
Every error has the same shape: a type, a code you can switch on, a plain message, and a request_id for support. A param identifies the field at fault when available.
| Status | Code | When |
|---|---|---|
| 400 | invalid_parameter | A required field is missing or malformed. |
| 401 | invalid_token | The key/token is invalid, revoked or expired. |
| 403 | insufficient_scope | The connection lacks the route’s access. |
| 404 | not_found | The school record is unavailable, including location-scoped reads. |
| 409 | idempotency_conflict | The same key was used for a different request. |
| 422 | proposal_refused | The existing Swum domain checks could not safely prepare this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/lessons" \
-X POST \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"family_id":"family_example","swimmer_id":"swimmer_example","date":"2026-11-07","time":"09:00","duration_minutes":30,"location_id":"pool_example","payment_source":"no_charge"}'{
"status": "executed",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"result": {
"success": true,
"message": "Completed.",
"changes": {}
}
}{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}/v1/lessons/{id}/rescheduleReschedule a lesson
Prepares a move; the owner’s own app session executes it after approval. Domain checks may refuse unsupported lesson types, stale times or occupied slots.
Access: lessons:write
Headers
- Idempotency-KeystringRequired
Any unique string, like a UUID. Send the same key again and you get the first answer back instead of doing it twice. Keys last 24 hours.
Path parameters
- idstringRequired
The exact Swum document id.
Body
- datedateRequired
New date in the lesson’s time zone.
- timestringRequired
New local start time.
- reasonstring
Approval and retries
Always requires owner approval in Swum, including for API keys and Can Act agents. Preserve one Idempotency-Key for identical retries. A pending proposal or queued job is not completed work.
Errors
Every error has the same shape: a type, a code you can switch on, a plain message, and a request_id for support. A param identifies the field at fault when available.
| Status | Code | When |
|---|---|---|
| 400 | invalid_parameter | A required field is missing or malformed. |
| 401 | invalid_token | The key/token is invalid, revoked or expired. |
| 403 | insufficient_scope | The connection lacks the route’s access. |
| 404 | not_found | The school record is unavailable, including location-scoped reads. |
| 409 | idempotency_conflict | The same key was used for a different request. |
| 422 | proposal_refused | The existing Swum domain checks could not safely prepare this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/lessons/lesson_example/reschedule" \
-X POST \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"date":"2026-11-14","time":"10:00"}'{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}/v1/lessons/{id}/cancelCancel a lesson
Prepares a cancellation without requesting a refund. The owner approves in Swummy and the normal lesson endpoint applies the school’s current policy. Integration callers cannot request refunds.
Access: lessons:write
Headers
- Idempotency-KeystringRequired
Any unique string, like a UUID. Send the same key again and you get the first answer back instead of doing it twice. Keys last 24 hours.
Path parameters
- idstringRequired
The exact Swum document id.
Body
- reasonstring
- refund_choicestring
Optional; none is the only accepted value. Allowed: "none". Default: "none".
Approval and retries
Always requires owner approval in Swum, including for API keys and Can Act agents. Preserve one Idempotency-Key for identical retries. A pending proposal or queued job is not completed work.
Errors
Every error has the same shape: a type, a code you can switch on, a plain message, and a request_id for support. A param identifies the field at fault when available.
| Status | Code | When |
|---|---|---|
| 400 | invalid_parameter | A required field is missing or malformed. |
| 401 | invalid_token | The key/token is invalid, revoked or expired. |
| 403 | insufficient_scope | The connection lacks the route’s access. |
| 404 | not_found | The school record is unavailable, including location-scoped reads. |
| 409 | idempotency_conflict | The same key was used for a different request. |
| 422 | proposal_refused | The existing Swum domain checks could not safely prepare this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/lessons/lesson_example/cancel" \
-X POST \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"refund_choice":"none","reason":"Pool closed"}'{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}/v1/proposals/{id}Get a proposal status
Only the key or agent connection that requested the proposal can read it. approved means execution started, not that it completed.
Access: same connection
Path parameters
- idstringRequired
The exact Swum document id.
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/proposals/7a1991ec-5e37-43a0-a581-84e817790e4b" \
-H "Authorization: Bearer ${SWUM_API_KEY}"{
"id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"action_type": "LESSONS_CANCEL_LESSON",
"status": "executed",
"created_at": "2026-10-25T14:00:00.000Z",
"result": {
"message": "Lesson canceled."
}
}The lesson object
- idstring
- family_idstring | null
- coach_idstring | null
- location_idstring | null
- start_attimestamp | null
- end_attimestamp | null
- swimmer_idsstring[]
- statusstring
- updated_attimestamp | null