Download OpenAPI specification:
Commerce and order-fulfilment platform API for 4klyft.
This API provides 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>
Every /api/ request is rate-limited per caller — by your authenticated
identity when a token is present, otherwise by client IP. The
authentication endpoints (/auth/login, /auth/refresh,
/auth/request-password-reset) carry stricter, IP-based limits.
Each response advertises your current budget via headers:
X-RateLimit-Limit — the bucket sizeX-RateLimit-Remaining — tokens left in the current windowX-RateLimit-Reset — Unix timestamp when a token next frees upExceeding a limit returns 429 Too Many Requests (RFC 6585) with a
Retry-After header (seconds to wait). Back off and retry after the
indicated delay rather than hammering the endpoint.
Represents a tenant's org-level notification channel policy — the "ceiling" that decides which channels each topic may use before any per-user preference narrows it further.
The policy is a per-tenant singleton addressed at a fixed path; the resource identifier is therefore a constant. It is modeled as a topic x channel matrix — every entry is a (type, channel, enabled) cell.
Retrieve the org-level notification channel policy (topic x channel matrix) for the current tenant. Every topic/channel cell is returned with its effective enabled flag — Email and Storage default on, every other channel defaults off until enabled.
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "policy",
- "entries": [
- {
- "type": "shipping.shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipping.shipment.delivered",
- "channel": "push",
- "enabled": false
}
]
}Update the org-level notification channel policy matrix for the current tenant. Cells absent from the request retain their previous on/off state.
Channel policy configuration data
Array of objects Policy matrix cells to update |
{- "entries": [
- {
- "type": "shipping.shipment.delivered",
- "channel": "push",
- "enabled": true
}
]
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "policy",
- "entries": [
- {
- "type": "shipping.shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipping.shipment.delivered",
- "channel": "push",
- "enabled": false
}
]
}Represents a user's notification preferences.
Preferences are modeled as a topic x channel matrix — every entry is a (type, channel, enabled) cell. The dispatch pipeline asks the matrix "is this topic enabled on this channel" before delivering.
Retrieve the notification preferences (topic x channel matrix) for the currently authenticated user.
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "entries": [
- {
- "type": "shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipment.delivered",
- "channel": "sms",
- "enabled": false
}
], - "doNotDisturb": false,
- "doNotDisturbUntil": "2024-06-14T08:00:00+00:00",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00"
}Update the notification preference matrix for the currently authenticated user. Cells absent from the request retain their previous on/off state.
Notification preferences update data
Array of objects Preference matrix cells to update | |
| doNotDisturb | boolean Whether do not disturb mode is enabled |
| doNotDisturbStart | string or null Start time for do not disturb (HH:MM format) |
| doNotDisturbEnd | string or null End time for do not disturb (HH:MM format) |
{- "entries": [
- {
- "type": "shipment.delivered",
- "channel": "email",
- "enabled": true
}
], - "doNotDisturb": false,
- "doNotDisturbStart": "22:00",
- "doNotDisturbEnd": "08:00"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "entries": [
- {
- "type": "shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipment.delivered",
- "channel": "sms",
- "enabled": false
}
], - "doNotDisturb": false,
- "doNotDisturbUntil": "2024-06-14T08:00:00+00:00",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00"
}Disable do not disturb mode for the current user. Notifications will resume delivery.
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "entries": [
- {
- "type": "shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipment.delivered",
- "channel": "sms",
- "enabled": false
}
], - "doNotDisturb": false,
- "doNotDisturbUntil": "2024-06-14T08:00:00+00:00",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00"
}Enable do not disturb mode for the current user. When enabled, notifications will not be delivered.
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "entries": [
- {
- "type": "shipment.delivered",
- "channel": "email",
- "enabled": true
}, - {
- "type": "shipment.delivered",
- "channel": "sms",
- "enabled": false
}
], - "doNotDisturb": false,
- "doNotDisturbUntil": "2024-06-14T08:00:00+00:00",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "updatedAt": "2024-06-14T14:45:00+00:00"
}Retrieve a paginated list of notifications for the current user.
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination |
| limit | integer [ 1 .. 100 ] Default: 10 Example: limit=10 Number of items per page |
| type | string Enum: "operational" "incident" "financial" "maintenance" "account" "announcement" Example: type=operational Filter by the coarse NotificationType bucket |
| isRead | boolean Filter by read status |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "type": "string",
- "topic": "string",
- "title": "string",
- "message": "string",
- "priority": "string",
- "isRead": true,
- "createdAt": "string",
- "readAt": "string",
- "resourceId": "string",
- "resourceType": "string",
- "subject": "string"
}
]
}Mark all notifications as read for the current user.
{- "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"
}Get the count of unread notifications for the current user.
{- "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"
}Returns a single stored notification, including subject, body, payload, and read state.
| id required | string StoredNotification identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "type": "string",
- "topic": "string",
- "title": "string",
- "message": "string",
- "priority": "string",
- "isRead": true,
- "createdAt": "string",
- "readAt": "string",
- "resourceId": "string",
- "resourceType": "string",
- "subject": "string"
}Mark a single notification as read.
| id required | string Example: notif-123 Notification ID |
{- "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"
}List all push notification subscriptions for the current user.
| page | integer Default: 1 The collection page number |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "expiresAt": "2025-06-14T10:30:00+00:00"
}
]
}Register a Web Push subscription for the current user. If a subscription with the same endpoint already exists, the keys are updated.
The new PushSubscription resource
| endpoint | string |
| p256dhKey | string |
| authKey | string |
| userAgent | string or null |
| expiresAt | string or null |
{- "endpoint": "string",
- "p256dhKey": "string",
- "authKey": "string",
- "userAgent": "string",
- "expiresAt": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "01HQWXYZ1234567890ABCDEF",
- "userId": "01HQWXYZ1234567890ABCDEF",
- "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
- "createdAt": "2024-06-14T10:30:00+00:00",
- "expiresAt": "2025-06-14T10:30:00+00:00"
}Remove a Web Push subscription by endpoint URL.
The new PushSubscription resource
| endpoint | string |
{- "endpoint": "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"
}Retrieve a list of all notification templates.
| notificationType | string Example: notificationType=route.assigned Filter by notification type |
| channelType | string Enum: "storage" "email" "sms" "push" Example: channelType=email Filter by channel type |
| locale | string Example: locale=en Filter by locale |
| page | integer Default: 1 The collection page number |
{- "totalItems": 0,
- "search": {
- "@type": "string",
- "template": "string",
- "variableRepresentation": "string",
- "mapping": [
- {
- "@type": "string",
- "variable": "string",
- "property": "string",
- "required": true
}
]
}, - "view": {
- "@id": "string",
- "@type": "string",
- "first": "string",
- "last": "string",
- "previous": "string",
- "next": "string"
}, - "member": [
- {
- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "notificationType": "string",
- "channelType": "string",
- "name": "string",
- "locale": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "isActive": true,
- "tenantId": "string",
- "createdAt": "string",
- "updatedAt": "string"
}
]
}Create a new notification template.
The new NotificationTemplate resource
| notificationType required | string Enum: "shipping.shipment.delayed" "shipping.shipment.delivered" "finance.payment.failed" "finance.payment.completed" "routing.incident.raised" "sales.order.fulfillment_blocked" "sales.order.fulfilled" "iam.tenant.invitation_sent" "iam.identity.password_reset" "iam.identity.email_verification" "admin.platform.announcement" "finance.invoice.overdue" "iam.identity.mfa_challenge_issued" "iam.identity.new_device_login" "finance.settlement.created" "finance.settlement.posted" "finance.settlement.paid" "iam.tenant.welcome_sent" "document.documentrequest.submitted" "document.documentrequest.review_started" "document.documentrequest.validated" "document.documentrequest.rejected" "document.documentrequest.cancelled" "document.document.finalized" "document.document.voided" "document.compliance.expiry_scan" "finance.invoice.issued" "finance.invoice.paid" "finance.creditnote.issued" "finance.bill.received" "finance.outgoing_payment.submitted" "finance.outgoing_payment.completed" "fulfilment.order.created" "fulfilment.order.progressed" "fulfilment.order.closed" "fulfilment.order.cancelled" "fulfilment.reservation.requires_attention" "fulfilment.fulfilment.handed_off" "fulfilment.return.requested" "fulfilment.return.authorized" "fulfilment.return.rejected" "fulfilment.return.received" "fulfilment.return.resolved" "partner.partner.created" "partner.partner.status_changed" "inventory.lot.recalled" "inventory.lot.expired" "inventory.serial_unit.status_changed" "inventory.item.discontinued" "iam.membership.created" "iam.membership.member_joined" "iam.membership.suspended" "iam.membership.reinstated" "iam.membership.role_assigned" "iam.membership.role_revoked" "sales.channel.sync_failed" "sales.order.ready" "sales.order.cancelled" "shipping.shipment.created" "shipping.shipment.scheduled" "shipping.shipment.in_transit" "shipping.shipment.out_for_delivery" "shipping.shipment.cancelled" "shipping.shipment.lost" "shipping.shipment.damaged" "shipping.shipment.refused" "platform.billing.invoice.reminder" "messaging.message.new" "messaging.message.mention" |
| channelType required | string Enum: "storage" "email" "sms" "push" "webhook" "slack" |
| name required | string <= 255 characters |
| subjectTemplate required | string |
| bodyTemplate required | string |
| htmlBodyTemplate | string or null |
| locale required | string <= 10 characters Default: "en" |
| tenantId | string or null <ulid> |
{- "notificationType": "shipping.shipment.delayed",
- "channelType": "storage",
- "name": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "locale": "en",
- "tenantId": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "notificationType": "string",
- "channelType": "string",
- "name": "string",
- "locale": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "isActive": true,
- "tenantId": "string",
- "createdAt": "string",
- "updatedAt": "string"
}Retrieve a single notification template by ID.
| id required | string NotificationTemplate identifier |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "notificationType": "string",
- "channelType": "string",
- "name": "string",
- "locale": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "isActive": true,
- "tenantId": "string",
- "createdAt": "string",
- "updatedAt": "string"
}Update an existing notification template.
| id required | string NotificationTemplate identifier |
The updated NotificationTemplate resource
| name | string or null <= 255 characters |
| subjectTemplate | string or null |
| bodyTemplate | string or null |
| htmlBodyTemplate | string or null |
| isActive | boolean or null |
{- "name": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "isActive": true
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "id": "string",
- "notificationType": "string",
- "channelType": "string",
- "name": "string",
- "locale": "string",
- "subjectTemplate": "string",
- "bodyTemplate": "string",
- "htmlBodyTemplate": "string",
- "isActive": true,
- "tenantId": "string",
- "createdAt": "string",
- "updatedAt": "string"
}Self-service topic-watch resource.
A user watches (subscribes to) a notification topic — optionally scoped to a single subject — so the SubscribersResolver includes them as a recipient. GET reports the current watch state for the FE toggle; POST watches; POST /unsubscribe unwatches. All operations act on the authenticated identity within its tenant.
Whether the current identity watches the given topic (optionally scoped to a subject). Backs the FE watch toggle.
| topic required | string Dotted topic value, e.g. shipping.shipment.delivered |
| subject | string Exact subject URI to scope the watch; omit to query the whole-topic watch |
{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "topic": "string",
- "subject": "string",
- "subscribed": true
}Subscribe the current identity to a topic (optionally scoped to a subject). Idempotent — watching again is a no-op.
The new TopicSubscription resource
| topic required | string Default: "" Enum: "shipping.shipment.delayed" "shipping.shipment.delivered" "finance.payment.failed" "finance.payment.completed" "routing.incident.raised" "sales.order.fulfillment_blocked" "sales.order.fulfilled" "iam.tenant.invitation_sent" "iam.identity.password_reset" "iam.identity.email_verification" "admin.platform.announcement" "finance.invoice.overdue" "iam.identity.mfa_challenge_issued" "iam.identity.new_device_login" "finance.settlement.created" "finance.settlement.posted" "finance.settlement.paid" "iam.tenant.welcome_sent" "document.documentrequest.submitted" "document.documentrequest.review_started" "document.documentrequest.validated" "document.documentrequest.rejected" "document.documentrequest.cancelled" "document.document.finalized" "document.document.voided" "document.compliance.expiry_scan" "finance.invoice.issued" "finance.invoice.paid" "finance.creditnote.issued" "finance.bill.received" "finance.outgoing_payment.submitted" "finance.outgoing_payment.completed" "fulfilment.order.created" "fulfilment.order.progressed" "fulfilment.order.closed" "fulfilment.order.cancelled" "fulfilment.reservation.requires_attention" "fulfilment.fulfilment.handed_off" "fulfilment.return.requested" "fulfilment.return.authorized" "fulfilment.return.rejected" "fulfilment.return.received" "fulfilment.return.resolved" "partner.partner.created" "partner.partner.status_changed" "inventory.lot.recalled" "inventory.lot.expired" "inventory.serial_unit.status_changed" "inventory.item.discontinued" "iam.membership.created" "iam.membership.member_joined" "iam.membership.suspended" "iam.membership.reinstated" "iam.membership.role_assigned" "iam.membership.role_revoked" "sales.channel.sync_failed" "sales.order.ready" "sales.order.cancelled" "shipping.shipment.created" "shipping.shipment.scheduled" "shipping.shipment.in_transit" "shipping.shipment.out_for_delivery" "shipping.shipment.cancelled" "shipping.shipment.lost" "shipping.shipment.damaged" "shipping.shipment.refused" "platform.billing.invoice.reminder" "messaging.message.new" "messaging.message.mention" |
| subject | string or null |
{- "topic": "shipping.shipment.delayed",
- "subject": "string"
}{- "@context": "string",
- "@id": "string",
- "@type": "string",
- "topic": "string",
- "subject": "string",
- "subscribed": true
}Remove the current identity's watch for a topic (optionally subject-scoped). No-op when not watched.
The new TopicSubscription resource
| topic required | string Default: "" Enum: "shipping.shipment.delayed" "shipping.shipment.delivered" "finance.payment.failed" "finance.payment.completed" "routing.incident.raised" "sales.order.fulfillment_blocked" "sales.order.fulfilled" "iam.tenant.invitation_sent" "iam.identity.password_reset" "iam.identity.email_verification" "admin.platform.announcement" "finance.invoice.overdue" "iam.identity.mfa_challenge_issued" "iam.identity.new_device_login" "finance.settlement.created" "finance.settlement.posted" "finance.settlement.paid" "iam.tenant.welcome_sent" "document.documentrequest.submitted" "document.documentrequest.review_started" "document.documentrequest.validated" "document.documentrequest.rejected" "document.documentrequest.cancelled" "document.document.finalized" "document.document.voided" "document.compliance.expiry_scan" "finance.invoice.issued" "finance.invoice.paid" "finance.creditnote.issued" "finance.bill.received" "finance.outgoing_payment.submitted" "finance.outgoing_payment.completed" "fulfilment.order.created" "fulfilment.order.progressed" "fulfilment.order.closed" "fulfilment.order.cancelled" "fulfilment.reservation.requires_attention" "fulfilment.fulfilment.handed_off" "fulfilment.return.requested" "fulfilment.return.authorized" "fulfilment.return.rejected" "fulfilment.return.received" "fulfilment.return.resolved" "partner.partner.created" "partner.partner.status_changed" "inventory.lot.recalled" "inventory.lot.expired" "inventory.serial_unit.status_changed" "inventory.item.discontinued" "iam.membership.created" "iam.membership.member_joined" "iam.membership.suspended" "iam.membership.reinstated" "iam.membership.role_assigned" "iam.membership.role_revoked" "sales.channel.sync_failed" "sales.order.ready" "sales.order.cancelled" "shipping.shipment.created" "shipping.shipment.scheduled" "shipping.shipment.in_transit" "shipping.shipment.out_for_delivery" "shipping.shipment.cancelled" "shipping.shipment.lost" "shipping.shipment.damaged" "shipping.shipment.refused" "platform.billing.invoice.reminder" "messaging.message.new" "messaging.message.mention" |
| subject | string or null |
{- "topic": "shipping.shipment.delayed",
- "subject": "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"
}