Skip to main content
Version: Latest (4.0.3)

Webhook Management

Webhooks let your systems react to what happens in cidaas the moment it happens. When an event such as ACCOUNT_CREATED, LOGIN, or ACCOUNT_MODIFIED occurs, cidaas calls your endpoint asynchronously so you can trigger business actions — not just technical ones — in real time.

Event-driven Asynchronous & non-blocking OAuth2, TOTP or API key secured
Security by design

A cidaas event payload intentionally does not contain personal data or secrets — only enough context (event type, object id, tenant, actor) to let your service call back into cidaas for the details it needs. Grant your webhook app only the scopes it actually requires, and add data-access scopes sparingly.

Why webhooks

React instantly

The event-driven architecture fires webhooks the moment an event occurs, so downstream systems stay in sync without polling.

Automate business actions

Go beyond technical integration — create a CRM record on registration, notify a fulfilment system, or kick off onboarding.

Non-blocking by design

Webhooks run asynchronously and never block processing inside cidaas. If your service is down, it consumes the event once it is back.

How a webhook works

1
Event occurs
A user or system action (e.g. an account is modified) triggers a cidaas event.
2
Setup matched
cidaas checks whether any webhook setup subscribes to that event.
3
POST to your URL
A signed/secured POST request is delivered to your webhook endpoint with the event payload.
4
Acknowledge & process
Your service returns HTTP 200 immediately, then processes the event asynchronously.

The following flowchart illustrates how a webhook is triggered when a user account is modified:

Best practice

Return HTTP 200 OK immediately after receiving the webhook request, then process the event asynchronously. This prevents timeouts for long-running operations and avoids unnecessary retries.

Configuration

You can define webhooks in two ways — both write to the same webhook setup.

Limits

Up to 20 webhooks can be created. Two webhooks cannot share the same URL, and if they do share a URL their event sets cannot overlap.

Securing your webhook

Your webhook endpoint must be protected against unauthenticated access. Each webhook setup is secured with exactly one method, selected via the auth_type field.

auth_typeSecurity levelHow it works
APIKEYlowcidaas sends a pre-shared static API key with each request (in a header or query parameter). Your endpoint verifies it. Recommended only for already-secured or low-risk environments.
TOTPmediumcidaas sends a time-based one-time password (TOTP) generated from a pre-shared key. Your endpoint validates it using the same key. Each TOTP is valid only once, within a short time window.
CIDAAS_OAUTH2highcidaas obtains an OAuth2 access token via the client credentials grant and sends it as a Bearer token. Your endpoint validates the token. Recommended for production.

With CIDAAS_OAUTH2, the cidaas Webhook Service authenticates itself to your endpoint using a cidaas app's client_id and client_secret. Before each delivery it requests an access token from the token endpoint using the client credentials grant, then calls your URL with Authorization: Bearer <access_token>. Your endpoint validates that token before processing the event.

1
Create a non-interactive app
A NON_INTERACTIVE (machine-to-machine) app with grant type client_credentials only. This produces the client_id / client_secret.
2
Assign a dedicated scope
Create a custom scope (e.g. webhook:applogs) under Permission Setup → Scopes and assign it to the app.
3
Create the webhook setup
Reference the app's client_id in cidaasAuthDetails with auth_type: CIDAAS_OAUTH2.
4
Validate the token
On every request, verify the Bearer token's signature, issuer, expiry, and required scope.

1. Create a dedicated non-interactive app

This app produces the client_id / client_secret used to authenticate webhook calls.

  • Application type: NON_INTERACTIVE (Non-Interactive Client / machine-to-machine). See Application types.
  • Grant type: client_credentials only — there are no user redirects or interactive flows for this app.
  • Naming: use a clear, purpose-specific name, e.g. webhook-applogs-<tenant>-test.
  • Scope of use: create a dedicated app for this webhook rather than reusing a general-purpose app, so its access can be reasoned about and rotated independently.

Keep the client_secret on the server side only; see Client secret rotation for rotation guidance.

2. Assign a scope to the app

cidaas issues the webhook token with the scopes granted to this app. Define a dedicated custom scope for this webhook rather than reusing broad ones.

  • Create the scope under Permission Setup → Scopes (see Scope management) and assign it to the app.
  • Custom scopes must not use the cidaas: prefix — that prefix is reserved for system scopes. Use a name matching your own convention, e.g. webhook:applogs.
  • If your webhook only needs to authenticate the caller, a single identifying scope is enough. Add extra data-access scopes only if your handler will call back into cidaas APIs to fetch details.

3. Create the webhook setup referencing the app

Use the Store Webhook Setup API (or Trustdesk) with auth_type: CIDAAS_OAUTH2. The setup stores only the client_id; the client_secret is never placed in the setup or exposed in the event.

{
"auth_type": "CIDAAS_OAUTH2",
"url": "https://applogs-test.example.com/cidaas",
"events": [
"ACCOUNT_CREATED_WITH_CIDAAS_IDENTITY",
"ACCOUNT_MODIFIED"
],
"cidaasAuthDetails": {
"client_id": "<client_id of the app created in step 1>"
}
}

4. Validate the token on your endpoint

On every incoming request, verify the Bearer token before processing the event:

  1. Signature — verify the JWT signature against the cidaas JWKS (https://<your-cidaas-host>/.well-known/jwks.json); cache the keys.
  2. Issuer (iss) — must match your cidaas host.
  3. Expiry (exp) / not-before (nbf) — reject expired tokens (allow small clock skew).
  4. Scope — require the dedicated scope you assigned (e.g. webhook:applogs). This proves the caller is your webhook app.
  5. Client (optional) — pin aud / client_id to the app from step 1 for extra assurance.

For real-time checks that also detect revoked tokens, you can use the Token Introspection API instead of (or in addition to) offline JWT validation. See Validating scopes in tokens for both approaches.

Because failed deliveries are retried, make your handler idempotent (see Webhook response below).

Implement a webhook

Preliminary considerations

  • You implement a webhook as a web service that is secured accordingly. You can secure it with OAuth2 for authentication.
  • You define which cidaas events your webhook consumes in the webhook setup.
  • Your webhook service will be called immediately when one of the events you registered your service for occurs.
  • The information given to the web service by cidaas is limited. It is used to allow you to retrieve additional data from cidaas if necessary to implement the intended use case.
  • In order to get this information from cidaas, you use an app that defines exactly the access you need.
  • Your web service always acknowledges successful processing with http status 200 (OK).
  • If a problem occurs during the execution of your webhook service and the service responds with an http status != 200, then cidaas will log the error and execute the service again. If it is a permanent error, the service will not be executed again.
  • Your service should be designed to be performant; if the execution time is too long, cidaas will not wait for the service response after a specified timeout.
  • Webhooks are called asynchronously:
    • for example, if your webhook service is not available, it will consume the cidaas event after availability
    • this also means that webhooks do not block processing in cidaas

The webhook request

The webhook service is executed as a POST call, passing the following information depending on the event.

The webhookObj is a standardized event payload that provides context about what happened, when, who triggered it, on which tenant, and what was affected. The only dynamic part is the metaData, which varies depending on the specific event type (eventtype).

Structure of webhookObj:

{
"webhookObj": {
"eventtype": "APP_MODIFIED",
"createdTime": "2025-01-15T10:30:00.000Z",
"client_id": "cc2dd2ed-57f1-4a5d-85f2-e868c98db3d7",
"tenantKey": "cidaas-your-tenant-name-test",
"actorId": "admin-user-id-123",
"metaData": {
"client_id": "modified-app-client-id"
},
"objectId": "app-id-456",
"objectType": "apps"
}
}

Field-by-field explanation:

FieldTypeDescriptionExample
eventtypestringThe type of event that occurred"APP_MODIFIED", "ACCOUNT_MODIFIED", "LOGIN_WITH_CIDAAS"
createdTimestring (ISO 8601)The exact time when the event was created or triggered"2025-01-15T10:30:00.000Z"
client_idstringThe identifier of the client that triggered the event (e.g., admin tool, API integration, or automated system)"cc2dd2ed-57f1-4a5d-85f2-e868c98db3d7"
tenantKeystringSpecifies the tenant (customer or environment) the event belongs to. Useful in multi-tenant systems"cidaas-your-tenant-name-test"
actorIdstringThe ID of the user or service that performed the action"admin-user-id-123"
metaDataobjectA flexible field that holds event-specific information. Structure and content depend on the eventtypeFor "APP_MODIFIED": {"client_id": "modified-app-client-id"}
objectIdstringThe ID of the main object affected by the event. Often, but not always, duplicates information in metaData"app-id-456"
objectTypestringSpecifies what kind of object the event was about"apps", "users", "usergroups"

Webhook response

Your webhook service must return HTTP 200 (OK) to indicate successful processing. This is the only status code that cidaas considers as successful completion.

Retries

All other HTTP status codes (e.g., 400, 401, 404, 417, 500) are treated as failures and cidaas will automatically retry the webhook call. A failed delivery is retried up to 3 additional times at intervals of 1 minute, 5 minutes, and 10 minutes. If the error is permanent, cidaas stops retrying. Make your handler idempotent so repeated deliveries are safe.

Successful response (HTTP 200):

Your webhook should return HTTP 200 with an optional response body:

{
"status": 200
}

Or with additional data:

{
"status": 200,
"data": {
"message": "Webhook processed successfully"
}
}

The response body (if provided) is stored in the webhook status and can be viewed in Trustdesk or by using the webhook API.

Available webhooks

cidaas provides a comprehensive set of webhook events across the platform. The events cover the following main categories:

User ManagementAccount creation, login, profile updates, verification
App & SystemApp settings, scopes, templates, webhooks
Groups & RolesGroup operations, user assignments, role changes
Security & AuthLogin failures, token operations, security events
CommunicationSMS, email, push notifications, IVR
VerificationPhysical verification, ID validation, consent
Business OpsCheckout sessions, subscriptions, payments

The interactive table is searchable and filterable, includes full JSON payload examples for every event, and supports one-click copy to clipboard for development.

Quick examples:

{
"eventtype": "ACCOUNT_CREATED_WITH_CIDAAS_IDENTITY",
"sub": "2ecb51cb-ac07-4f1f-98a7-fa61f512918f",
"createdTime": "2025-10-01T08:23:47.451+0000",
"client_id": "cc2dd2ed-57f1-4a5d-85f2-e868c98db3d7",
"tenantKey": "cidaas-your-tenant-name-test",
"userId": "2ecb51cb-ac07-4f1f-98a7-fa61f512918f",
"actorId": "2ecb51cb-ac07-4f1f-98a7-fa61f512918f",
"metaData": {
"provider": "self"
},
"objectId": "2ecb51cb-ac07-4f1f-98a7-fa61f512918f",
"objectType": "users"
}

Next steps

Need Support?

Please contact us directly on our support page or reach out to cidaas support at [email protected].