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.
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
The event-driven architecture fires webhooks the moment an event occurs, so downstream systems stay in sync without polling.
Go beyond technical integration — create a CRM record on registration, notify a fulfilment system, or kick off onboarding.
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
The following flowchart illustrates how a webhook is triggered when a user account is modified:
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.
Create and manage webhooks interactively in the cidaas administration hub — pick events, set the URL, and choose how the endpoint is secured.
Follow an Infrastructure-as-Code approach and provision webhook setups programmatically with the cidaas webhook APIs.
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_type | Security level | How it works |
|---|---|---|
APIKEY | low | cidaas 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. |
TOTP | medium | cidaas 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_OAUTH2 | high | cidaas 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. |
- cidaas OAuth2 (recommended)
- TOTP
- API Key
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.
NON_INTERACTIVE (machine-to-machine) app with grant type client_credentials only. This produces the client_id / client_secret.webhook:applogs) under Permission Setup → Scopes and assign it to the app.client_id in cidaasAuthDetails with auth_type: CIDAAS_OAUTH2.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_credentialsonly — 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:
- Signature — verify the JWT signature against the cidaas JWKS (
https://<your-cidaas-host>/.well-known/jwks.json); cache the keys. - Issuer (
iss) — must match your cidaas host. - Expiry (
exp) / not-before (nbf) — reject expired tokens (allow small clock skew). - Scope — require the dedicated scope you assigned (e.g.
webhook:applogs). This proves the caller is your webhook app. - Client (optional) — pin
aud/client_idto 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).
With TOTP, cidaas sends a time-based one-time password generated from a pre-shared key. Your endpoint validates the TOTP using the same key.
- Configure the shared TOTP key in the webhook setup.
- Each TOTP is valid only once, within a short time window (a few seconds), which protects against replay.
- Your endpoint recomputes the expected TOTP from the shared key and compares it to the value received with the request.
TOTP offers a medium security level — stronger than a static API key, but without the token-based, scope-aware guarantees of cidaas OAuth2.
With APIKEY, cidaas sends a pre-shared static key with each request. Your endpoint verifies it before accepting the event.
- Configure the key in the webhook setup, and choose whether cidaas places it in a header or query parameter (and the parameter name).
- Because the key is static, this is the lowest security level — recommended only for already-secured networks or low-risk environments.
- Rotate the key periodically and treat it as a secret.
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:
| Field | Type | Description | Example |
|---|---|---|---|
eventtype | string | The type of event that occurred | "APP_MODIFIED", "ACCOUNT_MODIFIED", "LOGIN_WITH_CIDAAS" |
createdTime | string (ISO 8601) | The exact time when the event was created or triggered | "2025-01-15T10:30:00.000Z" |
client_id | string | The identifier of the client that triggered the event (e.g., admin tool, API integration, or automated system) | "cc2dd2ed-57f1-4a5d-85f2-e868c98db3d7" |
tenantKey | string | Specifies the tenant (customer or environment) the event belongs to. Useful in multi-tenant systems | "cidaas-your-tenant-name-test" |
actorId | string | The ID of the user or service that performed the action | "admin-user-id-123" |
metaData | object | A flexible field that holds event-specific information. Structure and content depend on the eventtype | For "APP_MODIFIED": {"client_id": "modified-app-client-id"} |
objectId | string | The ID of the main object affected by the event. Often, but not always, duplicates information in metaData | "app-id-456" |
objectType | string | Specifies 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.
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:
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:
- User Account Created
- App Created
{
"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"
}
{
"eventtype": "APP_CREATED",
"sub": "admin-user-id-123",
"createdTime": "2025-10-01T08:23:47.451+0000",
"client_id": "cc2dd2ed-57f1-4a5d-85f2-e868c98db3d7",
"tenantKey": "cidaas-your-tenant-name-test",
"userId": "admin-user-id-123",
"actorId": "admin-user-id-123",
"metaData": {
"client_id": "new-app-client-id"
},
"objectId": "new-app-id-456",
"objectType": "apps"
}
Next steps
Please contact us directly on our support page or reach out to cidaas support at [email protected].