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

Progress

Levels and skills use the school’s saved progression definitions. Skill ids are level-id plus a colon and the zero-based skill position, for example level_example:0. Fetch current definitions before writing; positions can change when the school reorders its skills.

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

List levels

Returns saved level definitions and their skill ids.

Access: progress:read · MCP: list_levels

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.

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/levels" \
  -H "Authorization: Bearer ${SWUM_API_KEY}"
200Responseapplication/json
{
  "data": [
    {
      "id": "level_example",
      "name": "Beginners",
      "order": 0,
      "skills": [
        {
          "id": "level_example:0",
          "name": "Blow bubbles"
        }
      ],
      "required": 1
    }
  ],
  "next_cursor": null
}
GET/v1/progress/{swimmerId}

Get swimmer progress

Requires family_id and returns the owner’s per-skill progress for this roster swimmer. milestones counts completed plus skipped skills; completed_count and skipped_count keep them distinct. The response excludes private notes and the internal progress history.

Access: progress:read · MCP: get_swimmer_progress

Path parameters

  • swimmerIdstringRequired

    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.

  • family_idstringRequired

    The family document id. Write bodies also accept parent_uid. At most 128 characters.

Request
curl "${SWUM_API_BASE:-https://api.swum.ai}/v1/progress/swimmer_example" \
  -G \
  --data-urlencode 'family_id=family_example' \
  -H "Authorization: Bearer ${SWUM_API_KEY}"
200Responseapplication/json
{
  "data": {
    "swimmer_id": "swimmer_example",
    "family_id": "family_example",
    "levels": [
      {
        "id": "level_example",
        "name": "Beginners",
        "milestones": 1,
        "completed_count": 1,
        "skipped_count": 0,
        "completed": true,
        "required": 1,
        "skills": [
          {
            "id": "level_example:0",
            "status": "done",
            "completed_at": "2026-10-25",
            "name": "Blow bubbles"
          }
        ]
      }
    ],
    "updated_at": "2026-10-25T14:00:00.000Z"
  }
}
POST/v1/progress/{swimmerId}/skills/{skillId}/complete

Complete a skill

Marks a skill complete using the shared app progression logic. Already-completed skills are unchanged. Linked participant-group placement may advance; there is no automatic skill undo.

Access: progress: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

  • swimmerIdstringRequired

    The exact Swum document id.

  • skillIdstringRequired

    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.

  • level_idstring

    Required only when skillId is a numeric position rather than a composite level:index id. At most 128 characters.

  • datedate

    Completion date, no later than today; defaults to the server’s current date.

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/progress/swimmer_example/skills/level_example:0/complete" \
  -X POST \
  -H "Authorization: Bearer ${SWUM_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ${SWUM_IDEMPOTENCY_KEY}" \
  --data '{"family_id":"family_example","date":"2026-10-25"}'
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"
}