{"openapi":"3.1.0","info":{"title":"EquipEngine API","version":"1","description":"Read your organization's EquipEngine data, and — with write scopes — assign courses and flows, revoke enrollments, invite learners and build draft courses. Available on the Multiply plan. Scopes: people:read, courses:read, enrollments:read, flows:read, courses:write, enrollments:write, people:invite."},"servers":[{"url":"https://api.equipengine.com"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key from Settings → API"}}},"paths":{"/v1/me":{"get":{"operationId":"me.get","summary":"The calling key and its organization","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"key":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["people:read","courses:read","enrollments:read","flows:read","courses:write","enrollments:write","people:invite"]}},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","name","scopes","expires_at"]},"organization":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"]}},"required":["key","organization"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/people":{"get":{"operationId":"people.list","summary":"List people (staff accounts excluded)","x-required-scope":"people:read","x-required-scopes":["people:read"],"parameters":[{"name":"role","in":"query","required":false,"schema":{"type":"string","enum":["admin","creator","learner"]}},{"name":"email","in":"query","required":false,"description":"Exact address, any case","schema":{"description":"Exact address, any case","type":"string","maxLength":320}},{"name":"q","in":"query","required":false,"description":"Part of a name or email address, any case","schema":{"description":"Part of a name or email address, any case","type":"string","minLength":2,"maxLength":100}},{"name":"updated_since","in":"query","required":false,"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","schema":{"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","creator","learner"],"description":"Their role in your organization"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When they joined (ISO-8601, UTC)"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Last change to this person"}},"required":["id","name","email","role","created_at","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/people/{id}":{"get":{"operationId":"people.get","summary":"Get a person","x-required-scope":"people:read","x-required-scopes":["people:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","creator","learner"],"description":"Their role in your organization"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When they joined (ISO-8601, UTC)"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Last change to this person"}},"required":["id","name","email","role","created_at","updated_at"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/people/{id}/training":{"get":{"operationId":"people.training","summary":"A person's courses with progress, due dates and what's overdue","x-required-scope":"people:read","x-required-scopes":["people:read","enrollments:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"person":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","creator","learner"],"description":"Their role in your organization"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When they joined (ISO-8601, UTC)"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Last change to this person"}},"required":["id","name","email","role","created_at","updated_at"]},"courses":{"type":"array","items":{"type":"object","properties":{"enrollment_id":{"type":"string","minLength":1,"maxLength":128},"course":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string"},"title":{"type":"string"}},"required":["id","slug","title"]},"status":{"type":"string","enum":["active","completed"]},"credited":{"type":"boolean","description":"An admin marked it complete in a flow (never overdue)"},"enrolled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"completed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},{"type":"null"}]},"lessons_completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"due_date":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},{"type":"null"}],"description":"The earliest due date among the assignments behind it that still apply (direct, a group they are still in, or their role). Courses inside a flow branch have no stored due date unless also assigned with one"},"days_overdue":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Days past the due date, rounded (0 = less than half a day), while still active and not credited; null if not overdue"}},"required":["enrollment_id","course","status","credited","enrolled_at","completed_at","lessons_completed","lessons_total","due_date","days_overdue"]},"description":"Overdue first (most late first), then in progress by due date, then completed or credited (latest first). Unassigned courses are left out"},"truncated":{"type":"boolean","description":"true if the person has more than 500 courses and the list was cut short"}},"required":["person","courses","truncated"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/groups":{"get":{"operationId":"groups.list","summary":"List groups: cohorts and Planning Center groups, lists and teams","x-required-scope":"people:read","x-required-scopes":["people:read"],"parameters":[{"name":"q","in":"query","required":false,"description":"Part of the name, any case","schema":{"description":"Part of the name, any case","type":"string","minLength":1,"maxLength":100}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["cohort","pc_group","pc_list","pc_team"]}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"kind":{"type":"string","enum":["cohort","pc_group","pc_list","pc_team"],"description":"`cohort` (made in the app) or a Planning Center group, list or team"},"parent_name":{"description":"Planning Center's group type, service type or list category; null for cohorts","type":["string","null"]},"member_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People in your organization in the group"}},"required":["id","name","kind","parent_name","member_count"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/reports/overdue":{"get":{"operationId":"reports.overdue","summary":"People past a due date on a course they are still taking (and not credited in a flow), most overdue first","x-required-scope":"enrollments:read","x-required-scopes":["enrollments:read","people:read"],"parameters":[{"name":"course_id","in":"query","required":false,"description":"Course id or slug","schema":{"description":"Course id or slug","type":"string","minLength":1,"maxLength":128}},{"name":"flow_id","in":"query","required":false,"description":"Flow id or slug: the flow's courses (see due_date for courses inside branches)","schema":{"description":"Flow id or slug: the flow's courses (see due_date for courses inside branches)","type":"string","minLength":1,"maxLength":128}},{"name":"ministry_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"group_id","in":"query","required":false,"description":"People currently in this group or cohort (see List groups)","schema":{"description":"People currently in this group or cohort (see List groups)","type":"string","minLength":1,"maxLength":128}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"enrollment_id":{"type":"string","minLength":1,"maxLength":128},"person":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"email":{"type":"string"}},"required":["id","name","email"]},"course":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string"},"title":{"type":"string"}},"required":["id","slug","title"]},"due_date":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"The earliest due date among the assignments behind it that still apply (direct, a group they are still in, or their role). Courses inside a flow branch have no stored due date unless also assigned with one"},"days_overdue":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Days late, rounded (0 = less than half a day)"},"enrolled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"lessons_completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["enrollment_id","person","course","due_date","days_overdue","enrolled_at","lessons_completed","lessons_total"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/courses":{"get":{"operationId":"courses.list","summary":"List courses","x-required-scope":"courses:read","x-required-scopes":["courses:read"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","published","archived"]}},{"name":"ministry_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string","description":"Used in course URLs; can replace the id in `/v1/courses/{id}` paths"},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"ministry_id":{"description":"The ministry it belongs to","type":["string","null"]},"enrollment_type":{"type":"string","enum":["open","invite","code"],"description":"How learners get in: anyone, assigned only, or with a code"},"estimated_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Estimated time to complete"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","slug","title","description","status","ministry_id","enrollment_type","estimated_minutes","created_at","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"post":{"operationId":"courses.create","summary":"Create a draft course, optionally with modules and lessons","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"ministry_id":{"description":"Defaults to your default ministry","type":"string","minLength":1,"maxLength":128},"enrollment_type":{"description":"Default `open`","type":"string","enum":["open","invite"]},"outline":{"description":"New modules and their lessons. Without one, the course starts with an empty \"Module 1\". At most 200 lessons","minItems":1,"maxItems":30,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"lessons":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"content":{"type":"string","maxLength":20000,"description":"Markdown: headings, lists, bold, links. HTML is removed."},"task":{"description":"Something the learner does at the end of the lesson","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"acknowledge"},"prompt":{"type":"string","minLength":1,"maxLength":500,"description":"What the learner confirms, e.g. \"I have read the safety policy.\""}},"required":["kind","prompt"]},{"type":"object","properties":{"kind":{"type":"string","const":"quiz"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Graded: each choice question needs exactly one correct option (at least one for multi_select)"}},"required":["kind","questions"]},{"type":"object","properties":{"kind":{"type":"string","const":"reflection"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Not graded"}},"required":["kind","questions"]}]}},"required":["title"]}}},"required":["title","lessons"]}}},"required":["title"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"course":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","const":"draft"}},"required":["id","slug","title","description","status"]},"outline":{"anyOf":[{"type":"object","properties":{"modules_created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons_created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"modules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"}},"required":["id","title"]},"description":"Modules this call created"},"lessons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"module_id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"}},"required":["id","module_id","title"]},"description":"Lessons this call created"}},"required":["modules_created","lessons_created","modules","lessons"]},{"type":"null"}]}},"required":["course","outline"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/courses/{id}":{"get":{"operationId":"courses.get","summary":"Get a course outline (id or slug)","x-required-scope":"courses:read","x-required-scopes":["courses:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"course":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string","description":"Used in course URLs; can replace the id in `/v1/courses/{id}` paths"},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"ministry_id":{"description":"The ministry it belongs to","type":["string","null"]},"enrollment_type":{"type":"string","enum":["open","invite","code"],"description":"How learners get in: anyone, assigned only, or with a code"},"estimated_minutes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Estimated time to complete"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","slug","title","description","status","ministry_id","enrollment_type","estimated_minutes","created_at","updated_at"]},"modules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"lessons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"type":{"type":"string","enum":["video","text","pdf"]},"word_count":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Words in the lesson body; null if it has none"},"task":{"anyOf":[{"type":"string","enum":["quiz","reflection","acknowledge","other"]},{"type":"null"}],"description":"What the learner does at the end, if anything"}},"required":["id","title","type","word_count","task"]}}},"required":["id","title","lessons"]}}},"required":["course","modules"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"patch":{"operationId":"courses.update","summary":"Change a draft course's title or description (id or slug)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"description":"`null` clears it","anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"description":"Send title, description or both"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","const":"draft"}},"required":["id","slug","title","description","status"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/ministries":{"get":{"operationId":"ministries.list","summary":"List active ministries","x-required-scope":"courses:read","x-required-scopes":["courses:read"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"is_default":{"type":"boolean","description":"The ministry new courses go into by default"}},"required":["id","name","slug","description","is_default"]}}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/enrollments":{"get":{"operationId":"enrollments.list","summary":"List enrollments with lesson progress","x-required-scope":"enrollments:read","x-required-scopes":["enrollments:read"],"parameters":[{"name":"course_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"user_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","completed","revoked"]}},{"name":"updated_since","in":"query","required":false,"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","schema":{"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"user_id":{"type":"string","minLength":1,"maxLength":128,"description":"The person (see People)"},"course_id":{"type":"string","minLength":1,"maxLength":128},"status":{"type":"string","enum":["active","completed","revoked"],"description":"revoked = unassigned; progress is kept"},"enrolled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"completed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},{"type":"null"}]},"revoked_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},{"type":"null"}]},"lessons_completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Lessons in the course now"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Last change, including lesson progress (not a change to the course itself)"}},"required":["id","user_id","course_id","status","enrolled_at","completed_at","revoked_at","lessons_completed","lessons_total","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/flows":{"get":{"operationId":"flows.list","summary":"List flows","x-required-scope":"flows:read","x-required-scopes":["flows:read"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","published","archived"]}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"course_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"description":"Course steps in order; branch steps omitted"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","slug","title","description","category","status","course_ids","created_at","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/flows/{id}/assignments":{"get":{"operationId":"flows.assignments","summary":"List a flow's assignments","x-required-scope":"flows:read","x-required-scopes":["flows:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"updated_since","in":"query","required":false,"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","schema":{"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"flow_id":{"type":"string","minLength":1,"maxLength":128},"target_kind":{"type":"string","enum":["user","role","group"],"description":"Which of the target fields below is set"},"target_user_id":{"type":["string","null"]},"target_role":{"anyOf":[{"type":"string","enum":["admin","creator","learner"]},{"type":"null"}]},"target_group_id":{"description":"A Planning Center group or a cohort","type":["string","null"]},"assigned_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","flow_id","target_kind","target_user_id","target_role","target_group_id","assigned_at","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"post":{"operationId":"flows.assign","summary":"Assign a published flow to a person, role or group","x-required-scope":"enrollments:write","x-required-scopes":["enrollments:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"user"},"user_id":{"type":"string","minLength":1,"maxLength":128,"description":"A person in your organization"}},"required":["type","user_id"]},{"type":"object","properties":{"type":{"type":"string","const":"role"},"role":{"type":"string","enum":["admin","creator","learner"],"description":"Everyone with this role when you assign. A course must be assigned again to include people who get the role later; a flow includes them automatically"}},"required":["type","role"]},{"type":"object","properties":{"type":{"type":"string","const":"group"},"group_id":{"type":"string","minLength":1,"maxLength":128,"description":"A Planning Center group or a cohort; members who join later are enrolled too"},"on_member_leaves":{"description":"What happens to someone who leaves the group. Planning Center groups only (cohorts always keep). Default: your organization’s setting on the Planning Center page (`unenroll` unless changed)","type":"string","enum":["keep","unenroll"]}},"required":["type","group_id"]}]},"notify":{"description":"Send emails (default true): the assignment email to people newly enrolled in a course, or the welcome email for a flow, and, when assigning a course to a Planning Center group, an invitation to members without an account. `false` sends none, for bulk backfills.","type":"boolean"}},"required":["target"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"flow_assignment_id":{"type":"string","minLength":1,"maxLength":128},"created":{"type":"boolean","description":"false when this target already had the flow"},"targeted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People the assignment covers"},"newly_enrolled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People newly enrolled, or re-enrolled, in at least one course by this call"}},"required":["flow_assignment_id","created","targeted","newly_enrolled"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/assignments":{"get":{"operationId":"assignments.list","summary":"List course assignments (people, roles and groups a course is assigned to)","x-required-scope":"enrollments:read","x-required-scopes":["enrollments:read"],"parameters":[{"name":"course_id","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"updated_since","in":"query","required":false,"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","schema":{"description":"ISO-8601. Only rows changed at or after this moment, ordered by `updated_at` (see Syncing changes)","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"course_id":{"type":"string","minLength":1,"maxLength":128},"target_kind":{"type":"string","enum":["user","role","group"],"description":"Which of the target fields below is set"},"target_user_id":{"type":["string","null"]},"target_role":{"anyOf":[{"type":"string","enum":["admin","creator","learner"]},{"type":"null"}]},"target_group_id":{"description":"A Planning Center group or a cohort","type":["string","null"]},"due_date":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},{"type":"null"}]},"on_member_leaves":{"type":"string","enum":["keep","unenroll"],"description":"Groups only: what happens to someone who leaves the group"},"assigned_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["id","course_id","target_kind","target_user_id","target_role","target_group_id","due_date","on_member_leaves","assigned_at","updated_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/deletions":{"get":{"operationId":"deletions.list","summary":"Records removed since a moment, so a sync can delete them too (kinds follow your read permissions)","parameters":[{"name":"updated_since","in":"query","required":true,"description":"ISO-8601, required. Deletions are kept for 90 days","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"ISO-8601, required. Deletions are kept for 90 days"}},{"name":"kind","in":"query","required":false,"description":"One kind only. Each kind needs its read permission: person → people:read, course → courses:read, enrollment and assignment → enrollments:read, flow_assignment → flows:read; others come back empty","schema":{"description":"One kind only. Each kind needs its read permission: person → people:read, course → courses:read, enrollment and assignment → enrollments:read, flow_assignment → flows:read; others come back empty","type":"string","enum":["person","course","enrollment","assignment","flow_assignment"]}},{"name":"limit","in":"query","required":false,"description":"1–100, default 50","schema":{"description":"1–100, default 50","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page","schema":{"description":"`next_cursor` from the previous page","type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["person","course","enrollment","assignment","flow_assignment"],"description":"`person` = left your organization or deleted their account"},"id":{"type":"string","description":"The id the record had"},"deleted_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"ISO-8601, UTC"}},"required":["kind","id","deleted_at"]}},"next_cursor":{"description":"null on the last page","type":["string","null"]}},"required":["data","next_cursor"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/courses/{id}/assignments":{"post":{"operationId":"courses.assign","summary":"Assign a published course to a person, role or group","x-required-scope":"enrollments:write","x-required-scopes":["enrollments:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"user"},"user_id":{"type":"string","minLength":1,"maxLength":128,"description":"A person in your organization"}},"required":["type","user_id"]},{"type":"object","properties":{"type":{"type":"string","const":"role"},"role":{"type":"string","enum":["admin","creator","learner"],"description":"Everyone with this role when you assign. A course must be assigned again to include people who get the role later; a flow includes them automatically"}},"required":["type","role"]},{"type":"object","properties":{"type":{"type":"string","const":"group"},"group_id":{"type":"string","minLength":1,"maxLength":128,"description":"A Planning Center group or a cohort; members who join later are enrolled too"},"on_member_leaves":{"description":"What happens to someone who leaves the group. Planning Center groups only (cohorts always keep). Default: your organization’s setting on the Planning Center page (`unenroll` unless changed)","type":"string","enum":["keep","unenroll"]}},"required":["type","group_id"]}]},"due_date":{"description":"YYYY-MM-DD, read as midnight UTC. Leaving it out keeps any existing due date","type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"notify":{"description":"Send emails (default true): the assignment email to people newly enrolled in a course, or the welcome email for a flow, and, when assigning a course to a Planning Center group, an invitation to members without an account. `false` sends none, for bulk backfills.","type":"boolean"}},"required":["target"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"assignment_id":{"type":"string","minLength":1,"maxLength":128},"created":{"type":"boolean","description":"false when this target already had the course"},"due_date_updated":{"type":"boolean"},"enrolled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People newly enrolled"},"reactivated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People brought back after being unassigned"},"unchanged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People who were already enrolled"}},"required":["assignment_id","created","due_date_updated","enrolled","reactivated","unchanged"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/enrollments/{id}/revoke":{"post":{"operationId":"enrollments.revoke","summary":"Revoke an active enrollment (reversible: re-assigning brings the person back)","x-required-scope":"enrollments:write","x-required-scopes":["enrollments:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"status":{"type":"string","const":"revoked"}},"required":["id","status"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/invitations":{"post":{"operationId":"invitations.create","summary":"Invite learners by email (learners only)","x-required-scope":"people:invite","x-required-scopes":["people:invite"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","maxLength":320}},"cohort_id":{"description":"A manual cohort; new invitees join it when they accept. Existing members are not added (assign them instead).","type":"string","minLength":1,"maxLength":128}},"required":["emails"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"outcome":{"type":"string","enum":["invited","already_member","already_invited","over_daily_cap","over_seat_limit","invalid_email"]}},"required":["email","outcome"]}},"invited":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Invitations sent"},"added_to_cohort":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Always 0 over the API: existing members aren’t added to cohorts"}},"required":["results","invited","added_to_cohort"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/courses/{id}/outline":{"post":{"operationId":"courses.outline","summary":"Add modules and lessons to a draft course (id or slug)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"modules":{"minItems":1,"maxItems":30,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"Required, but ignored when `existing_module_id` is set"},"lessons":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"content":{"type":"string","maxLength":20000,"description":"Markdown: headings, lists, bold, links. HTML is removed."},"task":{"description":"Something the learner does at the end of the lesson","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"acknowledge"},"prompt":{"type":"string","minLength":1,"maxLength":500,"description":"What the learner confirms, e.g. \"I have read the safety policy.\""}},"required":["kind","prompt"]},{"type":"object","properties":{"kind":{"type":"string","const":"quiz"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Graded: each choice question needs exactly one correct option (at least one for multi_select)"}},"required":["kind","questions"]},{"type":"object","properties":{"kind":{"type":"string","const":"reflection"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Not graded"}},"required":["kind","questions"]}]}},"required":["title"]}},"existing_module_id":{"description":"Add the lessons to this module of the course instead of creating one","type":"string","minLength":1,"maxLength":128}},"required":["title","lessons"]},"description":"At most 200 lessons per request"}},"required":["modules"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"modules_created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons_created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"modules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"}},"required":["id","title"]},"description":"Modules this call created"},"lessons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"module_id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"}},"required":["id","module_id","title"]},"description":"Lessons this call created"}},"required":["modules_created","lessons_created","modules","lessons"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/courses/{id}/module-order":{"put":{"operationId":"courses.reorderModules","summary":"Reorder a draft course's modules (id or slug)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"module_ids":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"description":"In the new order. Modules you leave out keep their order after these"}},"required":["module_ids"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"modules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","title","position"]}}},"required":["modules"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/modules/{id}":{"patch":{"operationId":"modules.update","summary":"Rename a module (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200}},"required":["title"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","title","position"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/modules/{id}/lessons":{"post":{"operationId":"modules.addLessons","summary":"Add lessons to the end of a module (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lessons":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"content":{"type":"string","maxLength":20000,"description":"Markdown: headings, lists, bold, links. HTML is removed."},"task":{"description":"Something the learner does at the end of the lesson","oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"acknowledge"},"prompt":{"type":"string","minLength":1,"maxLength":500,"description":"What the learner confirms, e.g. \"I have read the safety policy.\""}},"required":["kind","prompt"]},{"type":"object","properties":{"kind":{"type":"string","const":"quiz"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Graded: each choice question needs exactly one correct option (at least one for multi_select)"}},"required":["kind","questions"]},{"type":"object","properties":{"kind":{"type":"string","const":"reflection"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Not graded"}},"required":["kind","questions"]}]}},"required":["title"]},"description":"Text lessons, added after the module’s current lessons. At most 50 per request"}},"required":["lessons"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"lessons_created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"lessons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"module_id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"}},"required":["id","module_id","title"]}}},"required":["lessons_created","lessons"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/modules/{id}/lesson-order":{"put":{"operationId":"modules.reorderLessons","summary":"Reorder a module's lessons (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lesson_ids":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1,"maxLength":128},"description":"In the new order. Lessons you leave out keep their order after these"}},"required":["lesson_ids"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"lessons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","title","position"]}}},"required":["lessons"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/lessons/{id}":{"patch":{"operationId":"lessons.update","summary":"Change a lesson's title or written content (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"content":{"type":"string","maxLength":20000,"description":"Markdown: headings, lists, bold, links. HTML is removed."},"mode":{"description":"`append` adds `content` below the current text. Default `replace`, where empty content clears the lesson. Ignored without `content`","type":"string","enum":["replace","append"]}},"description":"Send title, content or both"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string"},"word_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","title","word_count"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/lessons/{id}/task":{"post":{"operationId":"lessons.addTask","summary":"Add a quiz, reflection or acknowledgement to a lesson (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"acknowledge"},"prompt":{"type":"string","minLength":1,"maxLength":500,"description":"What the learner confirms, e.g. \"I have read the safety policy.\""}},"required":["kind","prompt"]},{"type":"object","properties":{"kind":{"type":"string","const":"quiz"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Graded: each choice question needs exactly one correct option (at least one for multi_select)"}},"required":["kind","questions"]},{"type":"object","properties":{"kind":{"type":"string","const":"reflection"},"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]},"description":"Not graded"}},"required":["kind","questions"]}]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"task_id":{"type":"string","minLength":1,"maxLength":128},"lesson_id":{"type":"string","minLength":1,"maxLength":128},"kind":{"type":"string","enum":["acknowledge","quiz","reflection"]}},"required":["task_id","lesson_id","kind"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/lessons/{id}/questions":{"post":{"operationId":"lessons.addQuestions","summary":"Add questions to a lesson's quiz or reflection (draft courses only)","x-required-scope":"courses:write","x-required-scopes":["courses:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1–100 printable ASCII characters, no spaces. A retry with the same key and body returns the first successful response (for 24 hours) instead of repeating the write; after an error, a retry runs again.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"questions":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["multiple_choice","true_false","multi_select","short_text"],"description":"`short_text` is an open written answer (no options)"},"options":{"default":[],"description":"Answer choices: 2–8 for multiple_choice and multi_select, exactly 2 for true_false, none for short_text. `is_correct` is ignored on reflections, which are never graded","maxItems":8,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":300},"is_correct":{"default":false,"type":"boolean"}},"required":["text"]}}},"required":["question","type"]}}},"required":["questions"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"task_id":{"type":"string","minLength":1,"maxLength":128},"question_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}},"graded":{"type":"boolean"}},"required":["task_id","question_ids","graded"]}},"required":["data"]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_key","key_expired","tenant_suspended","plan_required","insufficient_scope","rate_limited","validation_failed","not_found","method_not_allowed","internal_error","forbidden","not_published","course_not_draft","invalid_json","unsupported_media_type","payload_too_large","idempotency_conflict","idempotency_in_progress"]},"message":{"type":"string"},"details":{},"request_id":{"type":"string"}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}}}}