Skip to main content

API Reference

Complete reference for all Orqestra HTTP endpoints.


Authentication

All tenant API calls require the x-api-key header:

x-api-key: YOUR_TENANT_API_KEY

Your API key is shown in the Admin UI. Never expose it in client-side code.


Trigger an event

POST /api/v1/events/trigger

The primary endpoint. Fires a notification event that Orqestra resolves against your configured templates and dispatches.

Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
x-api-keyYesYour tenant API key
X-Orqestra-SignatureConditionalHMAC-SHA256 hex of raw body — required if webhook secret is configured
X-Idempotency-KeyNoCustom deduplication key (24-hour window)
X-Trace-IdNoTrace ID for distributed tracing

Request body

{
"eventType": "order.confirmed",
"eventId": "evt_optional_custom_id",
"channels": ["EMAIL"],
"payload": {
"userId": "uuid-of-recipient",
"recipientEmail": "user@example.com",
"recipientPhone": "+254712345678"
},
"variables": {
"title": "Order Confirmed",
"orderNumber": "ORD-2026-1234",
"amount": "$49.99",
"customField": "Any key here becomes {{customField}} in templates"
}
}

payload holds routing identity (who receives the notification). variables holds template data (what gets rendered). Keep them separate — only the three payload fields are recognised by the engine; everything else belongs in variables.

FieldTypeRequiredNotes
eventTypestringYesMust match a configured template's event type
eventIdstringNoAuto-generated UUID if omitted
channelsstring[]NoRestricts this dispatch: "EMAIL", "SMS", "PUSH"
payload.userIdstringYesRecipient's ID in your system
payload.recipientEmailstringNoRequired for email channel
payload.recipientPhonestringNoRequired for SMS (E.164 format)
variablesobjectNoArbitrary key/value pairs. Every key is available as {{fieldName}} in template content and subject lines. For global.* event types, include at least title and message.

Success response (200)

{
"success": true,
"message": "Event order.confirmed dispatched securely for YourTenantName"
}

Error responses

StatusErrorCommon cause
401UnauthorizedInvalid/missing API key, invalid HMAC signature, inactive tenant
422Validation ErrorMissing eventType, payload, or payload.userId
429Too Many RequestsRate limit exceeded — read Retry-After header
500Internal Server ErrorKafka unavailable, database error
{
"statusCode": 429,
"error": "Too Many Requests",
"message": "Rate limit exceeded for tenant YourApp. Limit: 100/min",
"retryAfter": 45
}

Request a real-time token

POST /api/v1/auth/realtime-token

Issues a Centrifugo connection token for WebSocket push notifications.

Headers

HeaderRequired
Content-TypeYes (application/json)
x-api-keyYes

Request body

{ "userId": "uuid-of-logged-in-user" }

Response

{
"token": "eyJhbGciOiJIUzI1NiIs...",
"channels": [
"global_system#uuid-of-logged-in-user",
"orders#uuid-of-logged-in-user"
]
}

Tokens expire after 2 hours. Refresh before expiry using Centrifugo's getToken callback.


Fetch notification history

GET /api/v1/notifications/{tenantId}/{userId}

Returns the user's in-app notification history (Push channel only).

Headers

HeaderRequired
x-api-keyYes

Query parameters

ParamDefaultDescription
limit50Max items to return
offset0Pagination offset

Response

{
"success": true,
"data": [
{
"id": "notif-uuid",
"type": "order.confirmed",
"title": "Order Confirmed",
"body": "Your order ORD-2026-1234 has been confirmed.",
"status": "UNREAD",
"created_at": "2026-04-22T12:00:00Z"
}
]
}

Mark notification as read

PUT /api/v1/notifications/{tenantId}/{userId}/{notificationId}/read

Headers

HeaderRequired
x-api-keyYes

Response

{ "success": true }

Rate limits

LimitScopeBehaviour
Per-minute limitPer tenantSliding window counter — configurable at provisioning time
Daily capPer tenantResets at midnight UTC

When exceeded, the response includes:

  • HTTP 429 Too Many Requests
  • JSON body with retryAfter (seconds)
  • Retry-After header

Pre-production checklist

Before going live:

  • API Key is stored as an environment variable — never in client-side code
  • Webhook HMAC signing is enabled and tested
  • Error responses (401, 422, 429) are handled gracefully with retries
  • Frontend requests a new Centrifugo token on login and refreshes before expiry
  • Template variables in variables match what your templates expect ({{fieldName}}variables.fieldName)
  • Idempotency is tested: the same event twice returns the same response without duplicate delivery
  • Rate limit behaviour is understood and your backend respects Retry-After headers