The integration quickstart connects registration, event subscriptions and a signed receiver to your application workflow.
Receive application progress, decisions and information-request prompts on your backend. Use signed events to trigger follow-up and reconcile your application records.
Integration setup
Prepare a public HTTPS receiver that preserves raw request bytes, verifies signatures and durably queues accepted events.
Obtain a key with webhooks:manage. Register the receiver and store its one-time secret separately from the API key.
Use the test endpoint to check connectivity and signature verification.
Exercise a real application submission and decision on your test tenant. Check duplicate delivery, ordering, failure recovery and secret rotation before enabling client workflows.
Webhooks call your backend with HTTP POST. They are not browser redirects, and there is no callbackUrl parameter on application creation. For browser handoff use the exact loginUrl returned by the API; redirectPath selects a permitted page inside the Aegis portal. Read API authentication and errors before using the management routes.
Every route requires webhooks:manage. All example identifiers, domains and secrets are placeholders. The signing secret is returned only when you register an endpoint or rotate its secret.
POST /v1/webhooks
Register an endpoint and capture its signing secret once.
Required scope:webhooks:manage.
Request. Send a JSON body.
Field
Type
Description
urlrequired
string
Public HTTPS hostname, port 443, without user information or fragment. IP literals, private/special addresses and redirects are not supported.
eventsrequired
string[]
Nonempty exact event names, or one supported wildcard entry such as application.*, application.decision.* or *. Unknown filters are refused.
Webhook endpoint ID. Store it for management and delivery-history requests.
url
string
Registered public HTTPS destination.
events
string[]
Subscribed exact types or supported wildcard filter.
status
string
enabled or disabled.
description
string
Human-readable label supplied at registration.
createdAt
string
RFC 3339 UTC creation timestamp.
secret
string
Returned only by create and rotate-secret. Store immediately in your secret manager; reads never return it.
Default cap is five endpoints per tenant. A staff-configured bounded override may apply. Exceeding the effective cap returns 400 failed-precondition; invalid URL or subscription returns 400 invalid-argument.
Do not blindly retry after an ambiguous create failure. List endpoints and reconcile the registration before creating another one.
GET /v1/webhooks
List the tenant endpoint registrations without secrets.
Required scope:webhooks:manage.
Request. No request body.
Example request
GET /v1/webhooks HTTP/1.1
Host: aegis-api.theauroraedge.com
Authorization: Bearer aegis_<key-id>_<secret>
New secret, returned once. Store it before completing the receiver rollout.
previousSecretExpiresAt
string
RFC 3339 UTC expiry of the previous secret.
During overlap, deliveries carry one v1 signature per active secret. Accept a match against either secret. At most two secrets are active; another rotation expires the oldest immediately.
Coordinate rotation with receiver deployment. Do not retry it blindly if the response is lost; another rotation changes the overlap.
POST /v1/webhooks/{id}/test
Send a synchronous signed webhook.test event with no applicant data.
Whether the receiver returned a successful 2xx response. Check this even when the API request succeeds.
httpStatus
number
HTTP status returned by the receiver, when it responded.
latencyMs
number
Time taken in milliseconds.
responseSnippet
string
Up to the first 200 bytes of the test receiver response. Returned for diagnostics, not persisted.
sentHeaders
object
Exact outgoing headers for signature diagnostics. Do not write signature values to routine logs.
Uses the same signature format as real events. The test does not increment consecutiveFailures or trigger automatic disabling.
A successful test proves connectivity and signing, not that a real application event or retry has been delivered.
GET /v1/webhooks/{id}/deliveries
Retrieve delivery history for an endpoint, including deliveries that exhausted their retries. Required scope: webhooks:manage. Replace id with your registered endpoint ID and send no body. Use the history to investigate receiver failures and identify events needing reconciliation or staff replay.
Example request
GET /v1/webhooks/wh_123/deliveries
Authorization: Bearer aegis_<key-id>_<secret>
Delivery history excludes signing secrets and signatures. Staff also have access to delivery diagnostics. Re-enabling an endpoint does not replay dead deliveries; arrange replay with your support contact and reconcile the application through the API.
Event catalogue
A transition can emit both a specific event and application.status.changed, with distinct event IDs and sequence numbers. Subscribe only to the information your workflow needs. There is no application.decision.needs_info event; that condition is reported through info_request.raised and a status change to needs_info.
Event
When
Additional data fields
application.submitted
Applicant submission changes from not true to true.
Common application fields only.
application.status.changed
Any application status change.
reason: decision, info_request, pair_change or repair.
application.decision.proposed
Approval proposed; status becomes pending_approval.
action: approve; actorRole; comment (string or null).
application.decision.approved
Second approver countersigns; status becomes active.
Stable event ID across retries and every subscribed endpoint. Not a delivery-attempt ID.
type, apiVersion
string
Catalogue event type and payload API version, initially v1.
occurredAt
string
RFC 3339 UTC time of the state change, for display. Read the application for its current state.
tenantId
string
Tenant routing identity. Validate it against the tenants your receiver expects.
idempotencyKey
string
Equals id. Deduplication identity, distinct from your outbound API Idempotency-Key header.
data.clientId, externalRef
string, string | null
Application ID and your reference. Present on application events only.
data.status, previousStatus
string, string | null
Resulting status and preceding status. previousStatus is null on submitted, or equals status when no status change occurred.
data.sequence
integer
Strictly increasing event allocation number per application. Delayed event creation can make it differ from the chronological order of state changes. Filtered subscriptions can have gaps.
data.actorRole
string, where specified
Role such as analyst, mlro, admin, super_admin or customer. Never a staff email.
data.requestSeq
number, request events
Information-request sequence, distinct from the application event sequence. Other additions are in the catalogue.
Example information request data
{
"clientId": "a1b2c3d4-1111-4222-8333-123456789abc",
"externalRef": "ORDER-88213",
"status": "needs_info",
"previousStatus": "pending",
"sequence": 14,
"requestId": "request_123",
"requestSeq": 1,
"round": 1,
"openItems": 1,
"comment": "Please provide the current licence.",
"items": [{ "itemId": "item_123", "type": "document", "prompt": "Upload the current trade licence." }]
}
The information-request example is the data object inside the same envelope, with type application.info_request.raised. webhook.test instead has data containing only endpointId. Payloads exclude risk ratings, screening/sanctions/adverse-media results, form answers, applicant responses, files and filenames. Staff prompts and applicant-visible comments are included.
The timestamp is Unix seconds for the delivery attempt, not occurredAt. Attempt starts at 1. The signature header contains space-separated v1 values, one per active secret during rotation. Compute HMAC-SHA256 over timestamp, a literal dot and the exact raw body bytes. Do not parse and reserialize JSON before verification.
Capture raw bytes before JSON middleware. Read and validate the timestamp as integer seconds.
Reject timestamps more than 300 seconds before or after your clock.
Calculate the HMAC for each active secret you hold and compare v1 values in constant time.
After verification, parse the signed body and check id and type match their headers and tenantId is expected.
Atomically deduplicate and persist or enqueue the event before acknowledging. A previously accepted event gets 2xx without duplicate work.
Return 2xx quickly, then perform business processing asynchronously. Return failure if you could not persist the event.
Use the secret returned by registration or rotation directly as an opaque UTF-8 string. Do not base64-decode it, hex-decode it or strip a prefix. Pass your active secret strings to this Node.js helper. Verify signatures before parsing JSON; then check the envelope and durably accept the event.
At least once, with duplicates possible and no ordering guarantee, even for one application.
Success
Any HTTP 200 to 299. Redirects are failures and are not followed.
Timeout
5-second connection limit and 10-second total timeout. Persist and acknowledge promptly.
Default attempts
12 attempts including the initial send, bounded by 24 hours from the first attempt. Your service configuration may specify a different bounded attempt limit.
Backoff
Nominal retry delays: 30s, 1m, 2m, 4m, 8m, 16m, 32m, 64m, 128m, 256m, then 6h. Each delay is randomly selected between half and all of its nominal value.
Elapsed time
Nominal total 14h 31m 30s for 12 attempts; jitter usually shortens it. The 24-hour bound covers delayed delivery scheduling.
Retry-After
Receiver 429 and 503 can supply Retry-After. A valid value is honored within the delivery cap; otherwise the normal retry schedule applies.
Dead letter
Exhausted deliveries become dead, visible to staff and tenant. No automatic replay after exhaustion.
Receiver 410
Immediately disables the endpoint, with a reason explicitly identifying HTTP 410.
Other automatic disabling
20 consecutive deliveries reach dead, or at least one dead delivery with no success for 24 hours. Staff are notified.
Use events to trigger reconciliation, not to overwrite current status
Deduplicate by the verified event ID and process every unseen event. A higher sequence identifies a later allocation, not necessarily a newer status: an event can be generated after the underlying state has changed again. Fetch GET application for current status. Serialize this reconciliation per clientId so concurrent reads cannot overwrite each other out of order.
Store deduplication durably across receiver restarts. If multiple endpoints serve independent workflows, scope deduplication by the workflow or endpoint as well as event ID. Do not assume a redelivery arrives within the five-minute signature window; the delivery timestamp is distinct from the event time. Retain deduplication records for the agreed retry and manual-replay horizon.
Receiver operations and recovery
After a failure, inspect delivery history, fix the receiver, test a signed request and re-enable if needed. Arrange staff replay for dead deliveries. Read known applications after an outage and use the application list with updatedSince to sweep a window of changes. Overlap windows and deduplicate by clientId.
Use a public HTTPS hostname on port 443. No IP-literal URL, user information, fragment or private/special address is accepted. The destination is validated at registration, update and every delivery. Receiver response bodies are not persisted for real events; only the test endpoint returns a short diagnostic snippet. Log event IDs and outcomes instead of signatures, secrets or payload contents.
For rotation, capture the new secret, deploy verification with overlap and remove the old key only after previousSecretExpiresAt. API-key rotation has no such webhook grace period. Track contract changes in the changelog.