Graine AI
API referenceAudit logs

Fetch one audit event

Fetch one audit row in full.

Fetch one audit row in full.

An event belonging to another organisation answers 404, not 403 — the API never confirms that another tenant's identifier exists.

Errors: 401, 403 (missing audit:read), 404, 429, 503.

Rate limit: 1000 requests per minute per organization (bucket default). Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.

GET
/v2/audit-logs/{event_id}
/v2/audit-logs/aev_d563b9793bd6495aad684632599cb67a

The Authorization access token

Authorization

Authorization
Required
Bearer <token>

Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.

In: header

Path Parameters

event_id
Required
Event Id

Audit event identifier.

Query Parameters

organization_idOrganization Id

Must match the organisation the API key belongs to.

Response Body

200

The audit event, including its hash and the hash it chains to.

event_idEvent Id | null

Stable identifier for this row.

sequenceSequence | null

Position in this organisation's chain. Monotonic, gap-free unless rows were removed.

organization_idOrganization Id | null

Always the organization the calling key belongs to.

occurred_atOccurred At | null

ISO-8601 UTC, millisecond resolution.

actionAction | null

'.', e.g. 'agent.update'.

resource_typeResource Type | null

agent | agent_version | call | batch | api_key | webhook_subscription | inbound_agent | knowledge_base | organization | audit_log

resource_idResource Id | null

The object that was acted on.

outcomeOutcome | null

success | denied | failure | unreadable.

status_codeStatus Code | null

HTTP status the request was answered with.

error_codeError Code | null

The /v2 integer error code, when the request failed.

error_messageError Message | null

The message that was returned, when the request failed.

actorActor

Who made the request.

source_ipSource Ip | null

First hop of X-Forwarded-For, else the socket peer.

user_agentUser Agent | null

User-Agent header sent with the original request.

request_idRequest Id | null

Correlates with the x-request-id header on the original response.

methodMethod | null

HTTP method of the original request.

pathPath | null

Path of the original request.

changesChanges | null

Redacted summary of what changed. Phone numbers, secrets, header values and contact lists are reduced to '***' or to a count BEFORE the row is stored.

hashHash | null

sha256 over this row's chained fields.

prev_hashPrev Hash | null

The previous row's hash. Re-verify the chain yourself from an export.

401

1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

403

1102 — the key is valid but lacks the audit:read scope, or names another organisation.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

404

1200 — no such audit event IN THIS ORGANISATION. Never 403: event ids are not probeable.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

422

1001 — a query parameter failed validation; the message names the field.

error
Required
integer

Stable integer code from the error table. Branch on this, not on the message.

message
Required
string

One human-readable sentence. Wording may change; the code will not.

429

1300 — per-organisation rate limit exceeded. Carries Retry-After.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

503

1501 — the audit log could not be read. Deliberately NOT an empty page.

error
Required
Error

Stable integer code from the /v2 error table. Branch on this.

message
Required
Message

One human-readable sentence. Wording may change; the code will not.

curl -X GET "https://api.graine.ai/v2/audit-logs/aev_d563b9793bd6495aad684632599cb67a?organization_id=string" \
  -H "Authorization: Bearer <token>"

The audit event, including its hash and the hash it chains to.

{
  "event_id": "c8d41e0b-6a92-4f37-b5de-9a70c2f18e43",
  "sequence": 4821,
  "organization_id": "string",
  "occurred_at": "2026-08-26T12:19:54.580Z",
  "action": "agent.update",
  "resource_type": "agent",
  "resource_id": "6c6f4cc3-f56c-479d-8422-7f76694daa29",
  "outcome": "success",
  "status_code": 200,
  "error_code": 1102,
  "error_message": "This API key belongs to a different organization.",
  "actor": {
    "type": "api_key",
    "key_id": "key_1a2b3c4d5e6f7890",
    "developer_id": "dev_1a2b3c4d5e6f7a8b",
    "developer_name": "Production integration",
    "scopes_source": "grandfathered"
  },
  "source_ip": "203.0.113.42",
  "user_agent": "graine-python/2.0.0",
  "request_id": "f2a1b7c4-3d5e-4a9f-8b06-1c7d2e3f4a5b",
  "method": "PATCH",
  "path": "/v2/agents/6c6f4cc3-f56c-479d-8422-7f76694daa29",
  "changes": {
    "display_name": {
      "from": "Priya Plumber Activation Agent",
      "to": "Priya - Plumber Activation"
    }
  },
  "hash": "9f2c1d84a7e30b5f6c8d1e2a3b4c5d6e7f8091a2b3c4d5e6f7081920a3b4c5d6",
  "prev_hash": "4b7e9a1c2d3f4051627384950a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d"
}