IdenIden Docs
API ReferenceEvents

SIEM Integration Guide

Integrate Iden security events into your SIEM platform using the Events API.

Iden captures security-relevant events across your identity governance workflows: logins, access changes, app syncs, account provisioning, and more. The Events API lets you stream these into your SIEM platform (Splunk, OpenSearch, Microsoft Sentinel, Datadog, etc.) for centralized monitoring and incident response.

Rate Limit

The Events API is limited to 60 requests per minute per API key. Exceeding this returns 429 Too Many Requests with a Retry-After header. At the recommended polling interval of 30–60 seconds, you'll use 1–2 requests per minute, well within the limit. See Rate Limiting for details.

Quick Start

1. Get your API key

Go to Settings → API Keys in your Iden dashboard (app.idenhq.com/api-keys or app.in.idenhq.com/api-keys depending on your data residency region). Create a key and note your organization slug (visible on the same page).

2. Fetch your first events

curl -H "Authorization: Api-Key YOUR_KEY" \
  "https://developer.idenhq.com/org/{your-slug}/api/events/?limit=5"

3. Set up incremental polling

Use cursor-based pagination to poll for new events without missing any or receiving duplicates.

import requests
import time

API_KEY = "YOUR_KEY"
BASE_URL = "https://developer.idenhq.com/org/{your-slug}/api/events/"
cursor = None

while True:
    params = {"limit": 200}
    if cursor:
        params["cursor"] = cursor

    resp = requests.get(
        BASE_URL,
        headers={"Authorization": f"Api-Key {API_KEY}"},
        params=params,
    )
    resp.raise_for_status()
    data = resp.json()

    for event in data["results"]:
        push_to_siem(event)  # your SIEM ingestion function

    cursor = data.get("next_cursor")
    if not data["results"]:
        time.sleep(60)  # no new events, wait before polling again

The response includes next_cursor and previous_cursor. Pass next_cursor as the cursor parameter in your next request. When results is empty, wait 60 seconds before polling again.


Event Envelope

Every event returned by the API follows the same JSON structure:

{
  "event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "event_type": "session.login.succeeded",
  "event_version": 1,
  "category": "authentication",
  "severity": "low",
  "occurred_at": "2026-04-08T14:30:00.000Z",
  "ingested_at": "2026-04-08T14:30:00.123Z",
  "actor": {
    "type": "user",
    "uuid": "11111111-1111-1111-1111-111111111111",
    "ip": "203.0.113.42",
    "user_agent": "Mozilla/5.0 ..."
  },
  "subject": {
    "type": "iden_user",
    "uuid": "11111111-1111-1111-1111-111111111111"
  },
  "source": {
    "type": "user_action",
    "uuid": null
  },
  "payload": {
    "login_method": "google"
  }
}

Field Reference

FieldTypeDescription
event_idUUIDGlobally unique event identifier
event_typestringDot-notated event type (e.g. session.login.succeeded). See Event Type Catalog for all types.
event_versionintegerSchema version (currently 1)
categorystringComputed from event type prefix. See Categories.
severitystringComputed severity level. See Severity Mapping.
occurred_atISO 8601When the event happened
ingested_atISO 8601When Iden recorded the event
actorobjectWho or what triggered the event
actor.typestringuser, system, service, or iden_admin
actor.uuidUUIDActor's Iden user UUID. null for system-triggered events.
actor.ipstringIP address of the actor (when available)
actor.user_agentstringBrowser/client user agent (when available)
subjectobjectThe entity the event is about
subject.typestringiden_user, app_user, app, app_group, task, ticket, or system
subject.uuidUUIDUUID of the subject entity
sourceobjectWhat triggered the event
source.typestringuser_action, system, sync, schedule, api, or task
payloadobjectEvent-specific data. See Event Type Catalog for payload fields per event type.

Pagination

The Events API uses cursor-based pagination for reliable incremental polling. This ensures you never miss events or receive duplicates, even if new events are created while you're paginating.

{
  "next_cursor": "cD0yMDI2LTA0LTA4VDE0...",
  "previous_cursor": "cD0yMDI2LTA0LTA4VDE0...",
  "results": [...]
}
ParameterTypeDefaultMaxDescription
cursorstring--Opaque cursor from a previous response
limitinteger50200Number of events per page

Events are returned in reverse chronological order (newest first). To poll for new events, store the next_cursor from your last successful response and pass it in subsequent requests.


Filtering

Use query parameters to narrow results. All filters can be combined.

By event type (exact)

Filter for a specific event type. See the Event Type Catalog for all available values.

GET /api/events/?event_type=session.login.succeeded

By event type prefix

The prefix must end with . (this prevents partial matches).

# All session events (login, logout, expired, blocked)
GET /api/events/?event_type_prefix=session.

# All app sync events
GET /api/events/?event_type_prefix=app.sync.

# All account lifecycle events
GET /api/events/?event_type_prefix=account.

# All access ticket events (created, approved, denied)
GET /api/events/?event_type_prefix=ticket.

# All API key events (created, revoked, used)
GET /api/events/?event_type_prefix=api_key.

# All user lifecycle events
GET /api/events/?event_type_prefix=user.

By category

Filter by logical category. Each category maps to one or more event type prefixes. See Categories for the full mapping.

# All authentication events (session.*, warp.*, api_key.*)
GET /api/events/?category=authentication

# All authorization events (account.*, ticket.*)
GET /api/events/?category=authorization

# All application events (app.*)
GET /api/events/?category=application

# All user identity lifecycle events
GET /api/events/?category=user_lifecycle

By severity

Comma-separated list of severity levels. See Severity Mapping for which events map to which level.

# Critical and high only
GET /api/events/?severity=critical,high

# Medium and above
GET /api/events/?severity=critical,high,medium

By time range

ISO 8601 timestamps.

GET /api/events/?occurred_at__gte=2026-04-01T00:00:00Z&occurred_at__lte=2026-04-08T23:59:59Z

By actor or subject

# Events triggered by a specific user
GET /api/events/?actor_uuid=a1b2c3d4-...

# Events about a specific entity
GET /api/events/?subject_uuid=a1b2c3d4-...

# Events from a specific IP address
GET /api/events/?actor_ip=203.0.113.42

Filter Parameters Reference

ParameterTypeExampleDescription
event_typestringsession.login.succeededExact match. See Event Type Catalog.
event_type_prefixstringsession.Prefix match (must end with .).
categorystringauthenticationCategory filter. See Categories.
severitystringcritical,highComma-separated. See Severity Mapping.
occurred_at__gteISO 86012026-04-01T00:00:00ZEvents at or after this timestamp
occurred_at__lteISO 86012026-04-08T23:59:59ZEvents at or before this timestamp
actor_uuidUUIDa1b2c3d4-...Filter by actor UUID
subject_uuidUUIDa1b2c3d4-...Filter by subject UUID
actor_ipstring203.0.113.42Filter by actor IP address

Categories

Events are grouped into categories based on the event type prefix. Use the category filter parameter to query by category.

CategoryPrefixesDescription
authenticationsession.*, warp.*, api_key.*Login, logout, session expiry, IP blocks, browser/API based app connections, and API key usage
authorizationaccount.*, ticket.*Account provisioning, deprovisioning, suspension, access tickets, and group membership changes
applicationapp.*App connections, syncs, disconnections, and configuration changes
tasktask.*Task lifecycle
user_lifecycleuser.*IdenUser lifecycle: creation, profile updates, deactivation, reactivation and deletion

Severity Mapping

Severity is computed from the event type. Use the severity filter to query by level. Events not listed below default to info.

Critical

Event TypeDescription
session.ip_blockedIP address blocked after repeated failed login attempts

High

Event TypeDescription
session.login.failedFailed login attempt
task.failedTask failed
ticket.deniedAccess ticket denied
user.deactivatedIdenUser account deactivated
account.deprovisionedUser account deprovisioned (access removed)

Medium

Event TypeDescription
app.sync.failedApp sync failed
task.dispatch_blockedTask blocked from dispatch

Low

Event TypeDescription
session.login.succeededSuccessful login
session.logoutUser logged out
task.completedTask completed
user.updatedIdenUser profile updated
app.createdNew app connected

Info (default)

All other event types.


Event Type Catalog

A complete reference of all event types available through the Events API.

Authentication

Session

Event TypeDescription
session.login.succeededUser successfully logged in
session.login.failedFailed login attempt
session.logoutUser logged out
session.ip_blockedIP address blocked after repeated failed login attempts
session.expiredSession expired

Warp

Event TypeDescription
warp.login.attemptedBrowser/API based app login initiated via Warp
warp.login.failedBrowser/API based app login failed via Warp

API Keys

Event TypeDescription
api_key.createdLighthouse API key created
api_key.revokedLighthouse API key revoked or deleted
api_key.usedLighthouse API key used to authenticate a request

Authorization

Account Lifecycle

Event TypeDescription
account.provisionedUser account granted access to an app
account.deprovisionedUser account removed from an app
account.activatedUser account activated in an app (went from invited state to active)
account.suspendedUser account suspended in an app
account.unsuspendedSuspended user account reactivated
account.group.addedUser account added to an app group
account.group.removedUser account removed from an app group

Tickets

Event TypeDescription
ticket.createdAccess request ticket created
ticket.approvedAccess request ticket approved
ticket.deniedAccess request ticket denied

Application

Event TypeDescription
app.createdNew app connected to Iden
app.connectedApp connection established successfully
app.disconnectedApp disconnected from Iden
app.sync.startedApp sync initiated
app.sync.completedApp sync completed successfully
app.sync.failedApp sync failed
app.sync.pausedApp sync paused
app.connection_request.createdNew app connection request submitted

Task

Event TypeDescription
task.createdTask created in the system
task.dispatchedTask dispatched to a runner
task.completedTask completed successfully
task.failedTask failed
task.retriedTask retried after failure
task.preemptedTask preempted by a higher-priority task
task.cancelledTask cancelled
task.dispatch_blockedTask blocked from dispatch due to a conflict

Identity

Event TypeDescription
user.createdIdenUser created in the system
user.updatedIdenUser profile updated (domain type or manager changed)
user.deactivatedIdenUser account deactivated
user.reactivatedIdenUser account reactivated
user.deletedIdenUser hard-deleted from the system
user.identity_type.changedIdenUser identity type changed (e.g. humanservice_account)

Rate Limiting

The Events API is rate-limited to 60 requests per minute per API key. A global rate limit of 300 requests per minute per IP also applies across all Lighthouse endpoints.

When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait.

HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json

{"detail": "Request was throttled. Expected available in 42 seconds."}

At a recommended polling interval of 30–60 seconds with limit=200, you will use 1–2 requests per minute, well within the limit.


SIEM Platform Examples

These examples use the incremental polling pattern from Quick Start.

OpenSearch / Elasticsearch

Index each event by event_id to ensure idempotent ingestion. Use monthly indices for lifecycle management.

from opensearchpy import OpenSearch

client = OpenSearch(["https://your-cluster:9200"])

for event in events:
    index = f"iden-events-{event['occurred_at'][:7]}"  # e.g. iden-events-2026-04
    client.index(
        index=index,
        id=event["event_id"],  # idempotent; re-ingesting the same event is a no-op
        body=event,
    )

Splunk (HEC)

Use the HTTP Event Collector with event_id as a unique identifier and occurred_at as the event time.

import requests

HEC_URL = "https://your-splunk:8088/services/collector/event"
HEC_TOKEN = "your-hec-token"

for event in events:
    requests.post(
        HEC_URL,
        headers={"Authorization": f"Splunk {HEC_TOKEN}"},
        json={
            "time": event["occurred_at"],
            "sourcetype": "iden:siem:event",
            "event": event,
        },
    )

Microsoft Sentinel

Use an Azure Logic App or Function App to poll the Iden Events API and push events via the Azure Monitor Data Collector API.

Datadog

Use a custom integration script that polls the Events API and sends events via the Datadog Logs API (POST /api/v2/logs).


Best Practices

  1. Poll every 30–60 seconds with limit=200 for near-real-time ingestion without hitting rate limits.
  2. Always use cursor pagination. Never use time-based offsets, which can miss events or produce duplicates.
  3. Store your cursor persistently (database, file, etc.) so you can resume after restarts without re-ingesting.
  4. Use event_id as the deduplication key in your SIEM. This ensures idempotent ingestion even if you accidentally re-poll the same range.
  5. Filter at the source using query parameters rather than fetching all events and filtering client-side.

On this page