OAuth2
Scopes
Each scope unlocks specific endpoints. The tables below are what you pass (request) and what you get back (response). Medical and contact data can be submitted on write scopes; it is never returned.
| Scope | Meaning | You pass |
|---|---|---|
camp.read | Read camp name, dates, and public settings | Nothing. Send the bearer token only. |
registration.urls | List registration URLs for groups and sections | Nothing. Send the bearer token only. |
registration.submit | Submit young person or leader registration forms | JSON body: token, type, then the same fields as creating a child or leader. Do not send camp_consent. Comma-separate dietary, allergies, and disabilities. |
children.read | List young people (first name, last initial, id, profile link) | Nothing on the list. Path id only when fetching one record. |
children.write | Create young person records (you submit details; they are not returned) | JSON body of young person fields. Tag lists must be comma-separated (or a JSON array of tags). |
leaders.read | List leaders (first name, last initial, id, profile link) | Nothing on the list. Path id only when fetching one record. |
leaders.write | Create leader records (you submit details; they are not returned) | JSON body of leader fields. Tag lists must be comma-separated (or a JSON array of tags). |
subcamps.read | Read sub-camps, details, and management (staff/patrols without personal data) | Nothing on the list. Path id for details and management. |
modules.read | Read other module data that is not personal (groups, sections, activities, schedule) | Nothing. Send the bearer token only. |
camp.read
Read camp name, dates, and public settings
You pass: Nothing. Send the bearer token only.
Endpoints
GET /camp— Camp name, dates, plan, access codeGET /me— Token metadata plus the same camp object (no extra scope)
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
camp.id | integer | Camp id |
camp.name | string | Camp name |
camp.access_code | string | Camp access code |
camp.status | string | Camp status |
camp.plan | string | Plan type |
camp.arrival_date | string | Arrival date |
camp.departure_date | string | Departure date |
registration.urls
List registration URLs for groups and sections
You pass: Nothing. Send the bearer token only.
Endpoints
GET /registration-urls— Public registration links for groups and sections
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
registration_urls[].id | integer | Row id |
registration_urls[].scout_group_id | integer | Group this link belongs to |
registration_urls[].section_id | integer | Section, or 0 if the link is group-wide |
registration_urls[].type | string | child or leader |
registration_urls[].token | string | Pass this to POST /registrations |
registration_urls[].url | string | Public form URL |
registration.submit
Submit young person or leader registration forms
You pass: JSON body: token, type, then the same fields as creating a child or leader. Do not send camp_consent. Comma-separate dietary, allergies, and disabilities.
Endpoints
POST /registrations— Submit a young person or leader registration form
Request
| Field | Type | Required | Notes |
|---|---|---|---|
token | string | Yes | Token from GET /registration-urls (the path segment, not the full URL) |
type | child | leader | Yes | Must match the token type |
| — young person fields — | No | When type is child, also send the children.write body (scout_group_id / section_id are taken from the token) | |
| — leader fields — | No | When type is leader, also send the leaders.write body |
Response
| Field | Type | Notes |
|---|---|---|
ok | boolean | true on success |
type | string | child or leader |
registration | object | Privacy-safe person object (same as a GET). Submitted medical and contact data is not echoed |
consent_pending | boolean | true. Camp consent is collected by email, not via OAuth2 |
consent_emails_sent | boolean | Whether the permission slip and signature emails were sent to the primary contact |
children.read
List young people (first name, last initial, id, profile link)
You pass: Nothing on the list. Path id only when fetching one record.
Endpoints
GET /children— List young peopleGET /children/:id— One young person
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
id | integer | Internal record id |
first_name | string | Given name only |
last_initial | string | First letter of surname. Full last names are never returned |
profile_url | string | Public profile / QR link |
scout_group_id | integer | Scout group id |
section_id | integer | Section id |
camp_status | string | On-camp status if the module is in use |
children.write
Create young person records (you submit details; they are not returned)
You pass: JSON body of young person fields. Tag lists must be comma-separated (or a JSON array of tags).
Endpoints
POST /children— Create a young person
Request
| Field | Type | Required | Notes |
|---|---|---|---|
first_name | string | Yes | Given name |
last_name | string | Yes | Full surname is stored. Reads only return the initial |
dob | string (YYYY-MM-DD) | Yes | Date of birth |
section_id | integer | Yes | From GET /sections |
scout_group_id | integer | Yes | From GET /groups. Ignored on registration.submit (taken from the token) |
emergency_name | string | Yes | Primary emergency contact name |
emergency_phone | string | Yes | Primary emergency contact phone |
emergency_email | string | Yes | Primary contact email. The permission slip and a separate signature request are sent here |
emergency_2_name | string | No | Second emergency contact name |
emergency_2_phone | string | No | Second emergency contact phone |
emergency_2_email | string | No | Second emergency contact email |
camp_consent | string | No | Not accepted. If sent, the request is rejected. The primary contact signs by email after submit |
photography_consent | YES | NO | No | Defaults to NO |
dietary | comma-separated tags | string[] | No | Dietary requirements. Alias: dietary_requirements |
allergies | comma-separated tags | string[] | No | Allergies. Alias: allergy |
health_other | comma-separated tags | string[] | No | Disabilities and other conditions. Aliases: disabilities, conditions, medical_conditions |
medical_info | string | No | Medication / treatment notes. Free text, not a tag list |
infectious_contact | string | No | Recent infectious disease contact notes |
notes_other | string | No | Other notes |
shooting_medical | string | No | Shooting medical notes if relevant |
line_1 | string | No | Address line 1 |
line_2 | string | No | Address line 2 |
city | string | No | Town or city |
county | string | No | County |
postcode | string | No | Postcode |
doctor_name | string | No | GP name |
doctor_surgery | string | No | GP surgery |
doctor_address | string | No | GP address |
doctor_phone | string | No | GP phone |
doctor_email | string | No | GP email |
otc_pain_relief_consent | YES | NO | No | Over-the-counter pain relief consent |
parent_alert_email | boolean | No | Whether to email the parent on medical incidents |
has_asthma | boolean | No | Pass 1, true, or "yes". Same pattern for the flags below |
has_diabetes | boolean | No | Diabetes flag |
has_epilepsy | boolean | No | Epilepsy flag |
has_migraines | boolean | No | Migraines flag |
has_fits_faints | boolean | No | Fits or faints flag |
can_swim_50m | boolean | No | Can swim 50 metres |
can_bathe_supervised | boolean | No | Can bathe when supervised |
shooting_air_rifle | boolean | No | Also: shooting_small_bore, shooting_full_bore, shooting_clay_pigeon, shooting_crossbow, shooting_target_sprint, shooting_muzzle_loaded |
Response
| Field | Type | Notes |
|---|---|---|
ok | boolean | true on success |
consent_pending | boolean | true. Camp consent is collected by email, not via OAuth2 |
consent_emails_sent | boolean | Whether the permission slip and signature emails were sent |
child.id | integer | Internal record id |
child.first_name | string | Given name only |
child.last_initial | string | First letter of surname. Full last names are never returned |
child.profile_url | string | Public profile / QR link |
child.scout_group_id | integer | Scout group id |
child.section_id | integer | Section id |
child.camp_status | string | On-camp status if the module is in use |
leaders.read
List leaders (first name, last initial, id, profile link)
You pass: Nothing on the list. Path id only when fetching one record.
Endpoints
GET /leaders— List leadersGET /leaders/:id— One leader
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
id | integer | Internal record id |
first_name | string | Given name only |
last_initial | string | First letter of surname. Full last names are never returned |
profile_url | string | Public profile / QR link |
scout_group_id | integer | Scout group id |
section_id | integer | Section id |
camp_status | string | On-camp status if the module is in use |
role | string | Leader role title |
leaders.write
Create leader records (you submit details; they are not returned)
You pass: JSON body of leader fields. Tag lists must be comma-separated (or a JSON array of tags).
Endpoints
POST /leaders— Create a leader
Request
| Field | Type | Required | Notes |
|---|---|---|---|
first_name | string | Yes | Given name |
last_name | string | Yes | Full surname is stored. Reads only return the initial |
email | string | Yes | Must be unique on the camp |
dob | string (YYYY-MM-DD) | Yes | Date of birth |
section_id | integer | Yes | Alias: section. From GET /sections |
scout_group_id | integer | Yes | Alias: scout_group. Ignored on registration.submit |
camp_consent | string | No | Not accepted. If sent, the request is rejected. The leader is emailed the permission slip and a separate signature request |
role | string | No | Defaults to Leader |
level | integer | No | Permission level. Defaults to 1 |
password | string | No | Optional login password. Must meet camp password rules if set |
phone | string | No | Leader phone |
photography_consent | YES | NO | No | Defaults to NO |
dietary | comma-separated tags | string[] | No | Dietary requirements. Alias: dietary_requirements |
allergies | comma-separated tags | string[] | No | Allergies. Alias: allergy |
medical_info | string | No | Medication / treatment notes. Free text |
emergency_name | string | No | Emergency contact name |
emergency_phone | string | No | Emergency contact phone |
emergency_email | string | No | Emergency contact email |
line_1 | string | No | Address line 1 |
line_2 | string | No | Address line 2 |
city | string | No | Town or city |
county | string | No | County |
postcode | string | No | Postcode |
otc_pain_relief_consent | YES | NO | No | Over-the-counter pain relief consent |
Response
| Field | Type | Notes |
|---|---|---|
ok | boolean | true on success |
consent_pending | boolean | true. Camp consent is collected by email, not via OAuth2 |
consent_emails_sent | boolean | Whether the permission slip and signature emails were sent |
leader.id | integer | Internal record id |
leader.first_name | string | Given name only |
leader.last_initial | string | First letter of surname. Full last names are never returned |
leader.profile_url | string | Public profile / QR link |
leader.scout_group_id | integer | Scout group id |
leader.section_id | integer | Section id |
leader.camp_status | string | On-camp status if the module is in use |
leader.role | string | Leader role title |
subcamps.read
Read sub-camps, details, and management (staff/patrols without personal data)
You pass: Nothing on the list. Path id for details and management.
Endpoints
GET /subcamps— Sub-camp listGET /subcamps/:id— One sub-campGET /subcamps/:id/management— Patrols and staff without contact details
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
subcamps[].id | integer | Sub-camp id |
subcamps[].name | string | Name |
subcamps[].code | string | Short code |
subcamps[].color | string | Display colour |
subcamps[].map_x / map_y | number | Map position |
subcamps[].patrol_capacity | integer | Patrol capacity |
management.patrols[].members[].child_id | integer | Young person id only — no names on membership rows |
management.staff[].leader_id | integer | Staff leader id |
management.staff[].first_name / last_initial | string | Privacy-safe staff names |
management.staff[].role | string | Staff role on that sub-camp |
modules.read
Read other module data that is not personal (groups, sections, activities, schedule)
You pass: Nothing. Send the bearer token only.
Endpoints
GET /groups— Scout groupsGET /sections— SectionsGET /activities— ActivitiesGET /schedule— Programme sessions and scheduled activitiesGET /kit-lists— Kit list templates
Request
No body fields. Authenticate with Authorization: Bearer only.
Response
| Field | Type | Notes |
|---|---|---|
groups[].id / name | integer / string | Scout group |
groups[].registration_open | boolean | Whether that group is accepting registrations |
sections[].id / name | integer / string | Section |
sections[].child_registration_enabled | boolean | Whether young people can register into the section |
activities[].id / name / type | mixed | Activity catalogue |
activities[].slot_cost | integer | Programme slot cost |
activities[].is_swim / is_gun | boolean | Swim or shooting activity flags |
sessions[] | object | id, day_name, session_date, sort_order |
scheduled_activities[].young_people_count | integer | Headcount only — no child names |
scheduled_activities[].leaders[] | object | id, first_name, last_initial |
kit_lists[].id / name / event_type / is_active | mixed | Template metadata, not packed-kit personal data |