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
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/auth/login | Exchange credentials for a JWT |
| POST | /api/v1/auth/logout | Clear the session cookie |
| GET | /api/v1/account | The caller's account |
| GET | /api/v1/account/statements | Balance and statement lines |
| GET | /api/v1/account/tokens | The caller's API token |
| GET | /api/v1/transactions | The caller's transactions |
| GET | /api/v1/notifications/preferences | Notification settings |
| GET | /api/v1/config | Public application config |
| GET | /api/v1/catalog | Public product catalog |
| GET | /api/v1/status | Public service status |
| GET | /api/v1/regions | Public region list |
| GET | /api/v1/team | Team members, plus the documented write schema |
| POST | /api/v1/team | Add a team member |
| GET | /api/v1/admin/accounts | Every account (gateway blocks this path) |
| GET | /api/v1/admin/health | Admin health check (gateway blocks this path) |
| GET | /api/v1/search | Search team members, JSON |
| GET | /api/v1/render/search | Search results as a webview HTML fragment |
| GET | /api/v1/render/receipt | Payment 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"}'