Download OpenAPI specification:
Logistics operations API for the 4klyft platform.
This API provides comprehensive endpoints for managing:
All API endpoints (except /api/docs and /api/v1/iam/auth/*) require JWT Bearer token authentication.
Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>
API requests are rate-limited to ensure fair usage. Standard limits are:
Per-entity ability probe endpoint.
The UI calls POST /api/auth/can to ask "given the user's current scopes
The response is a flat map keyed by the requested scope. Each entry has:
allowed (bool) — combined verdict (scope held AND state allows)reason (string) — present on denials, suitable for tooltip displayBackend always remains authoritative via the bus AuthorizationStage; this endpoint is advisory and intended purely to drive UI gating.
Returns a map of scope → verdict for the current user against an optional subject entity. Both the user-holds-scope check and the entity-state check must pass for allowed to be true.
Subject URI (optional) and a list of scopes to probe
| subject | string ResourceUri of the entity being probed. Omit for scope-only checks. |
| scopes required | Array of strings [ 1 .. 50 ] items |
{- "subject": "glacia:///document/documents/01KT0000000000000000000000",
- "scopes": [
- "document:document:finalize",
- "document:document:void"
]
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Permanently anonymizes the authenticated user account. All PII is removed. This action is irreversible.
{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Authenticate a user with email and password. Returns access and refresh tokens.
Login credentials
| email required | string <email> User email address |
| password required | string <password> User password |
{- "email": "user@example.com",
- "password": "your-password"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Revoke all active sessions for the authenticated identity.
{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Revoke all active sessions for the authenticated identity except the current one.
{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Use a refresh token to obtain a new access token.
Refresh token
| refreshToken required | string The refresh token |
{- "refreshToken": "string"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Create a new account with email and password. No tokens are returned — a verification email is sent and the user must verify, then log in.
Registration details
| email required | string <email> User email address |
| password required | string <password> Password (minimum 8 characters) |
| firstName required | string First name |
| company | string Company / organization name (optional; used for the first-organization step after verification) |
| country | string Country (optional) |
| marketingOptIn | boolean Default: false Consent to marketing communications |
{- "email": "user@example.com",
- "password": "your-secure-password",
- "firstName": "Alex",
- "company": "string",
- "country": "string",
- "marketingOptIn": false
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Request a password reset email. Always returns success to avoid leaking email existence.
Email address
| email required | string <email> The email address associated with the account |
{- "email": "user@example.com"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Request a new verification email. Always returns success to avoid leaking email existence.
Email address
| email required | string <email> Email address to resend verification to |
{- "email": "user@example.com"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Submit the token received by email along with a new password to complete the password reset.
Reset token and new password
| token required | string The password reset token received by email |
| newPassword required | string <password> The new password (minimum 8 characters) |
{- "token": "string",
- "newPassword": "pa$$word"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Validates membership and issues a tenant-scoped access token. Include this token as Bearer in subsequent requests to operate within the selected tenant.
Tenant selection
| tenantId required | string ULID of the tenant to operate under |
{- "tenantId": "01HQWXYZ1234567890TENANT"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Submit the token received by email to verify the email address. No authentication required.
Verification token
| token required | string The verification token received by email |
{- "token": "string"
}{- "type": "/errors/validation-error",
- "title": "Validation Error",
- "status": 400,
- "detail": "The provided input is invalid",
- "violations": [
- {
- "propertyPath": "code",
- "message": "This value should not be blank."
}
], - "instance": "string"
}Social-signup / SSO entry-point endpoints.
POST /api/iam/auth/external/{kind}/start
Mints a signed HMAC state token and returns the provider's authorization
URL the browser must navigate to (or feed into a client-side SDK such as
Apple's AppleID.auth.init). Same JSON contract as StorageOAuthResource
on the Storage module.
The callback half of the flow lives on a separate invokable Symfony route ({@see \Glacia\IAM\Infrastructure\Api\ApiPlatform\State\Provider\ExternalIdentityCallbackProvider}) because the OAuth callback returns a redirect (with the freshly-issued tokens in the URL fragment) — that response shape does not fit API Platform's resource serialization.
Public route (no auth required) — see iam/prepend/security.yaml.
Mints an HMAC-signed state token and returns the provider authorization URL the browser must navigate to. The same JSON shape is consumed by client-side SDK flows (e.g. Apple JS SDK).
| kind required | string Enum: "google_oauth" "facebook_oauth" "apple_oauth" "oidc" "saml" Provider discriminator |
Optional return URI overriding the platform default.
| returnUri | string or null Final user-facing URL to bounce to after the callback succeeds. Must match the configured allow-list when one is set. |
{- "returnUri": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "kind": "string",
- "authorizationUrl": "string",
- "state": "string",
- "redirectUri": "string",
- "returnUri": "string",
- "expiresInSeconds": 0
}