> ## 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.

# Update a Loop

> Partial update. A paused Loop resumes from its next slot. `wake_on` replaces everything that wakes the Loop (send it alone, or with `name`, `prompt`, `notification_policy`, `until`, `max_runs` and `model`; a single entry of the kind already waking it changes that in place); a webhook it adds returns its URL and key once, as on create. Switching the Loop on, or onto another Session or model, checks the workspace can fund it (402 `loop_model_not_fundable`). Who sees and changes a Loop follows its Reason: the people who can use the Reason see and change its Loops, except that a teammate's Loop on a team Reason stays that teammate's (the Reason's owner may see and stop it). Workspace owners and admins may pause and delete any Loop.What a Loop runs in (its Session or computer), its Slack channels and what wakes it stay with its creator, since each is checked against their access (403 `loop_creator_only_change`).

<sub>Scope: `automations:write`</sub>



## OpenAPI

````yaml /openapi.json patch /v3/organizations/{orgId}/reasons/{reasonId}/loops/{loopId}
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:
  /v3/organizations/{orgId}/reasons/{reasonId}/loops/{loopId}:
    parameters:
      - $ref: '#/components/parameters/orgId'
      - name: reasonId
        description: The Reason id, returned as `id` by `listReasons` and `createReason`.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: loopId
        description: >-
          The Loop id, returned as `id` by `listReasonLoops` and as `loop.id` by
          `createReasonLoop`.
        in: path
        required: true
        schema:
          type: string
          format: uuid
    patch:
      tags:
        - Loops
      summary: Update a Loop
      description: >-
        Partial update. A paused Loop resumes from its next slot. `wake_on`
        replaces everything that wakes the Loop (send it alone, or with `name`,
        `prompt`, `notification_policy`, `until`, `max_runs` and `model`; a
        single entry of the kind already waking it changes that in place); a
        webhook it adds returns its URL and key once, as on create. Switching
        the Loop on, or onto another Session or model, checks the workspace can
        fund it (402 `loop_model_not_fundable`). Who sees and changes a Loop
        follows its Reason: the people who can use the Reason see and change its
        Loops, except that a teammate's Loop on a team Reason stays that
        teammate's (the Reason's owner may see and stop it). Workspace owners
        and admins may pause and delete any Loop.What a Loop runs in (its
        Session or computer), its Slack channels and what wakes it stay with its
        creator, since each is checked against their access (403
        `loop_creator_only_change`).


        <sub>Scope: `automations:write`</sub>
      operationId: updateReasonLoop
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateReasonLoop'
      responses:
        '200':
          description: The updated Loop, and a webhook it just gave out.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReasonLoopWrite'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: >-
            The workspace's plan or credits can't run this Loop's model
            (`loop_model_not_fundable`).
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >-
            The change can't apply to the Loop as it is (for example
            `loop_paused` or `loop_runs_used_up`); the message says what to do.
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - reasonApiKey:
            - automations:write
components:
  parameters:
    orgId:
      name: orgId
      in: path
      required: true
      description: Organization id or slug. Resolve it with `GET /v3/self`.
      schema:
        type: string
  schemas:
    UpdateReasonLoop:
      type: object
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 100000
          description: New instructions for its future wakes.
        name:
          type: string
          minLength: 1
          maxLength: 200
        enabled:
          type: boolean
          description: '`false` pauses it; `true` resumes it from its next slot.'
        schedule:
          type: string
          minLength: 1
          maxLength: 500
          description: >-
            A new schedule for a Loop that has one, in the same forms as a
            `wake_on` schedule.
        webhook:
          type: object
          properties:
            signing_secret_name:
              description: >-
                Name of a stored secret (the Reason's or the caller's) that the
                sender generated and signs with, such as Stripe's `whsec_`
                secret. `null` removes it. Without one, senders use the Loop's
                own key.
              type:
                - string
                - 'null'
              minLength: 1
              maxLength: 128
            condition:
              type:
                - string
                - 'null'
              minLength: 1
              maxLength: 500
              description: >-
                Plain words a small model checks each event against before it
                opens a Session, for example `a bug report or a complaint, not
                praise`. An unclear answer still wakes the Loop.
          description: A webhook Loop's signing secret or condition, changed in place.
        wake_on:
          minItems: 1
          maxItems: 8
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/LoopScheduleWake'
              - $ref: '#/components/schemas/LoopWebhookWake'
              - $ref: '#/components/schemas/LoopGithubWake'
              - $ref: '#/components/schemas/LoopSlackWake'
          description: >-
            Everything that wakes the Loop: at most one schedule, one webhook
            and one Slack listener, and GitHub events on one repository. A Loop
            woken by several things at once is in early access for some
            workspaces (403 `wake_on_unavailable` elsewhere). On update it
            replaces what wakes the Loop.
          example:
            - schedule: 0 9 * * 1-5
            - webhook: {}
        until:
          format: date-time
          description: >-
            End of a scheduled Loop: no wake after this time, then it reads
            `completed`. `null` clears it. A Loop woken by events has no end of
            its own.
          type:
            - string
            - 'null'
        max_runs:
          description: >-
            How many runs a scheduled Loop makes before it reads `completed`,
            counted from when it is set. `null` clears it.
          type:
            - integer
            - 'null'
          minimum: 1
          maximum: 100000
        execution_mode:
          type: string
          enum:
            - session
            - new_session
          description: >-
            `session` continues one Session across wakes, the one in
            `session_id` or else one of the Loop's own that its first wake
            opens; `new_session` opens a fresh Session on every wake. A Loop
            woken by events opens a Session per event (events sharing a
            correlation key continue one), so it takes neither.
        session_id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            An existing Session of the caller's that each wake continues. `null`
            unbinds it.
        device_id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            A connected computer of the caller's (`listDevices`) that its runs
            use; `null` runs them on a Reason cloud machine.
        notification_policy:
          type: string
          enum:
            - important_updates
            - failed_runs_only
          description: >-
            When the Loop tells the person about a run: on important updates
            (the default) or only when a run fails.
        timezone:
          type: string
          minLength: 1
          maxLength: 120
          description: >-
            IANA time zone a cron schedule is read in, such as
            `America/Los_Angeles`. Defaults to UTC, or keeps the Loop's own on
            update.
        model:
          description: >-
            Model its runs use, as a Session model id. `null` or `auto` runs it
            on the model of the Session it continues, or the workspace's. An id
            the workspace cannot pin returns 400 `invalid_model`.
          type:
            - string
            - 'null'
          minLength: 1
          maxLength: 200
      description: >-
        Only the fields sent change. `wake_on` replaces what wakes the Loop;
        send it with only `name`, `prompt`, `notification_policy`, `until`,
        `max_runs` and `model`.
    ReasonLoopWrite:
      type: object
      properties:
        loop:
          $ref: '#/components/schemas/ReasonLoop'
        webhook:
          $ref: '#/components/schemas/LoopWebhookKey'
      required:
        - loop
      description: The Loop as saved, and the webhook it just gave out, when it did.
    LoopScheduleWake:
      type: object
      properties:
        schedule:
          type: string
          minLength: 1
          maxLength: 500
          description: >-
            When it wakes: a one-time ISO 8601 time with `Z` or an offset, a
            fixed interval such as `every 30 minutes` (60 seconds at least), or
            a cron expression such as `0 9 * * 1-5`, read in `timezone`.
          example: 0 9 * * 1-5
      required:
        - schedule
      description: Wake on a schedule.
    LoopWebhookWake:
      type: object
      properties:
        webhook:
          type: object
          properties:
            signing_secret_name:
              description: >-
                Name of a stored secret (the Reason's or the caller's) that the
                sender generated and signs with, such as Stripe's `whsec_`
                secret. `null` removes it. Without one, senders use the Loop's
                own key.
              type:
                - string
                - 'null'
              minLength: 1
              maxLength: 128
            condition:
              type:
                - string
                - 'null'
              minLength: 1
              maxLength: 500
              description: >-
                Plain words a small model checks each event against before it
                opens a Session, for example `a bug report or a complaint, not
                praise`. An unclear answer still wakes the Loop.
          description: Options for the webhook the Loop gives out. Send `{}` for none.
      required:
        - webhook
      description: >-
        Wake on each event POSTed to a webhook the Loop gives out
        (`receiveLoopWebhookEvent`). The URL and its key come back once, in the
        response that adds it.
    LoopGithubWake:
      type: object
      properties:
        github:
          type: object
          properties:
            repo:
              type: string
              minLength: 3
              maxLength: 200
              description: >-
                `owner/name` of a GitHub repository connected to the workspace;
                the Loop's runs work in it.
            event:
              type: string
              enum:
                - issue_opened
                - issue_labeled
                - issue_closed
                - pr_opened
                - pr_reopened
                - pr_ready_for_review
                - pr_pushed
                - pr_closed
                - pr_review_submitted
              description: >-
                What on GitHub wakes it. `issue_labeled` and `issue_closed` need
                `filters.label`; `pr_closed` includes merged pull requests.
            filters:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                  maxLength: 100
                author:
                  minItems: 1
                  maxItems: 20
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 100
                title_contains:
                  type: string
                  minLength: 1
                  maxLength: 200
              description: >-
                Only issues or pull requests matching every filter given wake
                it.
          required:
            - repo
            - event
      required:
        - github
      description: Wake on a GitHub event in a connected repository.
    LoopSlackWake:
      type: object
      properties:
        slack:
          type: object
          properties:
            channels:
              minItems: 1
              maxItems: 500
              type: array
              items:
                type: string
                minLength: 3
                maxLength: 40
              description: >-
                Slack channel ids, such as `C0123ABCD`, that Reason's Slack app
                is in.
            matches:
              minItems: 1
              maxItems: 8
              type: array
              items:
                type: object
                properties:
                  kind:
                    type: string
                    enum:
                      - message
                      - mention
                      - keyword
                      - reaction
                required:
                  - kind
              description: >-
                What in those channels wakes it: `{"kind":"message"}` any new
                message (the default), `{"kind":"mention"}`,
                `{"kind":"keyword","words":[...]}` or
                `{"kind":"reaction","emoji":[...],"owner_only":false}`.
            from_users:
              maxItems: 200
              type: array
              items:
                type: string
                minLength: 3
                maxLength: 40
              description: >-
                Slack user ids; only these people wake it. Empty or absent is
                anyone.
            include_apps:
              type: boolean
              description: >-
                Other apps' posts wake it too: emails sent to the channel,
                alerts and integrations.
            flag_channel:
              description: Slack channel id where the Reason flags things for the team.
              type:
                - string
                - 'null'
              minLength: 3
              maxLength: 40
            condition:
              type: string
              minLength: 1
              maxLength: 500
              description: >-
                Plain words a small model checks each event against before it
                opens a Session, for example `a bug report or a complaint, not
                praise`. An unclear answer still wakes the Loop.
          required:
            - channels
      required:
        - slack
      description: >-
        Wake on Slack messages; the Loop answers as its Reason, one Session per
        Slack thread.
    ReasonLoop:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Loop id. Pass it as `loopId`.
        reason_id:
          type: string
          format: uuid
          description: >-
            The Reason the Loop is filed under; its runs are that Reason's
            Sessions.
        name:
          type: string
        prompt:
          type: string
          description: The instructions each wake follows.
        enabled:
          type: boolean
        status:
          type: string
          enum:
            - active
            - paused
            - completed
            - failed
          description: >-
            `completed` when a scheduled Loop reached its `until` or `max_runs`;
            `paused` names why in `paused_reason`.
        paused_reason:
          description: >-
            Why the scheduler paused it (for example `out_of_credits` or
            `repeated_failures`); null when it is not paused or was paused by
            hand.
          type:
            - string
            - 'null'
        trigger_description:
          type: string
          description: What wakes it, in words.
        wakes_on:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                enum:
                  - schedule
                  - slack
                  - webhook
                  - github
              description:
                type: string
            required:
              - kind
              - description
        schedule:
          description: Its schedule; null when only events wake it.
          type:
            - object
            - 'null'
          properties:
            kind:
              type: string
              enum:
                - every
                - cron
                - at
            expression:
              type:
                - string
                - 'null'
            every_seconds:
              type:
                - integer
                - 'null'
            timezone:
              type: string
            next_run_at:
              type:
                - string
                - 'null'
              format: date-time
          required:
            - kind
            - expression
            - every_seconds
            - timezone
            - next_run_at
        event_trigger:
          type:
            - object
            - 'null'
          properties:
            kind:
              type: string
              enum:
                - webhook
                - github
            url:
              description: >-
                For a webhook: where senders POST; null when this server has no
                public URL. The key is never returned here.
              type:
                - string
                - 'null'
          required:
            - kind
        slack:
          description: >-
            The Slack channels that wake it and its health; null when Slack does
            not.
          type:
            - object
            - 'null'
          properties: {}
        execution_mode:
          type: string
          enum:
            - session
            - new_session
        session_id:
          description: The Session it is bound to, when one is.
          type:
            - string
            - 'null'
        latest_session_id:
          description: The Session its most recent wake ran in.
          type:
            - string
            - 'null'
        device_id:
          type:
            - string
            - 'null'
        repository:
          type:
            - string
            - 'null'
        model:
          type:
            - string
            - 'null'
        notification_policy:
          type: string
          enum:
            - important_updates
            - failed_runs_only
        until:
          type:
            - string
            - 'null'
          format: date-time
        max_runs:
          type:
            - integer
            - 'null'
        run_count:
          type: integer
        last_run:
          type:
            - object
            - 'null'
          properties:
            status:
              type: string
            at:
              type: string
            session_id:
              type: string
          required:
            - status
            - at
            - session_id
        created_by_user_id:
          type: string
          format: uuid
          description: Who created it; its runs are billed as theirs.
        viewer_access:
          type: object
          properties:
            edit:
              type: boolean
            stop:
              type: boolean
          required:
            - edit
            - stop
          description: >-
            What the caller may do with it: change what it runs (`edit`), or
            pause and delete it (`stop`). Present on reads (list and get).
      required:
        - id
        - reason_id
        - name
        - prompt
        - enabled
        - status
        - paused_reason
        - schedule
        - slack
        - execution_mode
        - session_id
        - latest_session_id
        - device_id
        - repository
        - model
        - notification_policy
        - until
        - max_runs
        - run_count
        - last_run
        - created_by_user_id
      description: >-
        A Loop: standing work a Reason does, woken by a schedule or an event.
        Each wake opens or continues a Session of the Reason.
    LoopWebhookKey:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: >-
            Where senders POST events (`receiveLoopWebhookEvent`). Also readable
            later as `event_trigger.url`.
        key:
          type: string
          description: >-
            The webhook's key, shown only in this response: send it as
            `Authorization: Bearer <key>`, sign the body with it, or append it
            to the URL as a last path segment. Store it now; it is never
            readable again.
      required:
        - url
        - key
      description: The webhook a Loop just gave out, returned once.
    Error:
      type: object
      properties:
        error:
          oneOf:
            - type: string
            - type: object
              required:
                - type
                - message
              properties:
                type:
                  type: string
                message:
                  type: string
                request_id:
                  type:
                    - string
                    - 'null'
        message:
          type: string
        required_scope:
          type: string
          description: >-
            The capability required when the request was denied for a missing
            scope.
  responses:
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: prompt_required
    Unauthorized:
      description: Missing, invalid, or expired key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: missing_bearer
            message: Authorization required
    Forbidden:
      description: The key lacks the required scope or role.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: missing_scope
            required_scope: sessions:read
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: session_not_found
    RateLimited:
      description: >-
        Too many requests. Retry after the number of seconds in the
        `Retry-After` response header.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 1
          required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: rate_limited
              message: This API key exceeded its request-rate limit
  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.