> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nohead.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List a project's audit events

> The project's audit events, newest first. API keys need the `audit:read`
scope and see their own project only.




## OpenAPI

````yaml /openapi.json get /v1/projects/{project_id}/audit-events
openapi: 3.1.1
info:
  title: Nohead API
  version: 1.0.0
  summary: Programmable content and data API.
  contact:
    name: Nohead
    email: hello@nohead.io
    url: https://nohead.io
  description: >
    The Nohead API manages projects, collections (your data models), their

    fields, and records (your content), with full version history.


    ## Authentication


    Send `Authorization: Bearer <token>`. Servers, CI and agents use a

    project API key (`nohead_sk_...`, or `nohead_pk_...` for a published-only

    key; created in the web app under API keys)

    with scopes such as `records:read` or `schema:write`. Organization,

    project, member and API key management need a person signed in to the

    web app and are not available to API keys.


    ## Resources and IDs


    Every object has an `object` type, and every resource with an identity of

    its own an opaque, prefixed `id` (`col_`, `fld_`, `rec_`, ...). Record
    values live under `data`, keyed by each

    field's `key`. Timestamps are ISO 8601 in UTC. Deleting a record,

    collection, field, asset or webhook is soft: it can be restored until its

    `purge_after`.


    ## Lists


    Lists return `{ "data": [...], "meta": { "next_cursor", "has_more" } }`.

    Pass `limit` (1-100) and `cursor` to page, and `sort` (prefix `-` for

    descending). Records also take `filter[<key>]=value`,

    `filter[published_at][exists]=true` and `expand=<relation, asset or

    rich text fields>`.


    ## Errors


    Errors share one envelope: `{ "error": { "type", "message",

    "request_id", "details" } }`. `details` lists field-level problems as

    `{ "field", "code", "message" }`. Include the `request_id` when asking

    for support.


    ## Safe retries and concurrent edits


    Send `Idempotency-Key` on any `POST`, `PUT`, `PATCH` or `DELETE` to make
    retrying

    it safe: the first result is stored for 24 hours and returned again for

    the same request. Record responses carry the record's revision as an

    `ETag`; send it back as `If-Match` to update only if nobody changed the

    record in the meantime (`412` otherwise).


    ## History


    Every change to a record is a revision, attributed to the person or API

    key that made it: record revisions can be listed, diffed and reverted,

    and collections keep a schema history. Send `Nohead-Change-Note` to

    record why a change was made. Changes that rewrite existing values

    (such as a field's type) are explicit, previewable field migrations.


    How long revisions are kept depends on the organization's plan. Older

    ones are removed, but every record keeps its first revision and its

    last 10; `history_pruned_through` says how far history was removed.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.nohead.io
    description: Production
security:
  - apiKey: []
tags:
  - name: records
    x-group: Records
    description: Content entries, one at a time or many at once.
  - name: publishing
    x-group: Publishing
    description: Making records live, now or at a set time, and taking them down.
  - name: revisions
    x-group: Revisions
    description: A record's history, comparing two revisions, and going back to one.
  - name: drafts
    x-group: Drafts
    description: Changes to a record that wait to be merged into it, now or at a set time.
  - name: collections
    x-group: Collections
    description: User-defined data models.
  - name: schema-changes
    x-group: Schema changes
    description: A collection's schema history, and its schema at any version.
  - name: fields
    x-group: Fields
    description: Field definitions of a collection.
  - name: migrations
    x-group: Field migrations
    description: Explicit field changes that rewrite existing record values, with previews.
  - name: assets
    x-group: Assets
    description: Files stored for a project, uploaded directly to storage.
  - name: search
    x-group: Search
    description: Full-text search in collections and across a project.
  - name: webhooks
    x-group: Webhooks
    description: Event notifications sent to your URLs, and the secrets that sign them.
  - name: deliveries
    x-group: Webhook deliveries
    description: Each event sent to a webhook, its attempts, and retrying it.
  - name: audit
    x-group: Activity log
    description: The append-only trail of who changed what, through which client.
  - name: system
    x-group: System
    description: Service status, the caller, and its feature flags.
paths:
  /v1/projects/{project_id}/audit-events:
    parameters:
      - $ref: '#/components/parameters/ProjectId'
    get:
      tags:
        - audit
      summary: List a project's audit events
      description: |
        The project's audit events, newest first. API keys need the `audit:read`
        scope and see their own project only.
      operationId: audit_events_list
      parameters:
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/AuditEventFilter'
        - $ref: '#/components/parameters/AuditEventSort'
      responses:
        '200':
          description: A page of audit events.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditEventList'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
      x-codeSamples:
        - lang: typescript
          label: TypeScript
          source: |
            import { Nohead } from "@nohead/sdk"

            const nohead = new Nohead()

            for await (const event of nohead.auditEvents.list({
              filter: {
                type: "record.*",
                created_at: { gte: "2026-10-01T00:00:00Z" },
              },
              sort: "-created_at",
            })) {
              console.log(event)
            }
        - lang: python
          label: Python
          source: >
            from nohead import Nohead


            nohead = Nohead()


            for event in nohead.audit_events.list(filter={"type": "record.*"},
            sort="-created_at"):
                print(event)
        - lang: ruby
          label: Ruby
          source: >
            require "nohead"


            nohead = Nohead::Client.new


            nohead.audit_events.list(filter: { type: "record.*", resource_type:
            %w[record draft] }, sort: "created_at").each do |event|
              puts event
            end
components:
  parameters:
    ProjectId:
      name: project_id
      in: path
      required: true
      schema:
        type: string
      example: prj_01J9ZQ3F8X5W2K7M4N6P0R1S2T
    Limit:
      name: limit
      in: query
      description: Page size.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    Cursor:
      name: cursor
      in: query
      description: The `next_cursor` from the previous page.
      schema:
        type: string
    AuditEventFilter:
      name: filter
      in: query
      style: deepObject
      explode: true
      description: |
        `type` matches exactly, or by prefix with a trailing `.*`
        (`filter[type]=record.*`). `resource_type` takes one type, or several
        with `[in]` (`filter[resource_type][in]=collection,field`). Unknown
        filters are `400`.
      schema:
        type: object
        additionalProperties: false
        properties:
          type:
            type: string
            examples:
              - field.updated
              - record.*
          resource_type:
            oneOf:
              - type: string
                examples:
                  - record
              - type: object
                additionalProperties: false
                required:
                  - in
                properties:
                  in:
                    type: string
                    description: Comma-separated types.
          resource_id:
            type: string
          actor_type:
            type: string
            enum:
              - user
              - api_key
              - system
          actor_id:
            type: string
            description: A user (`usr_...`) or API key (`key_...`).
          created_at:
            $ref: '#/components/schemas/TimeFilter'
    AuditEventSort:
      name: sort
      in: query
      schema:
        type: string
        enum:
          - created_at
          - '-created_at'
        default: '-created_at'
  schemas:
    AuditEventList:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AuditEvent'
        meta:
          $ref: '#/components/schemas/ListMeta'
    TimeFilter:
      type: object
      additionalProperties: false
      description: >-
        A time range, as record lists filter times
        (`filter[created_at][gte]=2026-10-01T00:00:00Z`).
      properties:
        gte:
          type: string
          format: date-time
        gt:
          type: string
          format: date-time
        lte:
          type: string
          format: date-time
        lt:
          type: string
          format: date-time
    AuditEvent:
      type: object
      additionalProperties: false
      required:
        - id
        - object
        - organization_id
        - project
        - type
        - resource
        - actor
        - via
        - note
        - metadata
        - request_id
        - created_at
      properties:
        id:
          type: string
          examples:
            - evt_01J9ZQ3F8X5W2K7M4N6P0R1S2T
        object:
          const: event
        organization_id:
          type: string
        project:
          description: >-
            The project the event belongs to, or null for organization-level
            events.
          oneOf:
            - type: 'null'
            - type: object
              additionalProperties: false
              required:
                - id
                - name
              properties:
                id:
                  type: string
                name:
                  type: string
        type:
          type: string
          description: |
            `<resource>.<verb>`, e.g. `record.published`, `field.updated`,
            `api_key.created`, `member.role_changed`: a webhook event's type
            too, for the events webhooks get.
          examples:
            - record.published
        resource:
          type: object
          additionalProperties: false
          required:
            - type
            - id
          properties:
            type:
              type: string
              description: >-
                What the event is about, such as `record`, `draft`,
                `collection`, `field`, `asset` or `webhook`; a field's change
                names its collection in `metadata.collection_id`.
              examples:
                - record
            id:
              type: string
              description: The resource's public ID (or key, for feature flags).
        actor:
          $ref: '#/components/schemas/Actor'
        via:
          description: The client the change came through, when known.
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/Via'
        note:
          type:
            - string
            - 'null'
          description: |
            The change note (`Nohead-Change-Note`) the change was made with,
            read from the revision or schema change the event references, so
            record and schema events have one when their change did; null
            otherwise, and once a revision's history is pruned.
          examples:
            - Clearer title
        metadata:
          type: object
          description: |
            Small, action-specific references, e.g. `revision_id` and
            `collection_id` for record events, `schema_change_id` for schema
            events, `changed` attribute names for updates (field keys for a
            draft's). Never content.
          additionalProperties: true
        request_id:
          type:
            - string
            - 'null'
        created_at:
          type: string
          format: date-time
    ListMeta:
      type: object
      description: Cursor pagination metadata returned with every list.
      additionalProperties: false
      required:
        - next_cursor
        - has_more
      properties:
        next_cursor:
          type:
            - string
            - 'null'
          description: Opaque cursor for the next page, or null on the last page.
        has_more:
          type: boolean
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - type
            - message
            - request_id
          properties:
            type:
              $ref: '#/components/schemas/ErrorType'
            message:
              type: string
            request_id:
              $ref: '#/components/schemas/RequestId'
            details:
              type: array
              items:
                $ref: '#/components/schemas/ErrorDetail'
    Actor:
      type: object
      additionalProperties: false
      required:
        - type
        - id
        - name
      properties:
        type:
          type: string
          enum:
            - user
            - api_key
            - system
        id:
          type:
            - string
            - 'null'
          description: >-
            The user (`usr_...`) or API key (`key_...`), or null for system
            changes.
        name:
          type:
            - string
            - 'null'
          description: |
            Resolved when read, never stored: a user's current name (or
            email), "Deleted user" once they deleted their account, an API
            key's name, or "System".
    Via:
      type: string
      description: The client a change came through; `scheduler` for scheduled changes.
      enum:
        - ui
        - api
        - cli
        - sdk
        - mcp
        - system
        - scheduler
    RequestId:
      type: string
      pattern: ^req_[A-Za-z0-9]+$
      examples:
        - req_01J9ZQ3F8X5W2K7M4N6P0R1S2T
    ErrorType:
      type: string
      enum:
        - invalid_request
        - authentication_error
        - plan_limit_exceeded
        - authorization_error
        - not_found
        - conflict
        - precondition_failed
        - validation_error
        - rate_limited
        - internal_error
        - service_unavailable
    ErrorDetail:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        field:
          type: string
          description: Key of the offending field or parameter, when applicable.
        code:
          type: string
          description: Machine-readable error code, e.g. `required`.
        message:
          type: string
        usage:
          type: integer
          description: Current usage, for `plan_limit` details.
        limit:
          type: integer
          description: The plan's limit, for `plan_limit` details.
        current_revision:
          type: integer
          description: The resource's current revision, for `revision_mismatch` details.
        record_id:
          type: string
          description: The record that already has the value, for `taken` details.
        draft_id:
          type: string
          description: The record's draft, for `draft_exists` and `draft_pending` details.
  responses:
    BadRequest:
      description: >-
        The request was malformed: unparseable JSON, an invalid query parameter,
        or a body key the operation doesn't take (detail code
        `unknown_parameter`, naming the key).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication is missing or invalid.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The caller is not allowed to perform this action.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The resource does not exist or is not visible to the caller.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >
        Too many requests for this API key or user (or, with failing

        credentials, this IP address). A published-only key is counted per

        client IP. Wait `Retry-After` seconds; retries with the same
        `Idempotency-Key`

        are safe. On the Free plan, an organization's API keys are also

        refused once its API requests reach the month's limit, with a

        `plan_limit` detail (`field` `api_requests`, `usage` and `limit`),

        until the next month (UTC) or an upgrade.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    RequestId:
      description: Unique identifier for the request, also echoed in error bodies.
      schema:
        $ref: '#/components/schemas/RequestId'
    RateLimitLimit:
      description: >-
        Requests allowed in the current window. Sent on every authenticated
        response.
      schema:
        type: integer
    RateLimitRemaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimitReset:
      description: Seconds until the window resets.
      schema:
        type: integer
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: |
        Project-scoped API key, e.g. `nohead_sk_k7fz0a9c3m2q_<secret>`, or
        `nohead_pk_…` for a published-only key. Used by servers, CI, the CLI
        and coding agents.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.