Skip to content

Emit audit events

Record an event from your application code. The smplkit SDK is fire-and-forget by default — calls return immediately, the SDK buffers in memory, flushes periodically, retries with backoff, and de-duplicates on idempotency key.

SDK

python
from smplkit import SmplClient

with SmplClient(environment="production", service="checkout") as client:
    client.audit.events.create(
        event_type="order.placed",
        resource_type="order",
        resource_id="o-9876",
        data={
            "snapshot": {
                "customer_id": "c-1234",
                "total_cents": 8990,
            },
            "ip": request.remote_addr,
        },
    )

The same surface is exposed in every smplkit SDK. See your SDK's README for per-language idioms.

The event has a single data field for whatever JSON payload you want to attach. There is no separate snapshot field — to record a snapshot of the resource's state, place it inside data (smplkit's own services use data.snapshot for consistency, but the shape is unconstrained — pick whatever convention fits your data).

Slug rules

event_type and resource_type are slugs — they're surfaced in the Activity tab dropdowns, in URLs, and in your SIEM-side searches. The audit service rejects any value that isn't slug-shaped at write time so the dropdowns stay clean.

The rules:

  • 1 to 100 characters.
  • Lowercase letters, digits, dots, hyphens, and underscores only — [a-z0-9._-]+.
  • Cannot start or end with . or -. Underscores at the boundaries are fine.
  • The smpl. prefix is reserved for smplkit-emitted events. Customer credentials writing a resource_type that begins with smpl. get a 403.

Valid:

order
order.placed
api-key.rotated
user.login_failed
config_item.updated

Rejected (400 Bad Request):

Order              # uppercase
order placed       # whitespace
.order             # leads with a dot
order-             # ends with a hyphen
                   # over 100 chars

The error response identifies which attribute failed and why, so a confused caller can map back to the call site quickly.

Idempotency

Pass idempotency_key to safely retry without recording duplicates:

python
client.audit.events.create(
    event_type="order.shipped",
    resource_type="order",
    resource_id="o-9876",
    idempotency_key="order-9876-shipped",
)

A retry with the same key returns the original event. Useful when you have a natural idempotency key in your domain (an order id with a status, a webhook event id) — cleaner than relying on the auto-generated content hash.

REST

If you can't use an SDK, post directly:

bash
curl -X POST https://audit.smplkit.com/api/v1/events \
  -H "Authorization: Bearer $SMPLKIT_API_KEY" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "event",
      "attributes": {
        "event_type": "order.placed",
        "resource_type": "order",
        "resource_id": "o-9876",
        "data": { "snapshot": { "customer_id": "c-1234", "total_cents": 8990 } }
      }
    }
  }'

Returns 201 the first time, 200 on a duplicate matched by idempotency key. See API Reference — Audit for the full schema, query parameters, and pagination.