# API Reference

Base path: `/v1/auditmanager/`. The spec below is rendered from the live [`docs/openapi.json`](https://github.com/OpenG2P/audit-manager/blob/develop/docs/openapi.json). CI regenerates it from the FastAPI app on every `src/`-touching push, so endpoint signatures, response shapes, status-code descriptions, and the error-code catalog stay in lockstep with the code. This page does **not** duplicate any of that in prose.

A running instance also exposes the live spec at `/v1/auditmanager/openapi.json` and interactive UIs at `/v1/auditmanager/docs` (Swagger) and `/v1/auditmanager/redoc`.

## Ingest a single CloudEvent

> Accepts one CloudEvent, validates its schema, and enqueues it for durable publication to Kafka.\
> \
> Returns \*\*202 Accepted\*\* the moment the event lands in the in-process queue — Kafka and Postgres latency are fully hidden from the caller. Delivery from there is at-least-once with idempotent inserts on (\`id\`, \`occurred\_at\`), so replays after a crash never produce duplicate rows in the audit store.

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"paths":{"/v1/auditmanager/events":{"post":{"summary":"Ingest a single CloudEvent","description":"Accepts one CloudEvent, validates its schema, and enqueues it for durable publication to Kafka.\n\nReturns **202 Accepted** the moment the event lands in the in-process queue — Kafka and Postgres latency are fully hidden from the caller. Delivery from there is at-least-once with idempotent inserts on (`id`, `occurred_at`), so replays after a crash never produce duplicate rows in the audit store.","operationId":"ingest_event_v1_auditmanager_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloudEvent"}}},"required":true},"responses":{"202":{"description":"Event accepted into the ingest queue. The `id` you submitted is echoed back.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedResponse"}}}},"422":{"description":"Malformed CloudEvent — failed schema validation (missing required field, invalid `outcome` enum, unparseable `time`, etc.).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service not ready or backpressure.\n\n- `AUD-004` — ingest queue full. Retry with exponential backoff + jitter.\n- `AUD-005` — service startup not complete.\n- `AUD-006` — database health check failed (surfaces via `/health`, but also blocks ingest readiness indirectly).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"CloudEvent":{"properties":{"specversion":{"type":"string","const":"1.0","title":"Specversion","default":"1.0"},"id":{"type":"string","title":"Id"},"source":{"type":"string","title":"Source"},"type":{"type":"string","title":"Type"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"time":{"type":"string","format":"date-time","title":"Time"},"datacontenttype":{"type":"string","title":"Datacontenttype","default":"application/json"},"traceparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Traceparent"},"data":{"$ref":"#/components/schemas/AuditData"}},"additionalProperties":true,"type":"object","required":["source","type","data"],"title":"CloudEvent","description":"CloudEvents v1.0 envelope.\n\nSpec: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md"},"AuditData":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"action":{"type":"string","title":"Action"},"outcome":{"type":"string","enum":["success","failure","denied"],"title":"Outcome"},"resource":{"anyOf":[{"$ref":"#/components/schemas/Resource"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","required":["actor","action","outcome"],"title":"AuditData","description":"OpenG2P-specific `data` shape. Open — extra fields allowed per event type."},"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."},"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."},"AcceptedResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/AcceptedPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"AcceptedResponse"},"AcceptedPayload":{"properties":{"accepted":{"type":"string","title":"Accepted","description":"The `id` of the CloudEvent that was accepted into the ingest queue."}},"type":"object","required":["accepted"],"title":"AcceptedPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."},"ErrorResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response","description":"Always `null` on an error response."},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors","description":"One entry per failure. Always at least one for a non-2xx response."}},"type":"object","required":["responsetime","errors"],"title":"ErrorResponse","description":"Shared shape for every non-2xx response — `response` is null, `errors` is populated."}}}}
```

## Ingest a batch of CloudEvents

> Accepts up to \`ingest.max\_batch\_size\` CloudEvents in a single request. Each event is validated and enqueued independently — same 202 semantics as \`/events\`. Events in the batch are not atomic: on queue overflow part way through, the response reports the count actually accepted.\
> \
> Events in a batch become \*\*separate rows\*\* in Postgres (one per CloudEvent). Batching is a transport optimization — not a storage concept.

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"paths":{"/v1/auditmanager/events/batch":{"post":{"summary":"Ingest a batch of CloudEvents","description":"Accepts up to `ingest.max_batch_size` CloudEvents in a single request. Each event is validated and enqueued independently — same 202 semantics as `/events`. Events in the batch are not atomic: on queue overflow part way through, the response reports the count actually accepted.\n\nEvents in a batch become **separate rows** in Postgres (one per CloudEvent). Batching is a transport optimization — not a storage concept.","operationId":"ingest_batch_v1_auditmanager_events_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventBatch"}}},"required":true},"responses":{"202":{"description":"All events (or as many as fit before backpressure) accepted. The response echoes accepted ids.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAcceptedResponse"}}}},"400":{"description":"`AUD-007` — batch payload exceeds the configured `ingest.max_batch_size`. Split into smaller batches.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Malformed CloudEvent — failed schema validation (missing required field, invalid `outcome` enum, unparseable `time`, etc.).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Service not ready or backpressure.\n\n- `AUD-004` — ingest queue full. Retry with exponential backoff + jitter.\n- `AUD-005` — service startup not complete.\n- `AUD-006` — database health check failed (surfaces via `/health`, but also blocks ingest readiness indirectly).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"EventBatch":{"properties":{"events":{"items":{"$ref":"#/components/schemas/CloudEvent"},"type":"array","title":"Events"}},"type":"object","required":["events"],"title":"EventBatch","description":"Batched ingest payload."},"CloudEvent":{"properties":{"specversion":{"type":"string","const":"1.0","title":"Specversion","default":"1.0"},"id":{"type":"string","title":"Id"},"source":{"type":"string","title":"Source"},"type":{"type":"string","title":"Type"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"time":{"type":"string","format":"date-time","title":"Time"},"datacontenttype":{"type":"string","title":"Datacontenttype","default":"application/json"},"traceparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Traceparent"},"data":{"$ref":"#/components/schemas/AuditData"}},"additionalProperties":true,"type":"object","required":["source","type","data"],"title":"CloudEvent","description":"CloudEvents v1.0 envelope.\n\nSpec: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md"},"AuditData":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"action":{"type":"string","title":"Action"},"outcome":{"type":"string","enum":["success","failure","denied"],"title":"Outcome"},"resource":{"anyOf":[{"$ref":"#/components/schemas/Resource"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","required":["actor","action","outcome"],"title":"AuditData","description":"OpenG2P-specific `data` shape. Open — extra fields allowed per event type."},"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."},"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."},"BatchAcceptedResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/BatchAcceptedPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"BatchAcceptedResponse"},"BatchAcceptedPayload":{"properties":{"accepted":{"items":{"type":"string"},"type":"array","title":"Accepted","description":"CloudEvent ids accepted into the ingest queue, in the order supplied."},"count":{"type":"integer","title":"Count","description":"Number of events accepted (matches `len(accepted)`)."}},"type":"object","required":["accepted","count"],"title":"BatchAcceptedPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."},"ErrorResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response","description":"Always `null` on an error response."},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors","description":"One entry per failure. Always at least one for a non-2xx response."}},"type":"object","required":["responsetime","errors"],"title":"ErrorResponse","description":"Shared shape for every non-2xx response — `response` is null, `errors` is populated."}}}}
```

## Health / readiness probe

> Combined liveness + readiness probe. Returns \*\*200\*\* with \`status: UP\` only when service startup is complete \*\*and\*\* the Postgres connection is healthy. Kubernetes probes in the shipped Helm chart point at this endpoint.

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"paths":{"/v1/auditmanager/health":{"get":{"summary":"Health / readiness probe","description":"Combined liveness + readiness probe. Returns **200** with `status: UP` only when service startup is complete **and** the Postgres connection is healthy. Kubernetes probes in the shipped Helm chart point at this endpoint.","operationId":"health_v1_auditmanager_health_get","responses":{"200":{"description":"Service is ready to serve traffic.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"Not ready.\n\n- `AUD-005` — service startup not yet complete.\n- `AUD-006` — Postgres health check failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"HealthResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/HealthPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"HealthResponse"},"HealthPayload":{"properties":{"status":{"type":"string","title":"Status","description":"`UP` when ready to serve traffic; the envelope is 503 otherwise."}},"type":"object","required":["status"],"title":"HealthPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."},"ErrorResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response","description":"Always `null` on an error response."},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors","description":"One entry per failure. Always at least one for a non-2xx response."}},"type":"object","required":["responsetime","errors"],"title":"ErrorResponse","description":"Shared shape for every non-2xx response — `response` is null, `errors` is populated."}}}}
```

## Service version and build metadata

> Returns the running service version plus the git commit and build timestamp baked into the Docker image. Useful from probes and smoke tests to confirm which image is actually deployed.

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"paths":{"/v1/auditmanager/version":{"get":{"summary":"Service version and build metadata","description":"Returns the running service version plus the git commit and build timestamp baked into the Docker image. Useful from probes and smoke tests to confirm which image is actually deployed.","operationId":"version_v1_auditmanager_version_get","responses":{"200":{"description":"Version metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionResponse"}}}}}}}},"components":{"schemas":{"VersionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/VersionPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"VersionResponse"},"VersionPayload":{"properties":{"service_version":{"type":"string","title":"Service Version"},"build_time":{"type":"string","title":"Build Time","description":"Image build timestamp baked in at `docker build` time."},"git_commit":{"type":"string","title":"Git Commit","description":"Short git commit hash baked in at `docker build` time."}},"type":"object","required":["service_version","build_time","git_commit"],"title":"VersionPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## Effective non-sensitive configuration

> Returns the non-sensitive portion of the effective service configuration — ingest tunables, Kafka topic/group names, and partition-maintenance settings. Secrets and Kafka bootstrap URLs are deliberately excluded.

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"paths":{"/v1/auditmanager/config":{"get":{"summary":"Effective non-sensitive configuration","description":"Returns the non-sensitive portion of the effective service configuration — ingest tunables, Kafka topic/group names, and partition-maintenance settings. Secrets and Kafka bootstrap URLs are deliberately excluded.","operationId":"config_view_v1_auditmanager_config_get","responses":{"200":{"description":"Effective configuration snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigResponse"}}}}}}}},"components":{"schemas":{"ConfigResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/ConfigPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"ConfigResponse"},"ConfigPayload":{"properties":{"service_id":{"type":"string","title":"Service Id"},"api_version":{"type":"string","title":"Api Version"},"ingest":{"additionalProperties":true,"type":"object","title":"Ingest","description":"Ingest-side config — queue bound, batch limit."},"kafka":{"additionalProperties":true,"type":"object","title":"Kafka","description":"Kafka-side non-sensitive config — topic, DLQ topic, consumer group."},"database":{"additionalProperties":true,"type":"object","title":"Database","description":"Postgres-side config — partition pre-create and retention."}},"additionalProperties":true,"type":"object","required":["service_id","api_version","ingest","kafka","database"],"title":"ConfigPayload","description":"Non-sensitive effective configuration. Shape follows `AuditManagerConfig`."},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The AcceptedResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"AcceptedResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/AcceptedPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"AcceptedResponse"},"AcceptedPayload":{"properties":{"accepted":{"type":"string","title":"Accepted","description":"The `id` of the CloudEvent that was accepted into the ingest queue."}},"type":"object","required":["accepted"],"title":"AcceptedPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The BatchAcceptedResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"BatchAcceptedResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/BatchAcceptedPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"BatchAcceptedResponse"},"BatchAcceptedPayload":{"properties":{"accepted":{"items":{"type":"string"},"type":"array","title":"Accepted","description":"CloudEvent ids accepted into the ingest queue, in the order supplied."},"count":{"type":"integer","title":"Count","description":"Number of events accepted (matches `len(accepted)`)."}},"type":"object","required":["accepted","count"],"title":"BatchAcceptedPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The HealthResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"HealthResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/HealthPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"HealthResponse"},"HealthPayload":{"properties":{"status":{"type":"string","title":"Status","description":"`UP` when ready to serve traffic; the envelope is 503 otherwise."}},"type":"object","required":["status"],"title":"HealthPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The VersionResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"VersionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/VersionPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"VersionResponse"},"VersionPayload":{"properties":{"service_version":{"type":"string","title":"Service Version"},"build_time":{"type":"string","title":"Build Time","description":"Image build timestamp baked in at `docker build` time."},"git_commit":{"type":"string","title":"Git Commit","description":"Short git commit hash baked in at `docker build` time."}},"type":"object","required":["service_version","build_time","git_commit"],"title":"VersionPayload"},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The ConfigResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"ConfigResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"$ref":"#/components/schemas/ConfigPayload"},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["responsetime","response"],"title":"ConfigResponse"},"ConfigPayload":{"properties":{"service_id":{"type":"string","title":"Service Id"},"api_version":{"type":"string","title":"Api Version"},"ingest":{"additionalProperties":true,"type":"object","title":"Ingest","description":"Ingest-side config — queue bound, batch limit."},"kafka":{"additionalProperties":true,"type":"object","title":"Kafka","description":"Kafka-side non-sensitive config — topic, DLQ topic, consumer group."},"database":{"additionalProperties":true,"type":"object","title":"Database","description":"Postgres-side config — partition pre-create and retention."}},"additionalProperties":true,"type":"object","required":["service_id","api_version","ingest","kafka","database"],"title":"ConfigPayload","description":"Non-sensitive effective configuration. Shape follows `AuditManagerConfig`."},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The ErrorResponse object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"ErrorResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Constant — identifies the service that produced this envelope.","default":"openg2p.auditmanager"},"version":{"type":"string","title":"Version","description":"Envelope schema version (not the service version).","default":"1.0"},"responsetime":{"type":"string","title":"Responsetime","description":"RFC3339 timestamp at which this response was produced."},"response":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response","description":"Always `null` on an error response."},"errors":{"items":{"$ref":"#/components/schemas/ErrorDetail"},"type":"array","title":"Errors","description":"One entry per failure. Always at least one for a non-2xx response."}},"type":"object","required":["responsetime","errors"],"title":"ErrorResponse","description":"Shared shape for every non-2xx response — `response` is null, `errors` is populated."},"ErrorDetail":{"properties":{"errorCode":{"type":"string","title":"Errorcode","description":"OpenG2P-assigned error code. Catalog: `AUD-004` (ingest queue full — backpressure), `AUD-005` (service not ready — startup incomplete), `AUD-006` (database health check failed), `AUD-007` (batch payload exceeds configured max size)."},"message":{"type":"string","title":"Message","description":"Human-readable message describing the failure."}},"type":"object","required":["errorCode","message"],"title":"ErrorDetail","description":"One error entry in the `errors[]` array of the response envelope."}}}}
```

## The CloudEvent object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"CloudEvent":{"properties":{"specversion":{"type":"string","const":"1.0","title":"Specversion","default":"1.0"},"id":{"type":"string","title":"Id"},"source":{"type":"string","title":"Source"},"type":{"type":"string","title":"Type"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"time":{"type":"string","format":"date-time","title":"Time"},"datacontenttype":{"type":"string","title":"Datacontenttype","default":"application/json"},"traceparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Traceparent"},"data":{"$ref":"#/components/schemas/AuditData"}},"additionalProperties":true,"type":"object","required":["source","type","data"],"title":"CloudEvent","description":"CloudEvents v1.0 envelope.\n\nSpec: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md"},"AuditData":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"action":{"type":"string","title":"Action"},"outcome":{"type":"string","enum":["success","failure","denied"],"title":"Outcome"},"resource":{"anyOf":[{"$ref":"#/components/schemas/Resource"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","required":["actor","action","outcome"],"title":"AuditData","description":"OpenG2P-specific `data` shape. Open — extra fields allowed per event type."},"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."},"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."}}}}
```

## The EventBatch object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"EventBatch":{"properties":{"events":{"items":{"$ref":"#/components/schemas/CloudEvent"},"type":"array","title":"Events"}},"type":"object","required":["events"],"title":"EventBatch","description":"Batched ingest payload."},"CloudEvent":{"properties":{"specversion":{"type":"string","const":"1.0","title":"Specversion","default":"1.0"},"id":{"type":"string","title":"Id"},"source":{"type":"string","title":"Source"},"type":{"type":"string","title":"Type"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"time":{"type":"string","format":"date-time","title":"Time"},"datacontenttype":{"type":"string","title":"Datacontenttype","default":"application/json"},"traceparent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Traceparent"},"data":{"$ref":"#/components/schemas/AuditData"}},"additionalProperties":true,"type":"object","required":["source","type","data"],"title":"CloudEvent","description":"CloudEvents v1.0 envelope.\n\nSpec: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md"},"AuditData":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"action":{"type":"string","title":"Action"},"outcome":{"type":"string","enum":["success","failure","denied"],"title":"Outcome"},"resource":{"anyOf":[{"$ref":"#/components/schemas/Resource"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","required":["actor","action","outcome"],"title":"AuditData","description":"OpenG2P-specific `data` shape. Open — extra fields allowed per event type."},"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."},"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."}}}}
```

## The Actor object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."}}}}
```

## The AuditData object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"AuditData":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"action":{"type":"string","title":"Action"},"outcome":{"type":"string","enum":["success","failure","denied"],"title":"Outcome"},"resource":{"anyOf":[{"$ref":"#/components/schemas/Resource"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","required":["actor","action","outcome"],"title":"AuditData","description":"OpenG2P-specific `data` shape. Open — extra fields allowed per event type."},"Actor":{"properties":{"type":{"type":"string","enum":["user","system","service","anonymous"],"title":"Type","default":"user"},"id":{"type":"string","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"additionalProperties":true,"type":"object","required":["id"],"title":"Actor","description":"Who (or what system) triggered the event.\n\n`extra=\"allow\"` lets emitters carry custom actor attributes (e.g. a\nKeycloak `username` distinct from `name`, an OAuth `session_state`) without\nrequiring a schema change here. Whatever extras are sent land in the\n`details.actor.*` JSONB column alongside the named fields below."},"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."}}}}
```

## The Resource object

```json
{"openapi":"3.1.0","info":{"title":"OpenG2P Audit Manager","version":"0.1.0"},"components":{"schemas":{"Resource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"}},"additionalProperties":true,"type":"object","required":["type"],"title":"Resource","description":"The primary object acted upon (optional for plain logins)."}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.openg2p.org/platform/platform-services/audit-manager/api-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
