Skip to content

Management API Overview

The Management API provides programmatic access to all Parako.ID administration features. It is a RESTful API at the /api/v1 base path, secured with JWT access tokens obtained via the OAuth2 Client Credentials grant.

The API is always enabled and available at /api/v1. Access is controlled entirely through JWT authentication and scope-based authorization — there is no separate configuration toggle.

The Management API respects the deployment’s tenancy mode. URL patterns differ between single-tenant and multi-tenant deployments.

All endpoints use the deployment URL directly:

OIDC issuer: https://auth.example.com/oidc/v1
Discovery: https://auth.example.com/oidc/v1/.well-known/openid-configuration
Token endpoint: https://auth.example.com/oidc/v1/token
Management API: https://auth.example.com/api/v1
Admin panel: https://auth.example.com/admin

In multi-tenant mode, the system derives three tenant tiers from the deployment URL. With DEPLOYMENT_URL=https://example.com:

Regular tenant{tenant}.example.com

Each tenant is an isolated OIDC provider with its own users, clients, sessions, and signing keys.

Issuer: https://acme.example.com/oidc/v1
Discovery: https://acme.example.com/oidc/v1/.well-known/openid-configuration
Token endpoint: https://acme.example.com/oidc/v1/token
Management API: https://acme.example.com/api/v1
Admin panel: https://acme.example.com/admin

Platform admin_platforms.example.com

Cross-tenant control plane for managing all tenants. Issues tokens that carry platform-only scopes (parako:tenants:*, parako:cross-tenant:*, parako:settings:*).

Issuer: https://_platforms.example.com/oidc/v1
Discovery: https://_platforms.example.com/oidc/v1/.well-known/openid-configuration
Token endpoint: https://_platforms.example.com/oidc/v1/token
Management API: https://_platforms.example.com/api/v1
Admin portal: https://_platforms.example.com/

Ops gateway_ops.example.com

Stateless infrastructure gateway for cross-tenant social login (OAuth callback relay). Not used for API requests.

Callback relay: https://_ops.example.com/social/{provider}/callback
Health probe: https://_ops.example.com/health

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.

InterfaceAccessAuthScope
Admin panel/admin on tenant subdomainSession (browser)One tenant — users, clients, settings
Platform portal_platforms subdomain (e.g. _platforms.example.com)Session (platform_admin role)All tenants — cross-tenant ops
Management API/api/v1 on any subdomainJWT Bearer (M2M)Programmatic — full 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 algorithms RS256, PS256, or ES256, with audience urn:parako:api:v1 and a 30-second clock tolerance.

Source: src/api/v1/middleware/jwt-auth.middleware.ts

The recommended way is through the admin panel. The CLI is available as an alternative.

Admin panel (recommended):

  1. Navigate to /admin/oidc-clients
  2. Click Create Client
  3. Select the “Management API” preset — this pre-fills grant_types: ['client_credentials'] and allowedResources: ['urn:parako:api:v1']
  4. Enter a client name and description
  5. Submit — you will see the generated client_id and client_secret (click the eye icon to reveal the secret)

CLI alternative:

Terminal window
yarn client add
# Select "Service Account" or "API" type
# Follow the interactive prompts

Single-tenant:

Terminal window
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):

Terminal window
curl -X POST https://acme.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 (platform — for cross-tenant scopes):

Terminal window
curl -X POST https://_platforms.example.com/oidc/v1/token \
-u "CLIENT_ID:CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "resource=urn:parako:api:v1" \
-d "scope=parako:tenants:read parako:tenants:write"

The resource parameter must be urn:parako:api:v1 — this is the audience for Management API tokens.

Single-tenant:

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

Multi-tenant (regular tenant):

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

Multi-tenant (platform — cross-tenant operations):

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

The API uses a 30-scope taxonomy following the pattern parako:<domain>:<action>.

Scopes are classified into three tiers with different recommended token TTLs:

TierTTLActionsUse case
read3,600s (1h)View dataSafe data retrieval
write1,800s (30m)Create, update, manageModifying resources
destructive900s (15m)Delete, revoke, rotateIrreversible operations

Source: src/api/v1/scopes.ts

ScopeClassificationDescription
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:readreadView dashboard 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:readreadView tenants (platform only)
parako:tenants:writewriteCreate/update tenants (platform only)
parako:tenants:deletedestructiveDelete tenants (platform only)
parako:cross-tenant:readreadRead cross-tenant config (platform only)
parako:cross-tenant:writewriteModify cross-tenant config (platform only)
parako:settings:readreadView system settings (platform only)
parako:settings:writewriteModify system settings (platform only)

Platform-only scopes (parako:tenants:*, parako:cross-tenant:*, parako:settings:*) can only be used by tokens whose issuer ends with /_platforms. In multi-tenant mode, this means the token must be obtained from the _platforms.example.com OIDC provider. Non-platform issuers requesting these scopes receive 403 Forbidden.

Source: src/api/v1/middleware/jwt-auth.middleware.ts

API rate limits are applied per tier within a 60-second sliding window:

TierLimitWindowOperations
read100 req60sGET list/detail
write30 req60sPOST, PUT, PATCH
delete10 req60sDELETE
sensitive3 req60sSecret rotation, password reset, MFA reset, key rotation

The rate limit key is the client_id from the JWT, with a fallback to the request IP address.

Source: src/api/v1/middleware/rate-limiter.middleware.ts

Rate limit headers are included in every response:

HeaderDescription
X-RateLimit-LimitMaximum requests in the window
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetWindow reset timestamp (Unix epoch)
Retry-AfterSeconds until the window resets (only on 429)

When rate limited, the API returns 429 Too Many Requests with a Retry-After header.

The API returns errors in RFC 9457 Problem Detail format with URN-based type identifiers:

{
"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"
}

Source: src/api/v1/errors.ts

Type URNStatusWhen
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(s)
urn:parako:error:not-found404Resource doesn’t 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
CodeMeaning
200Success
201Created
204No content (successful delete)
400Bad request (invalid config section)
401Unauthorized (missing or invalid token)
403Forbidden (insufficient scope)
404Not found
409Conflict (duplicate resource)
413Request body too large
422Validation error / constraint violation
429Too many requests (rate limited)
500Internal server error

List endpoints use keyset cursor-based pagination.

Source: src/api/v1/pagination.ts

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
}
}

Use the next_cursor value as the after parameter in the next request to fetch the next page. The total_count field is only present when include_count=true.

All Management API requests are logged to the audit trail:

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

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

Source: src/api/v1/middleware/audit-logger.middleware.ts

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