API

GraphQL is the data backend. REST carries auth, the endpoints the mobile client hits directly, and the fragments its webview loads.

GraphQL

POST /api/graphql  ·  GET serves GraphiQL

type Query {
  me: Account
  account(id: String!): Account
  accounts: [Account]
  team(limit: Int): [TeamMember]
  search(q: String!): [TeamMember]
  transactions: [Transaction]
  config: String
}

type Mutation {
  addTeamMember(username: String, role: String, account_balance: String): TeamMember
}

REST

MethodPathPurpose
POST/api/v1/auth/loginExchange credentials for a JWT
POST/api/v1/auth/logoutClear the session cookie
GET/api/v1/accountThe caller's account
GET/api/v1/account/statementsBalance and statement lines
GET/api/v1/account/tokensThe caller's API token
GET/api/v1/transactionsThe caller's transactions
GET/api/v1/notifications/preferencesNotification settings
GET/api/v1/configPublic application config
GET/api/v1/catalogPublic product catalog
GET/api/v1/statusPublic service status
GET/api/v1/regionsPublic region list
GET/api/v1/teamTeam members, plus the documented write schema
POST/api/v1/teamAdd a team member
GET/api/v1/admin/accountsEvery account (gateway blocks this path)
GET/api/v1/admin/healthAdmin health check (gateway blocks this path)
GET/api/v1/searchSearch team members, JSON
GET/api/v1/render/searchSearch results as a webview HTML fragment
GET/api/v1/render/receiptPayment receipt as a webview HTML fragment

Authentication

The token is accepted as Authorization: Bearer <jwt> or as the session cookie, so the website and the mobile client share one session.

curl -X POST '/api/v1/auth/login' \
  -H 'content-type: application/json' \
  -d '{"email":"range-user-001@example.invalid","password":"range-viewer-pw-001"}'