Skip to content
Last updated

Quickstart

Get from nothing to your first successful V3 call. Everything else — the full reference, error registry, PII rules — is in the Business Management v3 page; you should not need it to finish this one.

V3 is a contract preview. The endpoints are not deployed yet, so the calls below do not return data today. The shapes are stable enough to build against. The initial production release, including the core business flows, is planned for October 2026; additional operations become available in subsequent iterations.

Working with v1 or v2 instead? Those use a partner token and a combined Bearer <partner>, User <user> header — see How to Get API Keys (v1 and v2). V3 does not accept that header.

1. Pick your integration type

This one choice decides everything that follows.

You are buildingCredentialFlow
Your own script for your own business — internal automation, a private MCP server, a report jobRestricted key, created in your Altegio accountNone. The key is the credential
A product other businesses install — a marketplace app with a backend that runs unattendedMarketplace application + confidential OAuth client (client_id + client_secret)Client Credentials
An agent or desktop/CLI tool acting as a specific employee — Claude, Cursor, Codex, your own native appOAuth public client — self-registered via DCR/CIMD, or pre-registeredAuthorization Code + PKCE

Two things that surprise people:

  • Registering an OAuth client grants you nothing. It creates an identity, not access. Data still requires either a business installing your app, or a person consenting.
  • Public clients cannot use Client Credentials. If you self-registered through DCR, you act on behalf of a user — there is no unattended path without a marketplace application.

2. Get your credential

Restricted key — create it in your account. It is shown once; store it like a password. Choose its scopes and its Locations at creation time.

Marketplace app — register the application, then create a confidential OAuth client for it. You get client_id and client_secret; the secret is shown once and can be rotated with overlap.

Agent / native client — either pre-register and receive a client_id, or self-register:

curl -X POST https://api.alteg.io/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{
    "client_name": "Example MCP Host",
    "redirect_uris": ["http://127.0.0.1/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "token_endpoint_auth_method": "none"
  }'

Loopback redirects are accepted for native and CLI clients and the port is dynamic — you do not register every port you might bind. localhost is not accepted; use the literal 127.0.0.1 or [::1].

3. Get a token

Restricted key — skip this step. The key is sent directly as the Bearer credential.

Marketplace backend. You need the location_id you are acting in: you receive it when the business installs your app, as salon_id on your registration redirect. One token is bound to one Location — an app installed in twenty Locations requests twenty tokens.

curl -X POST https://api.alteg.io/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d location_id=777 \
  -d 'scope=clients:read appointments:read'

No refresh token comes back — request a new access token when the 15-minute one expires.

Agent acting as an employee. Send the user to GET /oauth/authorize with PKCE, let them log in and pick which Locations you may touch, then exchange the code:

curl -X POST https://api.alteg.io/oauth/token \
  -d grant_type=authorization_code \
  -d client_id="$CLIENT_ID" \
  -d code="$CODE" \
  -d code_verifier="$VERIFIER" \
  -d redirect_uri=http://127.0.0.1:53682/callback

This flow returns a rotating refresh token. Each use rotates it; replaying an old one kills the whole family, so always store the newest.

4. See what you can reach

curl https://api.alteg.io/oauth/accessible-resources \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Returns the Locations and chains this token can act in, with the scopes granted on each. Use it to learn which location_id to put in a path — it describes the token you already hold, so it is a check, not a way to discover your first Location.

5. Make the call

Resource paths sit under /api/v3. OAuth and discovery stay on the host root (no /api/v3).

curl "https://api.alteg.io/api/v3/locations/777/clients?limit=25" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Every resource lives under a Location. Lists are cursor-paginated: pass the returned next_cursor back as cursor.

Errors are application/problem+json with a stable code — branch on that, never on the message:

{
  "type": "https://developers.alteg.io/problems/missing-scope",
  "title": "Missing scope",
  "status": 403,
  "code": "missing_scope",
  "detail": "The token does not carry clients:read.",
  "instance": "urn:altegio:request:req_a1b2"
}

404 on a Location means "not yours or not there" — the two are deliberately indistinguishable, so do not treat it as "deleted".

Two complete examples

Agent host (Codex, Cursor, Claude). Self-register → client_id, no secret · Authorization Code + PKCE with a 127.0.0.1 redirect · the employee picks Locations on the consent screen · call accessible-resources to see what they picked · then act. Rotate the refresh token on every use.

Personal server-to-server script. Create a restricted key in your account, scoped to the Locations you need · send it as Authorization: Bearer <key> · that is the whole setup. No OAuth, no token endpoint, no refresh.

What not to expect

  • No account-wide token. Every marketplace Client Credentials token is bound to one Location. User-delegated tokens and restricted keys may cover multiple Locations and chains — call GET /oauth/accessible-resources to inspect the effective grants.
  • No refresh for marketplace backends. Re-authenticate with your client credentials instead.
  • client_id is not an application id. The word "client" also means the business's customer in /clients — the OAuth one is always written as client_id and looks like altg_oauth_… or a CIMD URL.
  • Scopes differ per credential class. Client Credentials cannot be granted chain-wide scopes, locations:create or team_members:manage_access; restricted keys also cannot use team_members:manage_access in the first iteration. Requesting an unavailable scope fails with invalid_scope/missing_scope. Authorization Code may hold team_members:manage_access when the business grants it.
  • Resource base is /api/v3. Example: https://api.alteg.io/api/v3/locations/{location_id}/…. Token, register, revoke, and accessible-resources stay at https://api.alteg.io/oauth/….