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 / Families
Families
Read the current family directory, create manual roster records, update permitted contact fields and add staff-private notes. Creation does not create an Auth account, link by email, send an invitation or store a payment card. Read responses exclude private notes and medical data.
Retry-After and X-RateLimit-RemainingPer key or agent connection, on the Enterprise plan.
/v1/familiesList families
A page of active roster families. q performs case-insensitive substring matching across family/display names, email and kid names; name and search are aliases.
Access: families: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.
- qstring
Case-insensitive name, display name, email or swimmer-name substring; name/search are aliases.
- namestring
Alias for q.
- searchstring
Alias for q.
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/families" \
-G \
--data-urlencode 'q=rivera' \
--data-urlencode 'limit=50' \
-H "Authorization: Bearer ${SWUM_API_KEY}"{
"data": [
{
"id": "family_example",
"name": "Rivera",
"email": "parent@example.test",
"phone": "+15555550142",
"status": "active",
"location_id": "pool_example",
"updated_at": "2026-10-25T14:00:00.000Z"
}
],
"next_cursor": null
}/v1/families/{id}Get a family
One active family within the connection’s location scope.
Access: families:read
Path parameters
- idstringRequired
The exact Swum document id.
Query parameters
- updated_sincedate-time
ISO 8601 datetime with an explicit time zone. Exclusive on lists; detail/open-spots reads validate it and return the current object.
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/families/family_example" \
-H "Authorization: Bearer ${SWUM_API_KEY}"{
"data": {
"id": "family_example",
"name": "Rivera",
"email": "parent@example.test",
"phone": "+15555550142",
"status": "active",
"location_id": "pool_example",
"updated_at": "2026-10-25T14:00:00.000Z"
}
}/v1/familiesCreate a family
Creates a school-owned manual family. Contact deduplication is scoped to the owner and normalized email/phone. A matching out-of-scope family is not disclosed; rosters over 5,000 need contact-index review before API contact changes.
Access: families: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
- namestringRequired
At most 200 characters.
- emailstring
At most 254 characters.
- phonestring
At most 40 characters.
- addressstring
At most 500 characters.
- location_idstring
At most 128 characters.
Current permission and roster checks
Both approval and persistence recheck the current school, roster and connection authority. Removed access, revoked or expired grants, changed records and narrowed locations can refuse a previously prepared proposal. Do not work around a refusal by starting a duplicate operation.
Contact fields
Allowed fields are name, email, phone, address and location_id. A name is required on creation. Email and phone are optional; school location ids must belong to the owner. No account, invitation, card or medical field is accepted.
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 current roster, class, entry or school policy refuses this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/families" \
-X POST \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"name":"Rivera","email":"parent@example.test","phone":"+15555550142","location_id":"pool_example"}'{
"status": "executed",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"result": {
"success": true,
"changes": {
"familyId": "family_example"
}
}
}{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}/v1/families/{id}Update a family
Updates only the supplied contact fields. Supply at least one field. A changed source field after proposal creation returns roster_changed rather than overwriting a newer office edit.
Access: families: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
- namestring
At most 200 characters.
- emailstring
At most 254 characters.
- phonestring
At most 40 characters.
- addressstring
At most 500 characters.
- location_idstring
At most 128 characters.
Current permission and roster checks
Both approval and persistence recheck the current school, roster and connection authority. Removed access, revoked or expired grants, changed records and narrowed locations can refuse a previously prepared proposal. Do not work around a refusal by starting a duplicate operation.
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 current roster, class, entry or school policy refuses this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/families/family_example" \
-X PATCH \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"phone":"+15555550143"}'{
"status": "executed",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"result": {
"success": true,
"changes": {
"familyId": "family_example"
}
}
}{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}/v1/families/{id}/notesAdd a family note
Adds a 1–5,000-character staff-private note. This write does not make note contents readable through family/list endpoints.
Access: families: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
- contentstringRequired
At most 5000 characters.
Family and swimmer notes
This family-note REST route has no MCP tool. The add_note tool uses the swimmer-note route, with swimmerId and family_id. Use non-medical operational notes; contact and medical fields are excluded from public read/event projections.
Current permission and roster checks
Both approval and persistence recheck the current school, roster and connection authority. Removed access, revoked or expired grants, changed records and narrowed locations can refuse a previously prepared proposal. Do not work around a refusal by starting a duplicate operation.
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 current roster, class, entry or school policy refuses this change. |
| 429 | rate_limit_exceeded | Wait the Retry-After interval. |
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/families/family_example/notes" \
-X POST \
-H "Authorization: Bearer ${SWUM_API_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
--data '{"content":"Parent prefers a Saturday class."}'{
"status": "executed",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"result": {
"success": true,
"changes": {
"familyId": "family_example",
"noteId": "note_example"
}
}
}{
"status": "pending_approval",
"proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
"proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}The family object
- idstring
A Swum document id; no prefix format is promised.
- namestring
- emailstring | null
- phonestring | null
- statusstring
- location_idstring | null
- updated_attimestamp | null