Use this guide to plan a future V3 integration against the contract prototype. Everything else — the full reference, error registry, PII rules — is in the Business Management v3 page.
Coming soon — October 2026. V3 is not ready: its endpoints are not deployed, and the calls below cannot return data today. This page documents a prototype for implementation planning; paths and schemas may still change before release.
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.
This one choice decides everything that follows.
| You are building | Credential | Flow |
|---|---|---|
| Your own script for your own business — internal automation, a private MCP server, a report job | Restricted key, created in your Altegio account | None. The key is the credential |
| A product other businesses install — a marketplace app with a backend that runs unattended | Marketplace 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 app | OAuth public client — self-registered via DCR/CIMD, or pre-registered | Authorization 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.
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].
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/callbackThis flow returns a rotating refresh token. Each use rotates it; replaying an old one kills the whole family, so always store the newest.
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.
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".
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.
- 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-resourcesto inspect the effective grants. - No refresh for marketplace backends. Re-authenticate with your client credentials instead.
client_idis not an application id. The word "client" also means the business's customer in/clients— the OAuth one is always written asclient_idand looks likeag_client_…or a CIMD URL.- Scopes differ per credential class. Client Credentials cannot be granted chain-wide scopes,
locations:createorteam_members:manage_access; restricted keys also cannot useteam_members:manage_accessin the first iteration. Requesting an unavailable scope fails withinvalid_scope/missing_scope. Authorization Code may holdteam_members:manage_accesswhen the business grants it. - Resource base is
/api/v3. Example:https://api.alteg.io/api/v3/locations/{location_id}/…. Token, register, revoke, andaccessible-resourcesstay athttps://api.alteg.io/oauth/….