{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/superwall/json-schema/superwall-audit-log-entry-with-actor-schema.json",
  "title": "AuditLogEntryWithActor",
  "x-generated": "2026-10-28",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/superwall-openapi.json#/components/schemas/AuditLogEntryWithActor",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Unique audit log entry id (UUID)"
    },
    "object": {
      "type": "string",
      "enum": [
        "audit_log_entry"
      ],
      "description": "Object type, always `audit_log_entry`"
    },
    "timestamp": {
      "type": "string",
      "description": "ISO 8601 timestamp of when the request was served"
    },
    "request_id": {
      "type": "string",
      "description": "Request identifier (x-request-id header, or auto-generated UUID)"
    },
    "route_family": {
      "type": "string",
      "enum": [
        "public_v2",
        "internal_v2"
      ],
      "description": "Which route family served the request"
    },
    "method": {
      "type": "string",
      "description": "HTTP method"
    },
    "request_url": {
      "type": "string",
      "description": "Full request URL with query string"
    },
    "path": {
      "type": "string",
      "description": "URL path with query string"
    },
    "endpoint_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Resolved OpenAPI endpoint name (e.g. listPaywalls)"
    },
    "auth_method": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "api_key",
            "cookie",
            "oauth",
            "agent_token",
            "service_token",
            "delegated_service_token",
            "workspace_token"
          ],
          "description": "Authentication method used"
        },
        {
          "type": "null"
        }
      ],
      "description": "Authentication method that succeeded, null if unauthenticated"
    },
    "attempted_auth_method": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "api_key",
            "cookie",
            "oauth",
            "agent_token",
            "service_token",
            "delegated_service_token",
            "workspace_token"
          ],
          "description": "Authentication method used"
        },
        {
          "type": "null"
        }
      ],
      "description": "Authentication method the caller attempted to use"
    },
    "user_id": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "description": "User id if authenticated via cookie/oauth"
    },
    "token_id": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "description": "API token id if authenticated via api_key"
    },
    "token_name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Credential label at time of request"
    },
    "service_principal_id": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "description": "Service principal id if authenticated via service_token or delegated_service_token. For delegated requests user_id is the user the service acted for."
    },
    "organization_id": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "description": "Organization the request was scoped to"
    },
    "authorized": {
      "type": "boolean",
      "description": "Whether the request cleared authn + authz checks"
    },
    "status_code": {
      "description": "HTTP response status code",
      "type": "number"
    },
    "failure_stage": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "authn",
            "authz"
          ],
          "description": "Stage at which the request was rejected, if any"
        },
        {
          "type": "null"
        }
      ],
      "description": "Stage at which the request was rejected, null on success"
    },
    "failure_code": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Machine-readable failure code (e.g. MissingApiKey, insufficient_scope)"
    },
    "mutation": {
      "type": "boolean",
      "description": "Whether the endpoint mutates state (POST/PUT/PATCH/DELETE except read endpoints)"
    },
    "resource_type": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Resource type touched by the mutation (e.g. `paywall`, `product`), if known"
    },
    "resource_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Stringified id of the resource touched by the mutation, if known"
    },
    "changes": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/AuditChange"
          }
        },
        {
          "type": "null"
        }
      ],
      "description": "Structured before/after diff for mutations. Null for reads, no-op patches, and entries from before this field was introduced."
    },
    "ip_address": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Client IP address the request originated from"
    },
    "country": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "ISO-3166 country code resolved from the client IP"
    },
    "city": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "City resolved from the client IP, if available"
    },
    "region": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Region/state resolved from the client IP, if available"
    },
    "timezone": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "IANA timezone resolved from the client IP, if available"
    },
    "user_agent": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Raw User-Agent header of the request"
    },
    "session_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Identifier of the login session (OAuth `sid`/`jti` claim). Groups every entry from one session. Null for api_key and cookie auth."
    },
    "actor": {
      "anyOf": [
        {
          "$ref": "#/$defs/AuditActorUser"
        },
        {
          "type": "null"
        }
      ],
      "description": "Resolved acting user, if `user_id` is set"
    }
  },
  "required": [
    "id",
    "object",
    "timestamp",
    "request_id",
    "route_family",
    "method",
    "request_url",
    "path",
    "endpoint_id",
    "auth_method",
    "attempted_auth_method",
    "user_id",
    "token_id",
    "token_name",
    "service_principal_id",
    "organization_id",
    "authorized",
    "status_code",
    "failure_stage",
    "failure_code",
    "mutation",
    "resource_type",
    "resource_id",
    "changes",
    "ip_address",
    "country",
    "city",
    "region",
    "timezone",
    "user_agent",
    "session_id",
    "actor"
  ],
  "additionalProperties": false,
  "$defs": {
    "AuditActorUser": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number"
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Display name, if set"
        },
        "email": {
          "type": "string",
          "description": "User email address"
        },
        "image": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "Avatar image URL, if set"
        }
      },
      "required": [
        "id",
        "name",
        "email",
        "image"
      ],
      "additionalProperties": false
    },
    "AuditChange": {
      "type": "object",
      "properties": {
        "op": {
          "type": "string",
          "enum": [
            "add",
            "remove",
            "replace",
            "truncated"
          ],
          "description": "Diff operation type. `truncated` is a sentinel emitted when the serialized diff exceeded the storage cap; subsequent changes were dropped."
        },
        "path": {
          "type": "string",
          "description": "Dot-joined path to the changed field (e.g. `metadata.foo`, `products.0.identifier`)"
        },
        "before": {
          "anyOf": [
            {}
          ],
          "description": "Value before the change; absent on `add`"
        },
        "after": {
          "anyOf": [
            {}
          ],
          "description": "Value after the change; absent on `remove`"
        }
      },
      "required": [
        "op",
        "path"
      ],
      "additionalProperties": false
    }
  }
}