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

# List runs of an automation

> Lists the runs of one automation, most recent first (`occurred_at`, then `id`). Runs are kept for 90 days. `404 automation_not_found` if the automation is not served in this workspace. Some automations never produce runs (see `Run`): their list is always empty.




## OpenAPI

````yaml /openapi/openapi-v1.yaml get /automations/{id}/runs
openapi: 3.0.3
info:
  title: Agentova Public API
  version: 1.0.0
  termsOfService: https://agentova.ai/legal/terms-of-use
  license:
    name: Proprietary — Agentova terms of use
    url: https://agentova.ai/legal/terms-of-use
  contact:
    name: Agentova support
    email: contact@agentova.ai
    url: https://docs.agentova.ai
  description: >
    The Agentova Public API lets your own code, Zapier or n8n work with an

    Agentova workspace: read its automations, runs and leads, pause and resume

    its automations, and receive events through signed webhooks.



    ## Base URL and authentication


    All endpoints are served over HTTPS under `https://core-api.agentova.ai/v1`.

    Every request carries an API key, created in the Agentova app

    (Settings → API), in the `Authorization` header:

    `Authorization: Bearer agk_live_…`


    - A key belongs to one workspace and gives access to the whole workspace.
      The key identifies the workspace: no workspace identifier is ever sent.
    - Every key starts with `agk_live_`. There are no test keys and no separate
      test environment: to experiment safely, use a dedicated workspace.
    - A revoked key is refused immediately, on every endpoint.

    - The API is meant to be called from a server. It sends no CORS headers,
      so a web page cannot call it from a browser, and an `OPTIONS` request
      receives an error in the format described under Errors.


    ## Stability


    This is version 1.0.0 of the v1 API, and v1 is stable: no breaking change

    will be made under `/v1`. Additive changes can still happen: new optional

    fields, new event types, new enum values. Your client must ignore the

    fields, event types and enum values it does not know.



    ## Coverage


    - **Automations**: the messaging automations of the workspace on Meta
      networks (`facebook`, `instagram`, `instagram_page`), WhatsApp
      (`whatsapp`) and e-mail (`gmail`, `microsoft_outlook`, `imap`), with the
      types `social_comments`, `social_story`, `social_messages`, `lead_ads`
      and `email_messages`, plus the CRM sources (`crm_source`). They can all
      be read, and paused or resumed with `PATCH`.
    - **Leads**: from the sources `widget`, `lead_ads`, `telephony`, `social`
      and `crm`.
    - **Runs**: see the `Run` schema for the automations that produce runs.

    - **Webhook events**: `lead.created`, `run.completed` and
      `automation.status_changed`.


    ## Conventions


    - **Identifiers** are opaque strings prefixed by their type: `aut_`
      (automation), `agt_` (agent), `run_` (run), `lea_` (lead), `whk_`
      (webhook subscription), `evt_` (event). Store them and send them back
      unchanged; never validate or parse them (length, alphabet). They are not
      UUIDs.
    - **Dates** are ISO 8601, in UTC, with the `Z` suffix.

    - **Unknown query parameters** are ignored, never rejected, so that a
      client written for a later version keeps working.
    - **Request bodies** are JSON, sent with `Content-Type: application/json`,
      and limited to 16 KB. Another content type is refused with HTTP `415`,
      a larger body with HTTP `413`, both with the code `invalid_request`.
    - **Caching**: every response carries `Cache-Control: no-store`, because
      responses contain personal data.


    ## Pagination


    Lists are paginated with an opaque cursor. `limit` takes a value from 1 to

    100 (25 by default); a value out of range is refused with `400`, not

    corrected. A page looks like

    `{ "data": [...], "has_more": true, "next_cursor": "..." }`: to get the

    next page, send `next_cursor` back as `cursor`. A missing or empty

    `cursor`, or the literal word `null`, means the first page.

    `GET /webhooks` is not paginated.



    ## Rate limits


    - Each API key can make about 100 requests per minute. Requests are
      counted per server instance, so this limit is approximate.
    - Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and
      `X-RateLimit-Reset` (seconds until the window resets, not a timestamp),
      `401` and `403` responses included.
    - Above the limit, the API answers `429 rate_limited` with a `Retry-After`
      header, in seconds.
    - More than 30 authentication failures per minute from the same IP address
      also lead to `429`. This never applies to requests made with a valid
      key.


    ## Errors


    Every 4xx and 5xx response has the same body:

    `{ "error": { "code": "...", "message": "...", "details": {} } }`.


    - `code` is stable and comes from a closed list (`ErrorCode`): branch on
      it.
    - `message` is in English, meant to be shown to a person, and can change
      at any time.
    - `details` is always an object: empty, or giving context such as the
      faulty `parameter` and a `reason`.

    | HTTP status | `code` | Meaning |

    |---|---|---|

    | 400 | `invalid_request` | Invalid query parameter or body
    (`details.parameter`) |

    | 413, 415 | `invalid_request` | Body larger than 16 KB, or unsupported
    content type (`details.reason`) |

    | 401 | `invalid_api_key` | Missing, malformed, unknown or revoked key |

    | 403 | `workspace_access_denied` | The workspace's subscription does not
    allow API access |

    | 404 | `automation_not_found` | No such automation in this workspace |

    | 404 | `webhook_not_found` | No such webhook subscription in this workspace
    |

    | 404 | `route_not_found` | Unknown path or method under `/v1` (never `405`)
    |

    | 422 | `automation_not_controllable` | `PATCH` on an automation in `draft`
    or `error` (`details.status`), or resuming an e-mail automation whose
    mailbox another active agent already uses (`details.reason: account_in_use`)
    |

    | 429 | `rate_limited` | Rate limit exceeded: wait `Retry-After` seconds |

    | 500 | `internal_error` | Unexpected error (generic message) |

    | 503 | `service_unavailable` | The API is temporarily switched off by
    Agentova: retry later |



    ## Webhooks


    Create a subscription with `POST /webhooks`. Agentova then sends every

    event of the subscribed types as a `POST` request to your URL; the body is

    described by the `delivery` callback of `POST /webhooks`.


    - **Request**: a `POST` with `Content-Type: application/json` and
      `User-Agent: Agentova-Webhooks/1.0`.
    - **Signature**: each delivery carries
      `X-Agentova-Signature: t=<unix timestamp>,v1=<hex digest>`. The digest
      is the HMAC-SHA256 of the string `{t}.{raw request body}`, keyed with the
      complete subscription `secret`, `whsec_` prefix included. Compare digests
      in constant time, and reject a delivery whose `t` is more than 5 minutes
      away from your clock (recommended tolerance). The official Zapier app
      accepts 1 hour, because Zapier can process hooks late and the hook URL
      is itself a secret.
    - **Success** is a 2xx status received within 10 seconds (a deadline for
      the whole response). The response body is ignored. Redirects are not
      followed: a 3xx is a failure.
    - **Retries**: 8 attempts spread over about 27 hours 35 minutes. The first
      attempt is immediate; after each failure, the next one comes 5 seconds,
      5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and finally 10 hours
      later. When your endpoint answers `429` or `503` with a `Retry-After`
      header, the next attempt waits at least that long, up to 12 hours. No
      attempt is ever scheduled more than 36 hours after the event was
      created: when the next one would be, the delivery is abandoned.
    - **`410 Gone`** deletes the subscription immediately, without any
      notification: answer `410` to unsubscribe (this is how Zapier reports a
      deleted Zap).
    - **Disabling**: a delivery is abandoned after its 8th failed attempt, or
      earlier when it reaches the 36-hour limit. The
      subscription is then disabled if it has at least 3 abandoned deliveries
      in a row and has been failing without interruption for at least 72
      hours. It is also disabled at once, without any delivery, if its URL no
      longer passes the address checks (an IP address that became forbidden).
      Workspace admins are notified in the app and by push
      notification. A disabled subscription receives nothing and cannot be
      re-enabled: delete it and create a new one (Zapier: turn the Zap off and
      on again; n8n: deactivate and reactivate the workflow). Disabled
      subscriptions are deleted automatically 30 days after being disabled.
    - **At least once, in no guaranteed order**: the same event can be
      delivered more than once, and events can arrive out of order.
      Deduplicate on the event `id` (`evt_…`): it is the same on every attempt
      and for every subscription that receives the event; keep the ids you
      have seen for at least 48 hours: retries are always scheduled within 36
      hours of the event's creation. To order events,
      use the timestamp of the resource in `data` (`updated_at` of an
      automation, `created_at` of a lead, `occurred_at` of a run), not the
      arrival order.
    - **Ownership**: subscriptions belong to the workspace; workspace admins
      see and delete them in Settings → API. Revoking the key that created a
      subscription deletes the subscription as well, unless the admin unticks
      that option in Settings → API. A key is also revoked, with its
      subscriptions, when the admin who created it leaves the workspace,
      loses the admin role or deletes their account.
    - **Retention**: the webhook delivery log is kept for 30 days, and runs
      for 90 days.
    - **While the API is switched off** (`503 service_unavailable`), no
      delivery is created for the events that happen in the meantime, and the
      deliveries already in progress are suspended: they resume when the API
      is back. Catch up on the missed events with the list endpoints.


    ## Support


    Documentation: https://docs.agentova.ai. Contact: contact@agentova.ai.
servers:
  - url: https://core-api.agentova.ai/v1
    description: Production, the only environment (there is no separate test environment)
security:
  - bearerAuth: []
paths:
  /automations/{id}/runs:
    get:
      summary: List runs of an automation
      description: >
        Lists the runs of one automation, most recent first (`occurred_at`, then
        `id`). Runs are kept for 90 days. `404 automation_not_found` if the
        automation is not served in this workspace. Some automations never
        produce runs (see `Run`): their list is always empty.
      operationId: listAutomationRuns
      parameters:
        - $ref: '#/components/parameters/AutomationId'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: A page of runs
          headers:
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PaginatedResponse'
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Run'
              example:
                data:
                  - id: run_01HZX4A1B2C3D4E5F6G7H8J9K0
                    automation_id: aut_01HZX3Q8K5N7P2R4S6T8V0W2Y4
                    status: success
                    trigger_type: comment
                    occurred_at: '2026-08-20T10:00:00Z'
                    actions:
                      - type: reply_comment
                        status: success
                    lead_id: null
                has_more: false
                next_cursor: null
        '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'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    AutomationId:
      name: id
      in: path
      required: true
      description: Opaque `aut_…` identifier, as returned by the API.
      schema:
        type: string
    Limit:
      name: limit
      in: query
      description: >
        Integer from 1 to 100 (default 25). Out of range or not an integer: `400
        invalid_request`.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
    Cursor:
      name: cursor
      in: query
      description: >
        Opaque cursor received in `next_cursor`. Missing, empty or equal to the
        literal word `null`: first page. Unreadable: `400 invalid_request`.
      schema:
        type: string
        nullable: true
  headers:
    Cache-Control:
      description: Always `no-store` (personal data, no intermediate cache)
      schema:
        type: string
        enum:
          - no-store
    X-RateLimit-Limit:
      description: >
        Number of requests allowed per window (per key; per IP address when the
        429 comes from repeated authentication failures)
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current window
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Seconds left before the window resets (NOT a timestamp)
      schema:
        type: integer
  schemas:
    PaginatedResponse:
      type: object
      required:
        - has_more
        - next_cursor
      properties:
        has_more:
          type: boolean
          description: Whether another page follows.
        next_cursor:
          type: string
          nullable: true
          description: >
            Opaque cursor of the next page, to send back as `cursor`; `null`
            when there is no next page.
    Run:
      type: object
      description: |
        One execution of an automation: what triggered it and what it did.

        Runs are produced by the messaging automations (comments, stories,
        private messages, e-mails), by the Lead Ads automations, and by the CRM
        automations that have an agent: one run per person of a Customer.io
        segment handled, and one run per action received from a CRM workflow
        (for example HubSpot, Close or Typeform). The website widget produces
        no runs. Runs are kept for 90 days.
      required:
        - id
        - automation_id
        - status
        - trigger_type
        - occurred_at
        - actions
        - lead_id
      properties:
        id:
          type: string
          description: Opaque identifier prefixed with `run_`.
        automation_id:
          type: string
          description: Opaque identifier prefixed with `aut_`.
        status:
          type: string
          description: >
            `success`: no action failed (a run without any action is also
            `success`). `failed`: every action failed. `partial`: some actions
            failed, for example an e-mail reply that could not be sent
            automatically and was saved as a draft instead.
          enum:
            - success
            - partial
            - failed
        trigger_type:
          type: string
          description: |
            What started the run:

            - `comment`: a comment on Facebook or Instagram.
            - `story_reply`: a reply to a story.
            - `message`: a private message on Facebook, Instagram or WhatsApp.
            - `email`: an e-mail received by an `email_messages` automation.
            - `lead_ads`: a Lead Ads form submission.
            - `crm_event`: an event from a CRM source.
          enum:
            - comment
            - story_reply
            - message
            - lead_ads
            - crm_event
            - email
        occurred_at:
          type: string
          format: date-time
          description: When the run happened.
        actions:
          type: array
          description: >
            What the automation did. `type` is an open string, today one of
            `reply_message`, `reply_comment`, `send_dm`, `story_reply`,
            `send_reply`, `save_draft`, `generate_reply`, `send_message` and
            `add_to_crm`. The list is empty for a Lead Ads run when the
            automation has no action configured (the run is then `success`).
          items:
            type: object
            required:
              - type
              - status
            properties:
              type:
                type: string
                description: Kind of action (open string; new values can appear).
              status:
                type: string
                description: Outcome of the action.
                enum:
                  - success
                  - failed
        lead_id:
          type: string
          nullable: true
          description: >-
            Opaque identifier, prefixed with `lea_`, of the lead involved, or
            `null`.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - details
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >
                In English, meant to be displayed; it can change without notice
                (branch on `code`).
            details:
              type: object
              description: >
                Empty (`{}`) or context: `parameter`, `allowed`, `max`,
                `reason`, `status`, `retry_after_seconds`…
    ErrorCode:
      type: string
      description: >
        Stable error codes. `invalid_request` (400; also 413 when the body is
        larger than 16 KB and 415 for an unsupported content type: the HTTP
        status is kept and the cause is in `details.reason`) · `invalid_api_key`
        (401) · `workspace_access_denied` (403) · `automation_not_found` (404) ·
        `webhook_not_found` (404) · `route_not_found` (404: unknown path or
        method) · `automation_not_controllable` (422: automation in `draft` or
        `error`, see `details.status`) · `rate_limited` (429) · `internal_error`
        (500, generic message) · `service_unavailable` (503: the API is
        temporarily switched off by Agentova; retry later).
      enum:
        - invalid_request
        - invalid_api_key
        - workspace_access_denied
        - automation_not_found
        - webhook_not_found
        - route_not_found
        - automation_not_controllable
        - rate_limited
        - internal_error
        - service_unavailable
  responses:
    BadRequest:
      description: Invalid query parameter or body (`details.parameter` names it)
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_request
              message: The limit parameter must be an integer between 1 and 100
              details:
                parameter: limit
                max: 100
    Unauthorized:
      description: >-
        Missing, malformed, unknown or revoked key (deliberately
        indistinguishable)
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_api_key
              message: Invalid or revoked key — create one in Settings → API
              details: {}
    Forbidden:
      description: >
        Valid key, but the workspace does not have access to the service (or no
        longer has it): its subscription is blocked (unpaid, paused, or initial
        payment never completed). A workspace without a subscription is on the
        free plan and is not affected. This is not a per-key permission: v1 has
        no per-key permissions.
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: workspace_access_denied
              message: This workspace's subscription does not allow access to the API
              details: {}
    NotFound:
      description: >
        Not found in this workspace (the same response whether the resource
        exists in another workspace or nowhere), or unknown route
        (`route_not_found`).
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: automation_not_found
              message: Automation not found in this workspace
              details: {}
    RateLimited:
      description: >
        Rate limit exceeded: too many requests with this key, or too many
        authentication failures from this IP address
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        Retry-After:
          description: Seconds to wait before retrying
          schema:
            type: integer
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: Rate limit exceeded — retry in a few seconds
              details:
                retry_after_seconds: 42
    ServiceUnavailable:
      description: >
        The API is temporarily switched off by Agentova (`service_unavailable`):
        retry later. This response may come without the `X-RateLimit-*` headers.
        While the API is switched off, no webhook delivery is created for the
        events that happen in the meantime.
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: service_unavailable
              message: The API is temporarily unavailable — retry later
              details: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: agk_live_<32 characters>
      description: >
        API key created in the Agentova app (Settings → API), sent as
        `Authorization: Bearer agk_live_…`. One key = one workspace: the key
        determines the workspace, and no workspace identifier ever travels in
        requests. The `Bearer` scheme is case-insensitive. A revoked key is
        refused immediately.

````

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