Skip to main content

Authenticating Requests (Zitadel PAT Keys)

Base URL​

All API requests are scoped to your Zitadel Project UUID:

https://<project-id>.api.solti.run/1

Authentication​

Solti supports three authentication strategies. Pick the one matching your surface.

API Key (Zitadel PAT) — project host​

Solti delegates all API Key authentication to Zitadel. When an API Key is generated via Dashboard or CLI, Zitadel provisions a machine user under the project's scope and issues a Personal Access Token (PAT).

Header format:

X-Solti-API-Key: <your_zitadel_pat_token>
note

Solti does not store or hash your API key locally. Zitadel cryptographically validates each request token against the machine user, verifying roles (admin, developer, viewer) in real time.

OAuth User Token — project host (CLI default)​

Interactive users authenticated via solti account login (LogTo, Authorization Code + PKCE) call the project host with a bearer token:

Authorization: Bearer <logto_access_token>

Global host vs project host​

  • Project-scoped surface (jobs, cronjobs, connections, keys, resources): https://<project-id>.api.solti.run/1 — accepts API Key or OAuth user tokens.
  • Global surface (account, organization & project management): https://api.solti.run/1 — OAuth user auth only; API Key auth is rejected with 401 (API keys are project-scoped machine-user credentials and carry no account context). See Global Host API.

Rate Limiting​

Ordinary requests (API Key / OAuth principals) are rate limited (superuser traffic and unauthenticated requests are not). Limits are flat across all tiers.

On limit exceeded the API returns 429 with a Retry-After header (seconds) and X-RateLimit-* headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) so clients can back off programmatically:

{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded for this project. Retry after 17 seconds."
}
}

SDKs/CLIs auto-retry on 429 honoring Retry-After; the SDK exception mapping is RateLimitError. Discovery endpoints (/1/resources/*) use a tighter, dedicated rate-limit bucket — see the Resources Discovery API.

Global Host: Account, Organization & Project API​

Account, organization, and project management endpoints live on the global host https://api.solti.run/1 (distinct from the project-scoped https://<project-id>.api.solti.run/1). OAuth user auth only; API Key auth is rejected with 401.

MethodPathMinimum RoleDescription
GET/1/accountauthenticatedCurrent account: email, name, organization memberships (id, name, role).
GET/1/organizationsauthenticatedList organizations the account belongs to.
POST/1/organizationsauthenticatedCreate an organization; creator becomes owner. Body: { "name": ... }.
GET/1/organizations/{org_id}memberOrganization detail.
PATCH/1/organizations/{org_id}adminUpdate organization (name, etc.).
DELETE/1/organizations/{org_id}ownerDelete organization.
GET/1/organizations/{org_id}/membersmemberList members with their org roles.
PATCH/1/organizations/{org_id}/members/{user_id}adminChange a member's org role (owner-only for owner roles).
DELETE/1/organizations/{org_id}/members/{user_id}adminRemove a member.
GET/1/organizations/{org_id}/projectsmemberList projects in the organization.
POST/1/organizations/{org_id}/projectsadminCreate a project in the organization.
GET/1/projects/{project_id}org memberProject detail (id, displayName, organization).
PATCH/1/projects/{project_id}project adminUpdate project (e.g., displayName).
DELETE/1/projects/{project_id}org ownerDelete project.

List endpoints paginate with ?limit / ?offset; request payloads use camelCase; errors reuse the standard API error format (403 on insufficient role). Organization/project creation reuses the existing dashboard-side provisioning logic server-side; invitations themselves stay in the dashboard.