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 / Enrollments

Enrollments

Read canonical occurrence enrollments, request family-confirmed enrollment, or add a swimmer to one verified free occurrence. Integrations cannot charge a family or silently enroll them in a paid class.

3,000requests per UTC hour
10requests a second, in bursts
429when over, with Retry-After and X-RateLimit-Remaining

Per key or agent connection, on the Enterprise plan.

GET/v1/enrollments

List enrollments

Requires both class_id and instance_id. Results are occurrence participant records, not a school-wide subscription ledger. Child states include active, absent, scheduled_drop, transferred and canceled; enrollment_kind describes the enrollment source.

Access: classes:read · MCP: list_enrollments

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.

  • statusstring

    Optional exact family enrollment status; all disables this filter.

  • class_idstringRequired

    At most 128 characters.

  • instance_idstringRequired

    The exact class occurrence id; a calendar date is not an instance id. 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.

Request
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/enrollments" \
  -G \
  --data-urlencode 'class_id=class_example' \
  --data-urlencode 'instance_id=instance_example' \
  -H "Authorization: Bearer ${SWUM_API_KEY}"
200Responseapplication/json
{
  "data": [
    {
      "id": "family_example",
      "family_id": "family_example",
      "class_id": "class_example",
      "instance_id": "instance_example",
      "swimmer_ids": [
        "swimmer_example"
      ],
      "status": "active",
      "swimmers": [
        {
          "id": "swimmer_example",
          "name": "Avery Rivera",
          "status": "active",
          "absent": false,
          "enrollment_kind": "permanent",
          "checked_in_at": null,
          "scheduled_drop_date": null
        }
      ],
      "updated_at": null
    }
  ],
  "next_cursor": null
}
POST/v1/classes/{id}/participants/{swimmerId}/remove

Remove a class participant

Removes exactly the named swimmer from a supported series class. Refund choice is fixed to none. Existing class lifecycle checks may refuse legacy billing models or ambiguous swimmer names.

Access: classes: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.

  • swimmerIdstringRequired

    The exact Swum document id.

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.

  • scopestring

    Default instance. series covers upcoming dates. Allowed: "instance", "series". Default: "instance".

  • instance_idstring

    Required to select the occurrence when scope is instance unless an unambiguous date is supplied. At most 128 characters.

  • datedate

    Calendar date YYYY-MM-DD in the location's time zone.

  • reasonstring

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.

StatusCodeWhen
400invalid_parameterA required field is missing or malformed.
401invalid_tokenThe key/token is invalid, revoked or expired.
403insufficient_scopeThe connection lacks the route’s access.
404not_foundThe school record is unavailable, including location-scoped reads.
409idempotency_conflictThe same key was used for a different request.
422proposal_refusedThe existing Swum domain checks could not safely prepare this change.
429rate_limit_exceededWait the Retry-After interval.
Request
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/classes/class_example/participants/swimmer_example/remove" \
  -X POST \
  -H "Authorization: Bearer ${SWUM_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
  --data '{"family_id":"family_example","scope":"instance","instance_id":"instance_example"}'
200Executedapplication/json
{
  "status": "executed",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "result": {
    "success": true,
    "message": "Completed.",
    "changes": {}
  }
}
202Pending owner approvalapplication/json
{
  "status": "pending_approval",
  "proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}
POST/v1/classes/{id}/waitlist/{swimmerId}/remove

Remove from a waitlist

The underlying operation removes a family’s waitlist entry across upcoming dates. The API therefore permits only entries containing exactly the named swimmer; multi-swimmer entries must be managed in Swum.

Access: classes: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.

  • swimmerIdstringRequired

    The exact Swum document id.

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.

  • reasonstring

    Removes the verified single-swimmer family's upcoming waitlist entries; instance selectors are not applied.

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.

StatusCodeWhen
400invalid_parameterA required field is missing or malformed.
401invalid_tokenThe key/token is invalid, revoked or expired.
403insufficient_scopeThe connection lacks the route’s access.
404not_foundThe school record is unavailable, including location-scoped reads.
409idempotency_conflictThe same key was used for a different request.
422proposal_refusedThe existing Swum domain checks could not safely prepare this change.
429rate_limit_exceededWait the Retry-After interval.
Request
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/classes/class_example/waitlist/swimmer_example/remove" \
  -X POST \
  -H "Authorization: Bearer ${SWUM_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
  --data '{"family_id":"family_example"}'
200Executedapplication/json
{
  "status": "executed",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "result": {
    "success": true,
    "message": "Completed.",
    "changes": {}
  }
}
202Pending owner approvalapplication/json
{
  "status": "pending_approval",
  "proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}
POST/v1/enrollments

Request enrollment or add to a free occurrence

mode=request is the default: creates a canonical family enrollment request. Registered families receive the normal Swum request; manual families wait for verified account claim/onboarding. It does not enroll or charge the family. mode=free adds only the exact instance_id after proving tuition, registration and service fees are zero and rechecking capacity, eligibility and required evaluations.

Access: classes: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_idstringRequired

    At most 128 characters.

  • swimmer_idstringRequired

    At most 128 characters.

  • class_idstringRequired

    At most 128 characters.

  • modestring

    Allowed: "request", "free". Default: "request".

  • instance_idstring

    Required for free mode; adds only this verified occurrence. At most 128 characters.

A separate free-mode request

For a genuinely free class, send mode:free and instance_id with family_id, swimmer_id and class_id. Use a new operation key for that distinct payload. Missing prices are not proof of free tuition; fees, capacity, eligibility and evaluation requirements still apply. A 202 with result.changes.status=requested means the integration action ran but the family has not confirmed enrollment.

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.

StatusCodeWhen
400invalid_parameterA required field is missing or malformed.
401invalid_tokenThe key/token is invalid, revoked or expired.
403insufficient_scopeThe connection lacks the route’s access.
404not_foundThe school record is unavailable, including location-scoped reads.
409idempotency_conflictThe same key was used for a different request.
422proposal_refusedThe current roster, class, entry or school policy refuses this change.
429rate_limit_exceededWait the Retry-After interval.
Request
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/enrollments" \
  -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","class_id":"class_example","mode":"request"}'
202Family confirmation requestedapplication/json
{
  "status": "executed",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "result": {
    "success": true,
    "changes": {
      "status": "requested",
      "familyId": "family_example",
      "kidId": "swimmer_example",
      "classId": "class_example",
      "requestId": "class_request_example",
      "delivery": "message"
    }
  }
}
202Pending owner approvalapplication/json
{
  "status": "pending_approval",
  "proposalId": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b"
}
200Free occurrence addedapplication/json
{
  "status": "executed",
  "proposal_id": "7a1991ec-5e37-43a0-a581-84e817790e4b",
  "result": {
    "success": true,
    "changes": {
      "familyId": "family_example",
      "kidId": "swimmer_example",
      "classId": "class_example",
      "instanceId": "instance_example"
    }
  }
}