Skip to content

Management API Overview

The Management API exposes every administration capability over REST at /api/v1. It is always enabled — access is controlled entirely through JWT Bearer tokens (OAuth2 Client Credentials) and scope-based authorization. There is no configuration toggle.

Endpoint reference for each resource lives in Management API Endpoints.

The Management API respects the deployment’s tenancy mode.

ModeOIDC issuerToken endpointAPI baseAdmin
Single-tenanthttps://auth.example.com/oidc/v1…/oidc/v1/tokenhttps://auth.example.com/api/v1https://auth.example.com/admin
Multi-tenant — regular tenanthttps://acme.example.com/oidc/v1…/oidc/v1/tokenhttps://acme.example.com/api/v1https://acme.example.com/admin
Multi-tenant — platform adminhttps://_platforms.example.com/oidc/v1…/oidc/v1/tokenhttps://_platforms.example.com/api/v1https://_platforms.example.com/
Multi-tenant — _ops gatewayn/a (not used for API requests)n/an/a (relays social OAuth callbacks)n/a

In multi-tenant mode, include the x-tenant-id header to scope API operations to a specific tenant when calling from a context that differs from the subdomain.

Admin panel vs Management API vs Platform portal

Section titled “Admin panel vs Management API vs Platform portal”
InterfaceAccessAuthScope
Admin panel/admin on tenant subdomainSession (browser)Single tenant — users, clients, settings
Platform portal_platforms.<base>Session (platform_admin role)All tenants — cross-tenant operations
Management API/api/v1 on any subdomainJWT Bearer (M2M)Programmatic — CRUD, CI/CD, automation

The admin panel uses internal routes and does not call the Management API. They are independent interfaces to the same underlying services.

The Management API uses JWT Bearer tokens obtained via the OAuth2 Client Credentials grant. Tokens are verified against the tenant’s JWKS using RS256, PS256, or ES256, with audience urn:parako:api:v1 and a 15-second clock tolerance (features.oidc.clock_tolerance).

Use the admin panel at /admin/oidc-clients and select the Management API preset. The preset pre-fills grant_types: ['client_credentials'] and allowedResources: ['urn:parako:api:v1']. The CLI (pnpm client add) is also available — see OIDC Clients.

Terminal window
# Single-tenant
curl -X POST https://auth.example.com/oidc/v1/token \
-u "CLIENT_ID:CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "resource=urn:parako:api:v1" \
-d "scope=parako:clients:read parako:users:read"
# Multi-tenant (regular tenant): replace the host with the tenant subdomain.
# Multi-tenant (platform-only scopes): hit https://_platforms.<base>/oidc/v1/token instead.

The resource parameter must be urn:parako:api:v1.

Terminal window
curl https://auth.example.com/api/v1/users \
-H "Authorization: Bearer ACCESS_TOKEN"

For platform-only scopes (parako:tenants:*, parako:cross-tenant:*, parako:settings:*), the API base must be the platform host (e.g. https://_platforms.example.com/api/v1/tenants).

This is the canonical scope table. Other docs link here.

Scopes follow the pattern parako:<domain>:<action> and are classified into three risk tiers with different recommended TTLs:

TierTTLOperation kind
read3,600 s (1 h)View data
write1,800 s (30 m)Create, update, manage
destructive900 s (15 m)Delete, revoke, rotate
ScopeTierDescription
parako:clients:readreadView OIDC client applications
parako:clients:writewriteCreate and update clients
parako:clients:deletedestructiveDelete clients
parako:users:readreadView user accounts and activity
parako:users:writewriteCreate, update, lock / unlock users
parako:users:deletedestructiveAnonymize or delete users
parako:sessions:readreadView active OIDC sessions
parako:sessions:revokedestructiveRevoke sessions
parako:grants:readreadView authorization grants
parako:grants:revokedestructiveRevoke grants
parako:jwks:readreadView signing keys
parako:jwks:rotatedestructiveRotate or retire keys
parako:audit:readreadQuery audit trail
parako:audit:writedestructiveCreate audit entries
parako:stats:readreadDashboard stats and health
parako:registration-tokens:readreadView DCR initial access tokens
parako:registration-tokens:writewriteCreate DCR tokens
parako:registration-tokens:deletedestructiveRevoke DCR tokens
parako:config:readreadView application configuration
parako:config:writewriteModify configuration
parako:social:readreadView social provider configs
parako:social:writewriteConfigure social providers
parako:webhooks:managewriteManage webhook subscriptions
parako:tenants:readreadPlatform only. View tenants
parako:tenants:writewritePlatform only. Create / update tenants
parako:tenants:deletedestructivePlatform only. Delete tenants
parako:cross-tenant:readreadPlatform only. Read cross-tenant config
parako:cross-tenant:writewritePlatform only. Modify cross-tenant config
parako:settings:readreadPlatform only. View system settings
parako:settings:writewritePlatform only. Modify system settings

Platform-only scopes are accepted only when the token’s issuer ends with /_platforms. Non-platform issuers requesting them receive 403 Forbidden.

Per-tier rate limits within a 60-second sliding window:

TierLimitWindowOperations
read100 req60 sGET list / detail
write30 req60 sPOST, PUT, PATCH
delete10 req60 sDELETE
sensitive3 req60 sSecret rotation, password reset, MFA reset, key rotation

The rate-limit key is the client_id from the JWT, falling back to the request IP.

Every response includes:

HeaderMeaning
X-RateLimit-LimitWindow cap
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetWindow reset (Unix epoch)
Retry-AfterSeconds until the next allowed request (429 only)

When throttled, the API returns 429 Too Many Requests.

Errors follow RFC 9457 Problem Detail with URN-based types:

{
"type": "urn:parako:error:not-found",
"title": "Resource Not Found",
"status": 404,
"detail": "User with ID 'abc123' was not found",
"instance": "/api/v1/users/abc123"
}
TypeStatusWhen
urn:parako:error:unauthorized401Missing or invalid credentials
urn:parako:error:token-expired401Token TTL exceeded
urn:parako:error:token-invalid401Bad signature or malformed JWT
urn:parako:error:forbidden403Authenticated but lacking permissions
urn:parako:error:scope-insufficient403Missing required scope
urn:parako:error:not-found404Resource does not exist
urn:parako:error:tenant-not-found404Tenant lookup failed
urn:parako:error:section-not-allowed400Requested config section not allowed
urn:parako:error:conflict409Duplicate resource
urn:parako:error:body-too-large413Request body too large
urn:parako:error:validation422Request validation failed
urn:parako:error:constraint-violation422Floor / ceiling constraint violated
urn:parako:error:rate-limit-exceeded429Too many requests
urn:parako:error:internal500Unexpected server error

List endpoints use keyset cursor pagination.

ParameterTypeDefaultDescription
limitnumber25Items per page (1–100)
afterstringOpaque cursor from previous response
include_countbooleanfalseInclude total_count in response
{
"data": [],
"pagination": {
"has_more": true,
"next_cursor": "eyJpZCI6IjY1...",
"total_count": 150
}
}

Pass next_cursor back as after for the next page. total_count is present only when include_count=true.

All Management API requests are logged asynchronously:

  • Activity type: api_request
  • Actor: service (identified by client_id)
  • Metadata: method, path, status_code, duration_ms, scope

Audit entries are written after the response is sent and do not affect request latency.

HeaderRequiredDescription
AuthorizationYesBearer <access_token>
Content-TypePOST / PUT / PATCHapplication/json
x-tenant-idMulti-tenant onlyTarget tenant identifier