> ## Documentation Index
> Fetch the complete documentation index at: https://ara-90a60a07.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Send an event to a Loop (key in the URL)

> Delivers an event to the Loop whose webhook this is. A Loop with a webhook wakes on each accepted event: the event opens a Session of its Reason, or continues the Session of earlier events with the same correlation key. The webhook URL and its key come back once, from the `createReasonLoop` (or `updateReasonLoop`) call that adds the webhook.

This form carries the key as the URL's last path segment, for a sender that only takes a URL. Prefer the bearer header or a signature where the sender allows one: a URL is easier to leak.

A retry with the same event id is answered 202 with `duplicate: true` and is not queued again. A paused or deleted Loop refuses events (409 `automation_disabled`).

<sub>Auth: the Loop's webhook key (bearer, body signature, or URL segment) only; API keys are not accepted</sub>



## OpenAPI

````yaml /openapi.json post /webhooks/automations/{publicToken}/{key}
openapi: 3.1.0
info:
  title: Reason API
  version: 3.0.0
  description: >-
    The Reason HTTP API. Drive cloud software-engineering agents: open sessions
    against your repositories, stream their work, and manage the secrets,
    skills, and automations they run with.


    Authenticate with a Reason API key sent as a bearer token. New keys use
    `reason_`; legacy `ara_` keys remain accepted. Every resource is scoped to
    an organization; resolve your `org_id` once with `GET /v3/self`.
servers:
  - url: https://api.reasonmachines.com
security:
  - reasonApiKey: []
tags:
  - name: Account
    description: Verify a key and resolve the organization it belongs to.
  - name: Reasons
    description: >-
      Start here. A Reason is the long-running agent a person keeps: their main
      Reason and named ones, each with its own instructions, default model and
      repositories, conversation, Loops and Sessions. Give a Reason work by
      messaging it (sendReasonMessage) and read its replies with
      listReasonMessages.
  - name: Loops
    description: >-
      Standing work a Reason does, woken by a schedule or an event: a webhook, a
      GitHub event or a Slack message. Each wake opens or continues a Session of
      the Reason; webhook events that share a correlation key continue one
      Session.
  - name: Memory
    description: >-
      What Reasons remember across Sessions. Each Session starts by reading
      MEMORY.md (a short index) and the list of topic notes, and reads a note
      when its topic comes up. `personal` memory belongs to one person (the API
      key's owner) and only their Sessions read it; `team` memory belongs to the
      Workspace and every member's Sessions read it. memory:read lists, reads
      and searches; memory:write writes and deletes, in team memory only for a
      Workspace owner or admin.
  - name: Sessions
    description: >-
      A Session is one run of work inside a Reason: every Reason message and
      Loop wake runs in one, and createSession starts one directly for a single
      unattended task with a pass/fail outcome. Its transcript, events, result
      and pull request are read here.
  - name: Skills
    description: >-
      Reusable instruction bundles Reason selects semantically from their
      descriptions for matching agent tasks.
  - name: Secrets
    description: >-
      Encrypted credentials injected into the agent's sandbox. Write-only:
      values can be set but never read back.
  - name: Attachments
    description: >-
      Files uploaded to the organization and shared with sessions, downloaded
      via short-lived signed URLs.
  - name: Repositories
    description: Connected repositories, their indexing state, and generated wikis.
  - name: Git Connections
    description: Linked source-control accounts and the repositories they expose.
  - name: Machines
    description: >-
      Named Workspace queues served by headless workers. Sessions target a
      Machine by name and wait for a free worker; more workers serve more
      Sessions concurrently.
  - name: Devices
    description: >-
      Owned Mac and headless Device identity, bounded enrollment and root
      grants.
  - name: Cloud Access
    description: >-
      Keyless cloud sign-in for sessions: Reason's OIDC issuer facts and the
      AWS, Google Cloud and Azure connections a workspace trusts, including
      which run triggers each one signs in.
  - name: MCP Servers
    description: >-
      Org-level Model Context Protocol servers exposed to the agent. Secret
      values are write-only.
  - name: Change Request Reviews
    description: >-
      Automated senior-engineer reviews posted on pull requests and merge
      requests.
  - name: Consumption
    description: 'Billing-aligned usage: daily consumption and billing cycles.'
  - name: Metrics
    description: Aggregate analytics over sessions, change requests, and usage.
  - name: Audit Logs
    description: An append-only record of changes made within the organization.
  - name: Organizations
    description: The top-level tenant. Create, read, update, and delete organizations.
  - name: Members
    description: People in an organization and their pending invites.
  - name: Roles
    description: Role assignments that govern what each member can do.
  - name: Settings
    description: 'Organization configuration: namespaced settings and the run tag policy.'
  - name: Provider credentials
    description: >-
      Configure Bring-Your-Own-Key (BYOK) API keys and subscription credentials
      for model providers. Secret values are write-only.
  - name: Feedback
    description: Report problems with the API or these docs to the Reason team.
  - name: Projects
    description: >-
      Deprecated: a project is a Reason with the same id. Use the Reasons
      operations; these remain for existing clients.
  - name: Automations
    description: >-
      The older form of Loops. Prefer the Loops under a Reason (listReasonLoops,
      createReasonLoop), which take every wake: schedule, webhook, GitHub,
      Slack. Use these for what Loops do not carry yet: a run's MCP and app
      tools, and automations not filed under a Reason.
paths:
  /webhooks/automations/{publicToken}/{key}:
    parameters:
      - name: publicToken
        description: >-
          The webhook's public token: the last segment of the webhook URL
          `createReasonLoop` returns. It names the webhook and authenticates
          nothing.
        in: path
        required: true
        schema:
          type: string
      - name: key
        description: The Loop's webhook key, for a sender that only takes a URL.
        in: path
        required: true
        schema:
          type: string
    post:
      tags:
        - Loops
      summary: Send an event to a Loop (key in the URL)
      description: >-
        Delivers an event to the Loop whose webhook this is. A Loop with a
        webhook wakes on each accepted event: the event opens a Session of its
        Reason, or continues the Session of earlier events with the same
        correlation key. The webhook URL and its key come back once, from the
        `createReasonLoop` (or `updateReasonLoop`) call that adds the webhook.


        This form carries the key as the URL's last path segment, for a sender
        that only takes a URL. Prefer the bearer header or a signature where the
        sender allows one: a URL is easier to leak.


        A retry with the same event id is answered 202 with `duplicate: true`
        and is not queued again. A paused or deleted Loop refuses events (409
        `automation_disabled`).


        <sub>Auth: the Loop's webhook key (bearer, body signature, or URL
        segment) only; API keys are not accepted</sub>
      operationId: receiveLoopWebhookEventWithKeyInPath
      parameters:
        - name: X-Webhook-Correlation-Key
          in: header
          required: false
          schema:
            type: string
            maxLength: 500
          description: >-
            Events with the same key continue one Session; without it (or a key
            in the body) each event opens its own.
        - name: X-Webhook-Event-Id
          in: header
          required: false
          schema:
            type: string
            maxLength: 240
          description: >-
            The sender's id for the event; a retry with the same id is answered
            as a duplicate and queued once. Without one (or an id in the body),
            every POST is a new event.
        - name: X-Webhook-Event-Source
          in: header
          required: false
          schema:
            type: string
            maxLength: 80
          description: Which system sent the event, shown with it.
        - name: X-Signature-256
          in: header
          required: false
          schema:
            type: string
          description: >-
            For a sender you write: hex HMAC-SHA256 of the exact body bytes,
            keyed with the Loop's webhook key (or its signing secret),
            optionally prefixed `sha256=`. `X-Signature` is read the same way.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              vendor: zod
      responses:
        '202':
          description: Accepted, or a duplicate of an event already accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoopWebhookAccepted'
        '400':
          description: >-
            The body is not a JSON object (`invalid_json`, `invalid_payload`),
            or an id or correlation key is too long (`identifier_too_long`).
        '401':
          description: >-
            No valid key or signature for this webhook (`unauthorized`); a
            signature that failed says so in `detail`.
        '409':
          description: The Loop is paused or deleted (`automation_disabled`).
        '413':
          description: The body is over 256 KiB (`payload_too_large`).
        '503':
          description: >-
            Events are not being taken on this deployment right now; retry
            later.
      security: []
components:
  schemas:
    LoopWebhookAccepted:
      type: object
      properties:
        accepted:
          type: boolean
          const: true
        duplicate:
          type: boolean
          description: >-
            True when an event with the same id already arrived: this one is not
            queued again, and the earlier event's ids are returned.
        event_id:
          type: string
          description: The stored event.
        work_item_id:
          description: >-
            The unit of work its correlation key groups it into: one Session per
            work item.
          type:
            - string
            - 'null'
      required:
        - accepted
        - duplicate
        - event_id
        - work_item_id
  securitySchemes:
    reasonApiKey:
      type: http
      scheme: bearer
      bearerFormat: 'reason_<hex> (legacy: ara_<hex>)'
      description: >-
        Your Reason API key from Settings › API keys. New keys use `reason_`;
        legacy `ara_` keys remain accepted. Keys are capability-scoped: run,
        mcp:read, mcp:write, secrets:read, secrets:write, sessions:read,
        sessions:debug, knowledge:read, memory:read, memory:write, skills:read,
        skills:write, repos:read, repos:write, reviews:read, reviews:write,
        deployment:read, analytics:read, org:read, org:write, attachments:read,
        attachments:write, guardrails:read, guardrails:write, network:read,
        network:write, automations:read, automations:write, agent_auth:read.
        network:read and network:write are opt-in, excluded from default keys.
        network:read reads the saved workspace network policy; network:write
        replaces custom allowed hosts and requires a current organization
        owner/admin. Legacy project PATCH requests containing
        network_allowed_hosts also require network:write plus their existing run
        scope and project management permission; saved project hosts do not
        affect current session egress. Only owners/admins can mint or manage
        keys with network:write; keys cannot grant themselves more authority.
        See /docs/network-policies for replacement semantics and runtime
        applicability. mcp:write manages MCP server configuration only; it does
        not authorize remote MCP-tool execution. sessions:read reads sessions,
        including the assistant, reasoning and tool activity in their events.
        sessions:debug is privileged: only for organization owners/admins, it
        expands session events to the full diagnostic projection (diagnostic
        event kinds, status text and raw event metadata).

````

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