{"openapi":"3.0.3","info":{"title":"OS Digital Education Research Assessment Portal REST API","version":"1.4.0.1","description":"Integrate learning management systems, student information systems, portals and scripts with the Research Assessment Portal. Authenticate with an API key created by the Super Admin (Integrations \u0026 API)."},"servers":[{"url":"https://rapp.simdols.com/api/v1"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"tags":[{"name":"System"},{"name":"Academic structure"},{"name":"Students"},{"name":"Staff"},{"name":"Projects"},{"name":"Events"},{"name":"Synchronisation"}],"paths":{"/ping":{"get":{"tags":["System"],"summary":"Check the key","operationId":"get_ping","description":"Returns the portal name and version and the key's scopes. Use it to test a new key.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Ping"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/departments":{"get":{"tags":["Academic structure"],"summary":"List departments","operationId":"get_departments","description":"Required scope: `read:academic`.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Department"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/programmes":{"get":{"tags":["Academic structure"],"summary":"List programmes","operationId":"get_programmes","description":"Each programme with its department, degree level and default research workflow.\n\nRequired scope: `read:academic`.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Programme"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/sessions":{"get":{"tags":["Academic structure"],"summary":"List academic sessions","operationId":"get_sessions","description":"Required scope: `read:academic`.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Session"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/workflows":{"get":{"tags":["Academic structure"],"summary":"List research workflows","operationId":"get_workflows","description":"Workflows (stage sets) with their stages in order.\n\nRequired scope: `read:academic`.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Workflow"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/students":{"get":{"tags":["Students"],"summary":"List students","operationId":"get_students","description":"Paginated. Filter with the query parameters; combine updated_since with your last sync time for incremental syncs.\n\nRequired scope: `read:students`.","parameters":[{"name":"page","in":"query","required":false,"description":"Page number (default 1)","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–200 (default 50)","schema":{"type":"integer"}},{"name":"q","in":"query","required":false,"description":"Search name, e-mail or ID number","schema":{"type":"string"}},{"name":"email","in":"query","required":false,"description":"Exact e-mail address","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"pending, active, suspended or deactivated","schema":{"type":"string"}},{"name":"department","in":"query","required":false,"description":"Department code","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"Only records changed since this ISO 8601 date/time","schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"description":"ID in a connected system","schema":{"type":"string"}},{"name":"connection","in":"query","required":false,"description":"Connection key (with external_id)","schema":{"type":"string"}},{"name":"matric_number","in":"query","required":false,"description":"Exact student ID","schema":{"type":"string"}},{"name":"programme","in":"query","required":false,"description":"Programme code","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Student"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Students"],"summary":"Create a student","operationId":"post_students","description":"Required: matric_number, first_name, last_name, email. Use department_code / programme_code / entry_session instead of ids if you prefer. activation: none (pending, default), invite or default_password. Send external_id + connection to link the account to a connected system.\n\nRequired scope: `write:students`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentInput"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Student"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/students/{id}":{"get":{"tags":["Students"],"summary":"Get a student","operationId":"get_students_id","description":"Includes the student's projects.\n\nRequired scope: `read:students`.","parameters":[{"name":"id","in":"path","required":true,"description":"Portal ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Student"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Students"],"summary":"Update a student","operationId":"patch_students_id","description":"Partial update: only the fields you send change. status may be active, suspended or deactivated. POST to the same URL also works.\n\nRequired scope: `write:students`.","parameters":[{"name":"id","in":"path","required":true,"description":"Portal ID","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentInput"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Student"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/staff":{"get":{"tags":["Staff"],"summary":"List supervisors / staff","operationId":"get_staff","description":"Paginated.\n\nRequired scope: `read:staff`.","parameters":[{"name":"page","in":"query","required":false,"description":"Page number (default 1)","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–200 (default 50)","schema":{"type":"integer"}},{"name":"q","in":"query","required":false,"description":"Search name, e-mail or ID number","schema":{"type":"string"}},{"name":"email","in":"query","required":false,"description":"Exact e-mail address","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"pending, active, suspended or deactivated","schema":{"type":"string"}},{"name":"department","in":"query","required":false,"description":"Department code","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"Only records changed since this ISO 8601 date/time","schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"description":"ID in a connected system","schema":{"type":"string"}},{"name":"connection","in":"query","required":false,"description":"Connection key (with external_id)","schema":{"type":"string"}},{"name":"staff_number","in":"query","required":false,"description":"Exact staff ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Staff"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Staff"],"summary":"Create a supervisor","operationId":"post_staff","description":"Required: staff_number, first_name, last_name, email. Administrator roles cannot be granted through the API.\n\nRequired scope: `write:staff`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffInput"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Staff"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/staff/{id}":{"get":{"tags":["Staff"],"summary":"Get a staff member","operationId":"get_staff_id","description":"Includes the projects they supervise.\n\nRequired scope: `read:staff`.","parameters":[{"name":"id","in":"path","required":true,"description":"Portal ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Staff"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Staff"],"summary":"Update a supervisor","operationId":"patch_staff_id","description":"Partial update. POST to the same URL also works.\n\nRequired scope: `write:staff`.","parameters":[{"name":"id","in":"path","required":true,"description":"Portal ID","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffInput"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Staff"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/projects":{"get":{"tags":["Projects"],"summary":"List research projects","operationId":"get_projects","description":"Paginated.\n\nRequired scope: `read:projects`.","parameters":[{"name":"page","in":"query","required":false,"description":"Page number (default 1)","schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1–200 (default 50)","schema":{"type":"integer"}},{"name":"student_id","in":"query","required":false,"description":"Student (owner or group member)","schema":{"type":"integer"}},{"name":"matric_number","in":"query","required":false,"description":"Student ID of the owner","schema":{"type":"string"}},{"name":"supervisor_id","in":"query","required":false,"description":"Current supervisor","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"topic_development, in_progress, awaiting_review, awaiting_revision, awaiting_approval, completed, suspended, archived","schema":{"type":"string"}},{"name":"programme","in":"query","required":false,"description":"Programme code","schema":{"type":"string"}},{"name":"session","in":"query","required":false,"description":"Academic session name","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"ISO 8601 date/time","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Projects"],"summary":"Create a project","operationId":"post_projects","description":"Required: student_id or matric_number, and lead_supervisor_id or lead_staff_number. Optional: programme_id / programme_code (defaults to the student's programme), session_id / session, co_supervisor_ids / co_staff_numbers, submission_deadline.\n\nRequired scope: `write:projects`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInput"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Project"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/projects/{id}":{"get":{"tags":["Projects"],"summary":"Get a project","operationId":"get_projects_id","description":"With members, milestones, submissions (metadata only — documents are not exposed) and grades.\n\nRequired scope: `read:projects`.","parameters":[{"name":"id","in":"path","required":true,"description":"Portal ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Project"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/events":{"get":{"tags":["Events"],"summary":"Activity feed","operationId":"get_events","description":"Research events in order. Poll with since_id = meta.next_since_id from the previous call. The same events can be pushed to you as webhooks.\n\nRequired scope: `read:events`.","parameters":[{"name":"since_id","in":"query","required":false,"description":"Return events after this id (default 0)","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"1–200 (default 100)","schema":{"type":"integer"}},{"name":"event","in":"query","required":false,"description":"Comma-separated event names","schema":{"type":"string"}},{"name":"project_id","in":"query","required":false,"description":"Only this project","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/sync/{key}/students":{"post":{"tags":["Synchronisation"],"summary":"Push student records","operationId":"post_sync_key_students","description":"Send records in your own format: they are converted with the connection's field mappings, matched (link → student ID → e-mail), updated, linked or created. Body: a JSON array or {\"records\": [...], \"dry_run\": false}. At most 5000 records per call.\n\nRequired scope: `sync`.","parameters":[{"name":"key","in":"path","required":true,"description":"Connection key","schema":{"type":"string"}},{"name":"dry_run","in":"query","required":false,"description":"Preview without saving","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncInput"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SyncResult"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/sync/{key}/staff":{"post":{"tags":["Synchronisation"],"summary":"Push staff records","operationId":"post_sync_key_staff","description":"As above, with the staff field mappings.\n\nRequired scope: `sync`.","parameters":[{"name":"key","in":"path","required":true,"description":"Connection key","schema":{"type":"string"}},{"name":"dry_run","in":"query","required":false,"description":"Preview without saving","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncInput"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SyncResult"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Authorization: Bearer rap_…"},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"message":{"type":"string"},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"Meta":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"},"pages":{"type":"integer"}}},"Ping":{"type":"object","properties":{"portal":{"type":"string"},"version":{"type":"string"},"api_version":{"type":"string"},"time":{"type":"string"},"key":{"type":"object","properties":{"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["read:academic","read:students","write:students","read:staff","write:staff","read:projects","write:projects","read:events","sync"]}}}}}},"Department":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":"string"},"name":{"type":"string"},"faculty":{"type":"string","nullable":true},"is_active":{"type":"boolean"}}},"Programme":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":"string"},"name":{"type":"string"},"research_type":{"type":"string"},"degree_level":{"type":"string","nullable":true},"department":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"}}},"workflow":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"is_active":{"type":"boolean"}}},"Session":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"starts_on":{"type":"string"},"ends_on":{"type":"string"},"submission_deadline":{"type":"string","nullable":true},"is_current":{"type":"boolean"}}},"Workflow":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"stages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"order":{"type":"integer"},"default_duration_days":{"type":"integer"}}}}}},"Student":{"type":"object","properties":{"matric_number":{"type":"string"},"id":{"type":"integer"},"title":{"type":"string","nullable":true},"first_name":{"type":"string"},"last_name":{"type":"string"},"other_names":{"type":"string","nullable":true},"email":{"type":"string"},"phone":{"type":"string","nullable":true},"status":{"type":"string","enum":["pending","active","suspended","deactivated"]},"department":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"external_ids":{"type":"array","items":{"type":"object","properties":{"connection":{"type":"string"},"external_id":{"type":"string"}}}},"last_login_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"updated_at":{"type":"string"},"programme":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"entry_session":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"custom_workflow":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"managed_by":{"type":"integer","nullable":true}}},"Staff":{"type":"object","properties":{"staff_number":{"type":"string"},"id":{"type":"integer"},"title":{"type":"string","nullable":true},"first_name":{"type":"string"},"last_name":{"type":"string"},"other_names":{"type":"string","nullable":true},"email":{"type":"string"},"phone":{"type":"string","nullable":true},"status":{"type":"string","enum":["pending","active","suspended","deactivated"]},"department":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"external_ids":{"type":"array","items":{"type":"object","properties":{"connection":{"type":"string"},"external_id":{"type":"string"}}}},"last_login_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"updated_at":{"type":"string"},"designation":{"type":"string","nullable":true},"specialisation":{"type":"string","nullable":true},"max_supervisees":{"type":"integer","nullable":true},"active_projects":{"type":"integer"},"roles":{"type":"array","items":{"type":"string"}}}},"StudentInput":{"type":"object","properties":{"matric_number":{"type":"string"},"title":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"other_names":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"department_id":{"type":"integer"},"department_code":{"type":"string"},"status":{"type":"string"},"external_id":{"type":"string"},"connection":{"type":"string"},"programme_id":{"type":"integer"},"programme_code":{"type":"string"},"entry_session_id":{"type":"integer"},"entry_session":{"type":"string"},"activation":{"type":"string","enum":["none","invite","default_password"]}},"example":{"matric_number":"CSC/2026/0101","first_name":"Ngozi","last_name":"Okafor","email":"ngozi.okafor@student.example.edu","programme_code":"MSC-CSC","activation":"invite"}},"StaffInput":{"type":"object","properties":{"staff_number":{"type":"string"},"title":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"other_names":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"department_id":{"type":"integer"},"department_code":{"type":"string"},"status":{"type":"string"},"external_id":{"type":"string"},"connection":{"type":"string"},"designation":{"type":"string"},"specialisation":{"type":"string"},"max_supervisees":{"type":"integer"},"activation":{"type":"string","enum":["none","invite","default_password"]}}},"ProjectInput":{"type":"object","properties":{"student_id":{"type":"integer"},"matric_number":{"type":"string"},"lead_supervisor_id":{"type":"integer"},"lead_staff_number":{"type":"string"},"co_supervisor_ids":{"type":"array","items":{"type":"integer"}},"co_staff_numbers":{"type":"array","items":{"type":"string"}},"programme_id":{"type":"integer"},"programme_code":{"type":"string"},"session_id":{"type":"integer"},"session":{"type":"string"},"submission_deadline":{"type":"string","format":"date"}}},"Project":{"type":"object","properties":{"id":{"type":"integer"},"reference":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"status":{"type":"string"},"is_group":{"type":"boolean"},"student":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"matric_number":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}}},"programme":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"session":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"workflow":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"source":{"type":"string"}}},"current_stage":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"supervisors":{"type":"array","items":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"staff_number":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"}}}},"milestones":{"type":"array","items":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"},"stage_code":{"type":"string"},"due_date":{"type":"string"},"status":{"type":"string"},"approved_at":{"type":"string"}}}},"submissions":{"type":"array","items":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"title":{"type":"string"},"stage_code":{"type":"string"},"status":{"type":"string"},"versions":{"type":"string"},"created_at":{"type":"string"}}}},"grades":{"type":"array","items":{"type":"object","nullable":true,"properties":{"student_id":{"type":"string"},"supervisor_id":{"type":"string"},"score":{"type":"string"},"recorded_at":{"type":"string"}}}},"submission_deadline":{"type":"string","nullable":true},"completed_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"Event":{"type":"object","properties":{"id":{"type":"integer"},"event":{"type":"string","enum":["project.created","project.status","project.completed","project.workflow_changed","supervisor.assigned","supervisor.removed","supervisor.lead_changed","topic.submitted","topic.approved","topic.assigned","topic.rejected","topic.revision_requested","stage.started","stage.approved","submission.uploaded","submission.resubmitted","submission.rejected","review.completed","corrections.requested","final.approved","milestone.approved","milestone.updated","grade.recorded","group.member_added","group.member_removed"]},"summary":{"type":"string"},"occurred_at":{"type":"string"},"project":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"reference":{"type":"string"},"student_id":{"type":"string"}}},"actor":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"subject":{"type":"object","nullable":true,"properties":{"type":{"type":"string"},"id":{"type":"string"}}}}},"SyncInput":{"type":"object","properties":{"records":{"type":"array","items":{"type":"object","additionalProperties":true}},"dry_run":{"type":"boolean"}},"example":{"records":[{"id":"10045","matric_no":"CSC/2026/0101","firstname":"Ngozi","surname":"Okafor","email":"ngozi.okafor@student.example.edu","programme":"MSC-CSC"}]}},"SyncResult":{"type":"object","properties":{"connection":{"type":"string"},"entity":{"type":"string"},"dry_run":{"type":"boolean"},"run_id":{"type":"integer","nullable":true},"summary":{"type":"object","properties":{"total":{"type":"integer"},"created":{"type":"integer"},"updated":{"type":"integer"},"linked":{"type":"integer"},"unchanged":{"type":"integer"},"skipped":{"type":"integer"},"errors":{"type":"integer"}}},"results":{"type":"array","items":{"type":"object","properties":{"n":{"type":"integer"},"external_id":{"type":"string"},"name":{"type":"string"},"action":{"type":"string","enum":["created","updated","linked","unchanged","skipped","error"]},"message":{"type":"string"},"user_id":{"type":"integer","nullable":true}}}}}}}}}