LaserData Cloud
API Reference

Audit

Read tenant audit records and the resource details attached to each event

API Variables
ld-api-key
{tenant_id}

Set variables to auto-fill all examples and run requests in-browser.

Audit in the Console records tenant activity. Use these endpoints through the main API at https://api.laserdata.cloud for programmatic access. Records are appended without changing earlier entries.

The audit log and its event types require audit:read. Deployment activity can also be read with deployment:activity:read, for the environments where the caller holds it.

Event Types

List Audit Event Types

GET
/audit/types

List all supported audit event type identifiers.

bash
curl https://api.laserdata.cloud/audit/types \
-H "ld-api-key: YOUR_API_KEY"

Audit Log

Query Tenant Audit Log

GET
/audit/tenants/{tenant_id}

Query the full audit log for a tenant, with filtering and pagination.

bash
curl "https://api.laserdata.cloud/audit/tenants/{tenant_id}?page=1&results=10" \
-H "ld-api-key: YOUR_API_KEY"
{
  "items": [
    {
      "type": "deployment_created",
      "name": "Deployment Created",
      "author": { "id": 608123456789012345, "name": "Jane Smith" },
      "api_key": { "id": 67890, "name": "ci-deploy-key" },
      "user": null,
      "division": { "id": 615380456123456790, "name": "Platform Engineering" },
      "environment": { "id": 615380456123456791, "name": "production" },
      "deployment": { "id": 611298765432109056, "name": "events-prod" },
      "data": {
        "cloud": "aws",
        "area": "us",
        "region": "us-east-1",
        "variant": "managed",
        "tier": "large",
        "cluster_kind": "standalone",
        "public_ip": "static",
        "storage_type": "network_balanced",
        "storage_size": 500,
        "target_network_tput": 10000,
        "encrypted": true,
        "protected": true,
        "retention": { "telemetry": { "logs_days": 90, "metrics_days": 90, "heartbeats_days": 90 } },
        "code": "abc123",
        "name": "events-prod",
        "domain": "events-prod-abc123.laserdata.cloud",
        "nodes": [
          {
            "id": 610809900976570889,
            "name": "node-1",
            "image_id": "ami-0abc123",
            "variant": "ubuntu_x64",
            "storage_type": "network_balanced"
          }
        ]
      },
      "correlation_id": "8f4a2b6c9d1e4f3a8b5c7d9e0f1a2b3c",
      "timestamp": "2025-01-15T10:30:00Z"
    }
  ],
  "page": 1,
  "total_results": 1,
  "total_pages": 1
}

Entries use the SDK's TenantAuditInfo structure:

FieldDescription
typeEvent type slug (e.g. deployment_created, member_invited, access_rule_added)
nameHuman-readable label for the event type
authorThe human who triggered the action. {id, name} or null for system events. Always set when an interactive session or an API key is involved (the user that owns the key).
api_keyThe API key that authored the call when the action came from automation. Omitted for actions taken from an interactive Console session. {id, name}. Lets you tell direct user activity apart from key-driven activity for SOC 2 / ISO machine-identity tracking.
userThe user the action was performed on (member operations, role assignments). null when not applicable
division / environment / deploymentResource scope. Each is {id, name} or null depending on what the event touches
dataEvent-type-specific payload. Shape varies per event (see below). Can be null for events without an extra payload
correlation_idUUID linking this event to others triggered by the same request or workflow. null if untracked
timestampISO 8601 time when the event was recorded

data contains event-specific details:

  • deployment_created records {cloud, area, region, variant, tier, cluster_kind, public_ip, storage_type, storage_size, target_network_tput?, encrypted, protected, retention, code, name, domain?, nodes[]}. Each node includes id, name, image_id, variant, storage_type.
  • deployment_upgraded records {from_tier, to_tier, from_storage, to_storage}.
  • deployment_data_access_updated records {data_access_enabled, previous_data_access_enabled}.
  • deployment_metadata_sync_updated records {metadata_sync_enabled, previous_metadata_sync_enabled, metadata_purged}.
  • deployment_renamed records {name, previous_name}.
  • deployment_moved records {environment_id, previous_environment_id} under the environment the deployment moved to.
  • deployment_deleted records {name, code, reason?}.
  • access_rule_added and access_rule_deleted record {cidrs, description?, rules}, including protocol toggles.
  • member_invited records {email, roles}.
  • api_key_created and api_key_deleted record {name, role_id, division_id?}.
  • config_activated records {config_id, kind, name, version}.
  • connector_activated and connector_deleted record {connector_type, connector_key, instance_key, instance_id, version}. connector_type is source or sink. connector_key identifies the catalog plugin, and instance_key is its deployment-specific hyphenated name. instance_id is numeric, and version is the plugin SemVer. The owning deployment, environment, and division appear in the top-level scope fields.

Use /audit/types to retrieve the complete event-type list for your tenant.

Query ParameterDescription
pagePage number
resultsItems per page (max 100)
fromStart time (ISO 8601)
toEnd time (ISO 8601)
userFilter by subject user id
authorFilter by acting user id
api_keyFilter by API key id (only events authored via that key)
divisionFilter by division id
environmentFilter by environment id
deploymentFilter by deployment id
typesComma-separated list of event types to include
correlation_idFind all events sharing a correlation UUID

Deployment Activity

Query Deployment Activity

GET
/audit/tenants/{tenant_id}/activities

Query the changes applied inside the tenant's deployments: streams, topics, partition counts, consumer groups, Iggy users, and personal access tokens.

bash
curl "https://api.laserdata.cloud/audit/tenants/{tenant_id}/activities?division={division_id}&page=1&results=20" \
-H "ld-api-key: YOUR_API_KEY"
{
  "items": [
    {
      "id": 4405,
      "division": { "id": 4402, "name": "Platform Engineering" },
      "environment": { "id": 4403, "name": "production" },
      "deployment": { "id": 4404, "name": "events-prod" },
      "kind": "change",
      "source": {
        "kind": "iggy",
        "log_id": "0000000000000000000000000000002a",
        "op": 128
      },
      "resource": "topic",
      "action": "partitions_changed",
      "requested_op": 127,
      "actor": { "id": 3, "name": "orders-service" },
      "stream_id": 3,
      "topic_id": 2,
      "resource_name": "telemetry",
      "details": { "partitions_count": 12, "previous_partitions_count": 8 },
      "timestamp": "2026-10-13T10:00:00.000000Z",
      "received_at": "2026-10-13T10:00:01.250000Z"
    }
  ],
  "page": 1,
  "total_results": 1,
  "total_pages": 1
}

Deployment activity includes applied Iggy changes, retained AGDX authorization events, and the AGDX changes the managed backend recorded in its audit log. Metadata sync supplies these records. An initial sync or a rebuilt baseline creates no synthetic resource-created entries. The managed backend writes its audit log as a new log in the deployment's ops stream, and Warden reads it from its start, so the changes made through the managed backend appear with their actor and time. Changes made before the deployment ran a managed backend that writes this log are not in it. Entries are kept for the life of the organization, like audit records, and so are the Iggy usernames that name their actors. Deleting a deployment's synced metadata through Update Metadata Sync, or deleting the deployment, does not remove them.

Callers with audit:read see every entry of the tenant. Other callers must pass division and see only the environments in it where they hold deployment:activity:read. The built-in developer role has it, viewer does not. Members read back as far as their plan's audit retention allows.

FieldDescription
idEntry id. Entries with the same timestamp are ordered by it
division / environment / deployment{id, name} of the scope when the change was applied. A later move or rename does not change it
kindchange for a recorded event, gap for incomplete coverage, or skipped for an entry that could not be stored
sourceTagged source evidence. Its kind is iggy, agdx_authorization, or plane_audit. See the source shapes below
resourcestream, topic, consumer_group, user, personal_access_token, managed_role, role_binding, filter, filter_binding, projection, fork, or schema. Absent when an entry has no single resource
actioncreated, updated, deleted, partitions_changed, password_changed, permissions_updated, defined, or bindings_updated
requested_opFor a delete or partition change that Iggy completed later, the operation that requested it
actor{id, name} of the Iggy user that made the change, with the newest username the audit service knew when it stored the entry. A later user incarnation corrects an earlier attribution to a reused id. On filter, filter binding, projection, schema, and fork entries it is the Iggy user whose request the managed backend applied. The root user is id 0. Absent when no actor is recorded, such as Iggy expiring a token, the managed backend deleting a fork on its own, or Iggy removing a deleted stream's bindings. This is an Iggy user, not a Console member. name is null until the user's name reaches the audit service, usually within a minute
agentOn filter, filter binding, projection, schema, and fork entries, the agent id the client's connection declared when it made the change over the binary protocol, as a Laser SDK agent declares itself. A claim the client makes, which nothing verifies. Absent for changes made over HTTP and for every other entry
member{id, name} of the Console member who made a filter, filter binding, projection, schema, or fork change from the Console's data view, which writes as one shared Iggy user named in actor. name is the member's email when the audit service knows it, else null. Absent for every other change, including native Iggy changes made from the Console
user{id, name} of the Iggy user that a user entry changed, or of the token owner in a personal_access_token entry
stream_id, topic_idIggy stream and topic ids. A filter binding entry carries both. Use the activity entry id as the row identity
resource_id / resource_created_at / resource_nameNative Iggy resource id, its creation time when known, and its name. The existing numeric id retains its meaning. User ids and names also appear in user. On AGDX entries resource_name is present only for a filter, a projection, a schema, or a filter binding's consumer group, whose names differ from their keys. A filter's name is the one its caller gave it, also for the filter a consumer group policy creates and for every later change to it. A dropped projection or schema keeps the name it had
resource_keyAGDX resource identity, such as a role name, a role binding's user id, a filter or schema id, a filter binding's stream_id:stream_created_at:topic_id:topic_created_at:group_id, or a projection or fork identifier. A filter binding key carries the stream's and topic's creation times in microseconds since the Unix epoch, so a group recreated with reused ids gets a new key. A projection binding entry is keyed by its projection, or by index:<name> when the binding names only an index. Absent on native Iggy entries
detailsWhat changed. See below
timestampRecorded event time, in RFC 3339. On filter, filter binding, projection, schema, and fork entries it is when the managed backend applied the change
received_atWhen the audit service stored the entry

details holds only what applies: previous_name after a rename, partitions_count and previous_partitions_count, removed_partition_ids, changed_options with the names of the options an update changed, a user's or a filter revision's status (active or inactive), reason (updated or resource_deleted for permissions, deleted or expired for tokens), a token's expiry, a gap's from and to, and a skipped entry's skipped_kind and skipped_reason. Previous values appear only when they are known to be exact. A change replayed during a rebuild can come without them, because the rebuild may have read the resource after that change. Configuring a group's filter again under a new name records a filter updated entry with changed_fields set to ["name"] and the old name in previous_name. AGDX details can also include changed_fields, bound role names in roles, a missing revision range in from_revision and to_revision or the filter revision a change concerns in to_revision alone, the filter a binding uses in filter_id, a projection or schema version, the names of the stream and topic a projection binding reads or a filter binding's group belongs to in source_stream and source_topic, a fork's parent, and the kind of a projection (row or graph) or a fork (severed or continuous) in resource_kind, which is unrecognized for a kind Warden does not know. An AGDX gap carries its cause as a code in gap_reason, and its source.kind says which history it belongs to. Authorization gaps use baseline_missing, history_changed, history_behind, events_evicted, incomplete, forbidden, unsupported, too_large, or unreadable. plane_audit gaps use history_changed when the ops stream or its audit topic was recreated, events_evicted when retention removed records from the log before they were read, and forbidden, unreadable, incomplete, or too_large when a read failed. A plane_audit record that cannot be decoded becomes a skipped entry, and the records after it still apply. Entries never carry passwords, token values, permission sets, option values, filter policies, projection definitions, schema bodies, key-value values, or messages.

The source shapes are:

source.kindFieldsCoverage
iggylog_id as 32 hex digits, opPosition of an applied Iggy metadata record
agdx_authorizationmetadata_log_id as 32 hex digits, revisionRetained role and binding events. The metadata identity is collection-time reset evidence, not the event's historical log position
plane_auditlog_id as 32 hex digits, offsetApplied filter, filter binding, projection, schema, and fork changes from the managed backend's audit log on the deployment's ops stream, _agdx. log_id identifies that log and changes when the ops stream or its audit topic is recreated, and offset is the record's position in it

Use the entry id to identify a row. Authorization history retains a bounded set of events, so older changes can be unavailable. The managed backend's audit log does not expire by default. If its retention is changed and records are removed before Warden reads them, activity shows an events_evicted gap. Recreating the ops stream or its audit topic loses the records the log held, reported as one history_changed gap. A change the managed backend refused is not activity. Gap entries report known coverage loss.

Query ParameterDescription
pagePage number
resultsItems per page (max 100)
fromInclusive start time (RFC 3339)
toExclusive end time (RFC 3339)
divisionFilter by division id. Required without audit:read
environmentFilter by environment id
deploymentFilter by deployment id
kindchange, gap, or skipped
resourceFilter by resource
actionFilter by action

Entries come newest first. A member who needs a division filter but omits division gets 400 with a validation error naming it. A caller without access to the requested division or environment gets 403.

On this page