App platform API

Learn more about the App platform project.

SpotTheSplat API v2.3

Base URL: https://spotthesplat.fly.dev/api/v2

Authentication

All endpoints require the X-API-Key header unless marked as public.

Header: X-API-Key: your-api-key

Core

Platform health, organisations, activities, and user management.

GET/health/Health check

Returns service status. Use to verify the API is running.

GET/organisations/List organisations

Returns all organisations registered on the platform with name, subdomain, and branding.

GET/activities/List activities

Returns app instances (activities) for organisations. Each activity links an app to an organisation.

ParameterTypeRequiredDescription
orgstringNoFilter by organisation subdomain
GET/user/Check user exists

Check if a Django user account exists for the given email address.

ParameterTypeRequiredDescription
emailstringYesEmail address to look up

Authentication

Social sign-in flows for mobile apps and WordPress plugins. Google and Apple are supported; Facebook is planned.

POST/auth/google/mobile/Google mobile sign-inPublic

Exchange a Google ID token (from native Google Sign-In) for an opaque bearer session token. The token is returned alongside the member's profile and organisation.

ParameterTypeRequiredDescription
id_tokenstringYesGoogle ID token from the mobile SDK
POST/auth/apple/mobile/Apple mobile sign-inPublic

Exchange an Apple identity token (from ASAuthorizationAppleIDCredential) for a bearer session token. Audience must match the app's bundle ID.

ParameterTypeRequiredDescription
identity_tokenstringYesApple identity token JWT from the iOS SDK
first_namestringNoFirst name (Apple only provides this on first sign-in)
last_namestringNoLast name (Apple only provides this on first sign-in)
GET/auth/apple/web/start/Apple web sign-in (start)Public

Redirects the browser to Apple's authorize URL. Used by WordPress plugins to initiate Sign in with Apple. Apple POSTs back to the callback endpoint.

ParameterTypeRequiredDescription
return_tostringYesHTTPS URL to redirect back to after Apple auth (e.g. the WP callback page)
POST/auth/apple/web/Apple web sign-in (callback)Public

Receives Apple's form_post callback with an authorization code + state. Exchanges the code for tokens, verifies the ID token, finds the member, and redirects back to the return_to URL with a signed payload (ok, email, expires, sig). If the member is not found, ok=false and apple_sub is included for linking.

ParameterTypeRequiredDescription
codestringYesAuthorization code from Apple (form-posted)
statestringYesHMAC-signed state containing the return URL (form-posted)
POST/auth/apple/link/start/Apple link account (start)Public
GET/auth/apple/link/verify/Apple link account (verify)Public

Members

Member directory and verification for SSO-protected content.

GET/members/List all members

Returns all active members with name, email, mobile, member type, access role, and organisation.

GET/members/verify/Verify membership

Checks if an email belongs to an active member. Used by WordPress plugins to gate content behind Google SSO.

ParameterTypeRequiredDescription
emailstringYesEmail address to verify

Groups & Positions

Member groups (committees, teams), organisational positions (President, Secretary), and year-scoped assignments. Used for access control, leadership displays, and committee listings.

GET/groups/List groups

Returns all active member groups for the organisation.

GET/groups/{id}/members/Group members

Returns members of a group for a given year, including ongoing (year-less) memberships. Includes role_label for each member.

ParameterTypeRequiredDescription
idintegerYesGroup ID
yearstringNoOrgYear label (e.g. '2025-26') or 'current' (default)
GET/groups/{id}/team/Group team with positions

Returns group members enriched with their position assignments. Members are derived from both explicit MemberGroupMembership and PositionAssignments where the position is scoped to this group. Sorted by position display_order. Also returns all OrgYears for a year picker.

ParameterTypeRequiredDescription
idintegerYesGroup ID
yearstringNoOrgYear label or 'current' (default)
GET/groups/all-teams/All groups with teams

Returns every active group for the organisation, each with its members and positions for the given year. Groups sorted by display_order; members within each group sorted by position display_order then last name. Designed for committee overview pages.

ParameterTypeRequiredDescription
yearstringNoOrgYear label or 'current' (default)
orgintegerNoOrganisation ID (required when using the global API key)
GET/officers/Current officers

Returns all positions for the organisation with their current holders. Designed for 'Meet the Team' displays. Positions are ordered by display_order.

ParameterTypeRequiredDescription
yearstringNoOrgYear label or 'current' (default)

Notices

Organisation announcements and events with date-ranged visibility.

GET/notices/List active notices

Returns notices currently within their visibility window. Includes title, description, event date/time, price, contact details, and access level.

GET/notices/{id}/qr/Notice QR code

Returns a QR code PNG image encoding the notice's website URL.

ParameterTypeRequiredDescription
idintegerYesNotice ID

Calendar

ICS calendar feed integration for club/organisation calendars.

GET/calendar/events/Get calendar events

Fetches and parses the ICS feed configured for the given activity. Returns events with name, start, end, location, description, and access level.

ParameterTypeRequiredDescription
activity_idintegerYesActivity ID with calendar config

Events

Organisation events with maps, QR codes, and per-event access control.

GET/events/List events

Returns published events with date, time, location, description, website, QR code URL, and access level.

ParameterTypeRequiredDescription
orgstringNoFilter by organisation subdomain
upcomingbooleanNoSet to 'true' to show only future events
GET/events/{id}/qr/Event QR codePublic

Returns a QR code PNG image encoding the event's website URL.

ParameterTypeRequiredDescription
idintegerYesEvent ID

Breakfast

Breakfast meeting RSVP system with choice selection, guest bookings, and reports.

GET/breakfast/events/Next breakfast eventPublic

Returns the next upcoming breakfast event with title, date, time, and location.

POST/breakfast/submit/Submit breakfast bookingPublic

Submit a breakfast choice for an event. Validates the choice code.

ParameterTypeRequiredDescription
event_idintegerYesBreakfast event ID
emailstringYesMember email
breakfast_choicestringYesChoice code: full, continental, bacon, none, apology
GET/breakfast/{org_slug}/current/Current breakfast status

Returns the current breakfast activity for the organisation, including deadline and the member's latest choice.

ParameterTypeRequiredDescription
org_slugstringYesOrganisation subdomain
emailstringYesMember email
POST/breakfast/{org_slug}/{activity_id}/submit/Submit or update choice

Submit or change a breakfast choice. Validates deadline, normalises choice codes, supports guest bookings.

ParameterTypeRequiredDescription
org_slugstringYesOrganisation subdomain
activity_idintegerYesActivity ID
emailstringYesMember email
breakfast_choicestringYesChoice code
bringing_guestbooleanNoSet to true if bringing a guest
guest_first_namestringNoGuest first name
guest_last_namestringNoGuest last name
guest_breakfast_choicestringNoGuest choice code
GET/breakfast/{org_slug}/{activity_id}/report/Breakfast attendance report

Full attendance report listing all members with their choices and summary totals.

ParameterTypeRequiredDescription
org_slugstringYesOrganisation subdomain
activity_idintegerYesActivity ID

Charities & Funders

Directory of charities and grant funders, filterable by UK county.

GET/charities/List charities

Returns charities with Charity Commission data, income, contact details, areas served, and tags.

ParameterTypeRequiredDescription
countystringNoUK county code (e.g. bedfordshire)
orgstringNoFilter by organisation subdomain
tagstringNoFilter by tag (e.g. homelessness)
searchstringNoSearch name, description, and address
GET/funders/List funders

Returns grant funders with type, geographic focus, grant range, eligibility, and how to apply.

ParameterTypeRequiredDescription
countystringNoUK county code
orgstringNoFilter by organisation subdomain
searchstringNoSearch name, notes, and eligibility

Alpaca Portfolio

Alpaca paper/live trading portfolio for club investment activities. Data is server-cached for 5 minutes per activity.

GET/alpaca/{activity_id}/Portfolio snapshot

Returns the cached Alpaca portfolio for an activity: account summary (equity, cash, buying power), open positions, recent orders (last 10), and intraday portfolio history (5-min intervals). Refreshes from Alpaca if the cache is older than 5 minutes. Respects per-member access control via ActivityMemberAccess and ActivityGroupAccess.

ParameterTypeRequiredDescription
activity_idintegerYesActivity ID (must be an Alpaca Portfolio activity with credentials configured)
member_emailstringNoMember email for access check (used by WP plugins; mobile apps use the Bearer token instead)

QuickBooks Online

Integration with QuickBooks Online for bank balances and balance sheet. Requires OAuth2 connection per organisation.

GET/qbo/connect/Connect to QuickBooks (OAuth start)Public

Initiates the QBO OAuth2 flow. Redirects the browser to Intuit's authorisation page. The organisation must have a QboConnection with Client ID and Secret configured in Django admin first.

ParameterTypeRequiredDescription
orgintegerYesOrganisation ID
GET/qbo/callback/QuickBooks OAuth callbackPublic

Intuit redirects here after authorisation. Exchanges the authorisation code for access and refresh tokens, stores the realm_id (QBO Company ID), and confirms the connection.

ParameterTypeRequiredDescription
codestringYesAuthorisation code from Intuit
statestringYesHMAC-signed state for CSRF protection
realmIdstringYesQBO Company ID
GET/qbo/{org_id}/summary/Finance summary

Returns cached bank account balances and a simplified balance sheet (one level deep with sub-sections). Data is refreshed from QBO if the cache is older than 5 minutes. Access tokens are auto-refreshed if expired.

ParameterTypeRequiredDescription
org_idintegerYesOrganisation ID (must have a connected QboConnection)

Audit

User action logs, model change logs, web sign-in tracking, and member platform access summary.

GET/audit/actions/Action logs

Returns custom action logs (sign-ins, page views, connections) for the organisation. Paginated with limit and offset.

ParameterTypeRequiredDescription
orgintegerNoOrganisation ID (required when using the global API key)
limitintegerNoMax results (default 50, max 200)
offsetintegerNoPagination offset (default 0)
GET/audit/changes/Model change logs

Returns django-auditlog model change logs (create/update/delete) with field-level old and new values. Paginated.

ParameterTypeRequiredDescription
orgintegerNoOrganisation ID (required when using the global API key)
limitintegerNoMax results (default 50, max 200)
offsetintegerNoPagination offset (default 0)
GET/audit/web-signin/Track web sign-in

Called by the WordPress plugin after a successful sign-in to record web platform access for audit tracking.

ParameterTypeRequiredDescription
emailstringYesThe signed-in member's email address
GET/audit/member-access/Member platform access

Returns all active members with their platform access status (web, iOS, Android) and counts. Used by the Member Access summary table.

ParameterTypeRequiredDescription
orgintegerNoOrganisation ID (required when using the global API key)

Communications

Channel-agnostic message dispatch system. Email channel working via Resend; push, WhatsApp, and SMS channels planned.

POST/comms/send/Send message

Compose and immediately dispatch a message to all org members, a group, or explicit recipients via the specified channel. Per-org API key required.

ParameterTypeRequiredDescription
channelstringYesChannel type: email, push, whatsapp, or sms
subjectstringNoEmail subject or push notification title
bodystringYesMessage body (HTML for email, plain text for push/SMS)
body_plainstringNoPlain text fallback for email
target_all_membersbooleanNoSend to all active members (default false)
target_group_idintegerNoSend to members of this group
source_appstringNoWhich app triggered the message (e.g. breakfast, notices)
GET/comms/history/Message history

Returns sent message history for the organisation with recipient counts and delivery status. Paginated.

ParameterTypeRequiredDescription
limitintegerNoMax results (default 20, max 100)
offsetintegerNoPagination offset (default 0)

Reference: Breakfast Choices

full Full English Breakfast (Cook)
continental Continental Breakfast (Cont)
bacon Bacon Sandwich (Bacon)
none No Breakfast (None)
apology Apologies (Apol)

SpotTheSplat API v2.3 — Schema auto-generated from /api/v2/schema/