API Docs
Dashboard

Mobile app quickstart

Build a native iOS or Android app where staff log in as themselves, switch between businesses, and manage everything the web dashboard can.

Two ways to authenticate

The API accepts two kinds of Bearer token. A business API key is long-lived and bound to one business — great for server-to-server integrations, but never safe to embed in an app a user installs. A user access token is obtained by logging a person in, is short-lived, and can act on every business that person can access. Mobile apps use user tokens.

Every endpoint in the reference accepts a user token except the handful marked as API-key specific.

1. Log in

Exchange the user's email and password for an access token (a 15-minute JWT) and a refresh token (valid 30 days). The response also lists every business the user can act on — use it to render a business switcher. Pass an optional device_name so the user can recognise the session later.

Request

curl -X POST https://app.appointment.dev/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "•••••••••",
    "device_name": "Pixel 9"
  }'

Response

{
  "data": {
    "token_type": "Bearer",
    "access_token": "eyJ0eXAiOiJKV1Qi...",
    "expires_in": 900,
    "refresh_token": "rt_9f2c4e...",
    "user": { "id": 42, "email": "[email protected]", "account_type": "A" },
    "businesses": [
      { "business_id": 7, "business_name": "Snazzy Digital" },
      { "business_id": 9, "business_name": "Second Studio" }
    ]
  }
}

2. Choose the acting business

Send the X-Business-Id header on every request. If the user has access to exactly one business you can omit it; with several available and none selected, the API returns 422 business_required listing the choices. Call GET /api/v1/me/businesses any time to refresh the switcher.

Request

curl https://app.appointment.dev/api/v1/dashboard/stats \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1Qi..." \
  -H "X-Business-Id: 7"

3. Keep the session alive

When a request returns 401 because the access token expired, exchange the refresh token for a fresh pair. Refresh tokens rotate: each call invalidates the token you sent and returns a new one, so always store the newest. Presenting an already-used refresh token is treated as theft and revokes the whole session — the user must log in again.

Store tokens in the secure store. Use the iOS Keychain or Android EncryptedSharedPreferences / Keystore — never plain preferences or disk.

Request

curl -X POST https://app.appointment.dev/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{ "refresh_token": "rt_9f2c4e..." }'

Log out (revokes the session)

curl -X POST https://app.appointment.dev/api/v1/auth/logout \
  -H "Content-Type: application/json" \
  -d '{ "refresh_token": "rt_9f2c4e..." }'

4. Sign in with Google

For native Google Sign-In, obtain a Google ID token on the device and exchange it for API tokens. The response matches /auth/login, with an extra needs_business_setup flag that is true on a brand-new account.

Add your Android and iOS OAuth client IDs to the server's google_mobile_client_ids configuration so their ID tokens are accepted.

Request

curl -X POST https://app.appointment.dev/api/v1/auth/google \
  -H "Content-Type: application/json" \
  -d '{ "id_token": "eyJhbGciOi...", "device_name": "iPhone 16" }'

5. Connect an integration

OAuth integrations (like Google Calendar) run in the device browser. Ask the API for an authorize URL, open it with an in-app browser / ASWebAuthenticationSession, and the connection completes on the server. The URL carries a signed 10-minute state that identifies the business — no session cookie needed.

Request

curl -X POST https://app.appointment.dev/api/v1/integrations/google/connect-url \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1Qi..." \
  -H "X-Business-Id: 7"

# -> { "data": { "authorize_url": "https://accounts.google.com/o/oauth2/...", "expires_in": 600 } }

Build a screen for anything the dashboard does

With a user token and a selected business you can drive the whole product:

  • Home — /dashboard/stats, /dashboard/recent-bookings, /dashboard/upcoming
  • Bookings — list, create, update status, notes, participants, refunds and payment links
  • Check-in — scan a QR code and POST /attendance/check-in
  • Customers, products, coupons, FAQs, testimonials, pages — full CRUD
  • Invoices & payments — create, record payments, email, download the PDF
  • Newsletter — subscribers, drafts and campaign sends
  • Settings & subscription — business profile, VAT, chatbot, plan and usage
  • Platform admin — for super-admins, see the Admin API

Browse every endpoint in the API reference, and read Errors for the shared error envelope.