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

# Approve or reject a review

> Records a person's decision on a pending review and acts on it. A review is decided once.

**Approving** carries out the worker's action:
- `deal_update` and `classification_label`: Heliyos applies the change before it answers, the same way an
  edit in Heliyos would, and reports it in `applied`. If applying fails, nothing is recorded and the review
  stays pending.
- A saved email draft (`origin: artifact`): the draft is sent before the call answers. If sending fails, the
  approval is still recorded and `orchestrator.error` says why.
- Every other type: the worker's run resumes in the background and carries out the action. This happens only
  once every pending review of that run is decided (`orchestrator.pending` counts the rest). Read the run, or
  the review's `outcome`, to see the result. If the run is no longer waiting, the decision is recorded and
  nothing runs.

**Rejecting** drops the action and tells the worker your `feedback`. A saved email draft is discarded. As
with approval, a paused run resumes, without the action, once every review it waits on is decided.

**Changing the proposal before approving.** For `deal_update`, send the fields to write in `data` (and
`relationships` or `schemaId`). For other paused actions, send the changed arguments in `args`. They are
checked by the same rules as the worker's; if they fail, the action does not run and `outcome.error`
says why. `data`, `relationships`, `schemaId` and `args` are ignored on rejection. A saved email draft is
sent as saved: `args` does not change it.

**Already decided.** A review that is not pending answers 400 and nothing happens, so sending a decision
again after it succeeded does not repeat the action. Send one decision at a time per review: of two
decisions sent at the same moment on a deal or label review, one wins and the other answers 409.

**Who can decide.** Any member of the workspace, and any API key. A decision made with an API key counts as
a person's: it is recorded under the user who created the key and carried out exactly as if that person
had approved it in Heliyos. Deciding is blocked while the workspace's subscription is inactive.

`meta.message` is `Review approved.` or `Review rejected.`. When a deal or label change was applied but the
run could not be told yet, it is `Review approved; the change is applied, but the agent run could not be
notified.` and `orchestratorError` is set: the run picks the decision up later on its own.

> [!WARNING]
>
> Approving through the API carries out the worker's action as if a person clicked Approve in Heliyos: the
> email is sent, the deal is changed, the meeting is booked. It cannot be undone. Read the review with
> Get a review first, and approve only what a person has confirmed.

> [!NOTE]
>
> In the Heliyos MCP server: [`heliyos_reviews_decide`](https://docs.heliyos.ai/mcp/tools/ask-runs-and-reviews#heliyos-reviews-decide).


## OpenAPI

````yaml /api-reference/openapi.json post /v1/platform/reviews/{id}/decisions
openapi: 3.0.3
info:
  title: Heliyos API
  version: 1.0.0
  description: >-
    The REST API for Heliyos, the AI operating system for revenue. Every request
    is scoped to the workspace that owns the API key. Responses are JSON in a `{
    meta, data }` envelope; errors use `{ message, error: { code, message,
    details } }`.
  contact:
    name: Heliyos support
    email: soham@heliyos.ai
    url: https://www.heliyos.ai
servers:
  - url: https://api-prod.heliyos.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Workspace
    description: >-
      The workspace your API key belongs to, and the log of credits it has used.
      Every other call in this API is scoped to this workspace.
  - name: Schemas
    description: >-
      Objects are your record types: companies, people, deal pipelines and any
      custom objects you add. Each object has fields, and a field's type decides
      what its records can hold.
  - name: Records
    description: >-
      Records are the rows of an object (base schema): companies, people, deals
      and custom objects. A record holds field values keyed by the object's
      field keys and links to other records.
  - name: Timeline
    description: >-
      The AI-written timeline of a company, person or deal: summary entries
      Heliyos writes on a schedule. For the exact change history see Activities,
      and for emails and meetings see Interactions.
  - name: Activities
    description: >-
      The change history of records and tasks: who created, changed or deleted
      what, and when. People, workers and the system each appear as the actor on
      the changes they make.
  - name: Interactions
    description: >-
      Email threads and meetings synced from connected mailboxes and calendars,
      linked to the people and companies they involve.
  - name: Notes
    description: >-
      Free-text notes, optionally linked to records, tasks and interactions.
      Notes show up on the timeline of every record they are linked to, and
      workers read them as customer memory.
  - name: Tasks
    description: >-
      Work items for people and workers, optionally linked to records. A task
      can be assigned to people, to workers, or both, and workers can be started
      on it directly.
  - name: Workers and runs
    description: >-
      Workers are the AI teammates of your workspace (the API calls them
      agents). Define what each one does and what starts it, ask Heliyos to do
      work, and follow every run, its steps and the reviews it waits on.
  - name: Reviews
    description: >-
      Reviews keep the team in control of consequential work. When a worker
      wants to send an email, change a deal, book a meeting, act in a connected
      app or needs a person's answer, the action waits as a review until someone
      approves or rejects it.
  - name: Scouts
    description: >-
      Scouts watch companies and the web for events such as funding rounds,
      product launches, leadership changes or press coverage, and record each
      finding as a signal. A workspace Scout defines what to look for; company
      Scouts are its copies running on individual companies.
  - name: Signals
    description: >-
      Signals are what Scouts find: one event, such as a funding round or a new
      executive, with a summary, its sources and the company it is about. New
      signals are unread until you mark them read.
  - name: Watchlist
    description: >-
      The watchlist is the set of companies your workers monitor. Each watched
      company uses one Watcher from your plan: the workers keep it enriched,
      pull in its emails and meetings, and run Scouts on it.
  - name: Knowledge base
    description: >-
      What your workers know about the business: the business context, four
      fixed texts (products, pain points, value proposition, qualification
      criteria) and any custom entries your team adds. Workers read it on their
      next run. Files your workers read live under Files, with kind
      `knowledge_base`.
  - name: Files
    description: >-
      Knowledge base files that workers read, and files attached to records,
      tasks and other resources. The API calls them attachments. Uploading takes
      three calls: get an upload URL, send the bytes to it, then create the
      file.
  - name: Labels
    description: >-
      Label groups that sort your email threads, for example Intent or Pricing
      questions. Heliyos files each classified thread under a group, and each
      group holds the more specific labels it brings together. The API calls
      them classification labels.
  - name: Team
    description: >-
      The people in your workspace and their roles: joined members and pending
      invitations. Inviting someone sends them an email.
  - name: Notification settings
    description: >-
      Which workspace events send notification emails, how often, and to whom.
      There is one settings document per workspace, shared by everyone in it.
paths:
  /v1/platform/reviews/{id}/decisions:
    post:
      tags:
        - Reviews
      summary: Approve or reject a review
      description: >-
        Records a person's decision on a pending review and acts on it. A review
        is decided once.


        **Approving** carries out the worker's action:

        - `deal_update` and `classification_label`: Heliyos applies the change
        before it answers, the same way an
          edit in Heliyos would, and reports it in `applied`. If applying fails, nothing is recorded and the review
          stays pending.
        - A saved email draft (`origin: artifact`): the draft is sent before the
        call answers. If sending fails, the
          approval is still recorded and `orchestrator.error` says why.
        - Every other type: the worker's run resumes in the background and
        carries out the action. This happens only
          once every pending review of that run is decided (`orchestrator.pending` counts the rest). Read the run, or
          the review's `outcome`, to see the result. If the run is no longer waiting, the decision is recorded and
          nothing runs.

        **Rejecting** drops the action and tells the worker your `feedback`. A
        saved email draft is discarded. As

        with approval, a paused run resumes, without the action, once every
        review it waits on is decided.


        **Changing the proposal before approving.** For `deal_update`, send the
        fields to write in `data` (and

        `relationships` or `schemaId`). For other paused actions, send the
        changed arguments in `args`. They are

        checked by the same rules as the worker's; if they fail, the action does
        not run and `outcome.error`

        says why. `data`, `relationships`, `schemaId` and `args` are ignored on
        rejection. A saved email draft is

        sent as saved: `args` does not change it.


        **Already decided.** A review that is not pending answers 400 and
        nothing happens, so sending a decision

        again after it succeeded does not repeat the action. Send one decision
        at a time per review: of two

        decisions sent at the same moment on a deal or label review, one wins
        and the other answers 409.


        **Who can decide.** Any member of the workspace, and any API key. A
        decision made with an API key counts as

        a person's: it is recorded under the user who created the key and
        carried out exactly as if that person

        had approved it in Heliyos. Deciding is blocked while the workspace's
        subscription is inactive.


        `meta.message` is `Review approved.` or `Review rejected.`. When a deal
        or label change was applied but the

        run could not be told yet, it is `Review approved; the change is
        applied, but the agent run could not be

        notified.` and `orchestratorError` is set: the run picks the decision up
        later on its own.
      operationId: createReviewDecision
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            pattern: ^[0-9a-fA-F]{24}$
          description: The review's id.
          example: 6731f2c4d5e6f7a8b9c0d1e2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                decision:
                  type: string
                  enum:
                    - approved
                    - rejected
                  description: '`approved` carries out the action. `rejected` drops it.'
                  example: approved
                comment:
                  type: string
                  maxLength: 5000
                  nullable: true
                  description: >-
                    A note kept on the review, up to 5,000 characters. Empty or
                    null stores nothing.
                  example: Confirmed with Dana by phone.
                feedback:
                  type: string
                  maxLength: 5000
                  nullable: true
                  description: >-
                    What to tell the worker, up to 5,000 characters: why you
                    rejected it, what to change, or your answer to a question
                    (`kind: question`). Empty or null sends nothing.
                  example: Hold the email until legal signs off on the discount.
                data:
                  type: object
                  properties: {}
                  additionalProperties: true
                  description: >-
                    `deal_update`, approving only: the deal's fields to write,
                    as field key to value. Replaces the worker's proposed
                    fields, so include every field you want written. Validated
                    against the deal's object. Omit to write the proposal as it
                    is.
                  example:
                    stage: Negotiation
                    amount: 45000
                relationships:
                  type: array
                  items:
                    $ref: '#/components/schemas/ObjectId'
                  maxItems: 500
                  description: >-
                    `deal_update`, approving only: ids of the company and people
                    records to link to the deal, up to 500. Omit, or send an
                    empty list, to keep the links the worker proposed.
                schemaId:
                  type: string
                  pattern: ^[0-9a-fA-F]{24}$
                  allOf:
                    - $ref: '#/components/schemas/ObjectId'
                  description: >-
                    `deal_update` creating a deal, approving only: the pipeline
                    (deal object) to create it in. Defaults to the one the
                    worker proposed. Must be a deal object of this workspace.
                args:
                  type: object
                  properties: {}
                  additionalProperties: true
                  description: >-
                    A paused action, approving only: the arguments you changed,
                    by name, as in `proposal.args`. They are merged over the
                    worker's arguments, so send only what changes.
                  example:
                    start: '2026-11-12T15:00:00'
                    timezone: Europe/London
              required:
                - decision
              additionalProperties: false
            examples:
              approve:
                summary: Approve as proposed
                value:
                  decision: approved
              approveWithChanges:
                summary: Approve a deal change with edited fields
                value:
                  decision: approved
                  comment: Amount agreed on the call.
                  data:
                    stage: Negotiation
                    amount: 45000
              reject:
                summary: Reject and tell the worker why
                value:
                  decision: rejected
                  feedback: Hold the email until legal signs off on the discount.
      responses:
        '200':
          description: The decision and the review after it.
          content:
            application/json:
              schema:
                type: object
                required:
                  - meta
                  - data
                properties:
                  meta:
                    type: object
                    required:
                      - message
                    properties:
                      message:
                        type: string
                        description: A human-readable summary of the result.
                  data:
                    $ref: '#/components/schemas/ReviewDecisionResult'
              example:
                meta:
                  message: Review approved.
                data:
                  status: APPROVED
                  applied:
                    action: Update
                    dealId: 6730aa11bb22cc33dd44ee55
                    schemaId: 66a0f1e2d3c4b5a697880003
                    object:
                      _id: 6730aa11bb22cc33dd44ee55
                      objectType: deals
                      data:
                        deal_name: Contoso expansion
                        stage: Negotiation
                        amount: 45000
                  orchestrator:
                    status: APPROVED
                    runId: 1a2b3c4d5e6f708192a3b4c5d6e7f809
                    resuming: true
                  review:
                    _id: 6731f2c4d5e6f7a8b9c0d1e2
                    id: 6731f2c4d5e6f7a8b9c0d1e2
                    type: deal_update
                    status: APPROVED
                    approval:
                      status: APPROVED
                      by: 66a0f1e2d3c4b5a697881111
                      at: '2026-11-04T15:12:00.000Z'
                      comment: Amount agreed on the call.
                      feedback: null
                    outcome:
                      ok: true
                      at: '2026-11-04T15:12:00.000Z'
                      appliedBy: platform
                      action: Update
                      dealId: 6730aa11bb22cc33dd44ee55
        '400':
          description: >-
            VALIDATION_FAILED: the body is invalid; the review is already
            decided (`Review is already approved.`, `rejected` or `processing`);
            or, for a deal, the edited fields fail the deal object's validation,
            the chosen pipeline is not a deal object, or the record is not a
            deal. Nothing is changed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: >-
            FORBIDDEN_ACTION: your role cannot decide reviews, or the
            workspace's subscription is inactive.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: >-
            NOT_FOUND: no review with this id in the workspace, or the deal it
            changes (or that deal's object) no longer exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: >-
            CONFLICT: another decision on this deal or label review is being
            applied. Read the review before trying again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: >-
            The deal or label review cannot be applied as stored: it names no
            deal to update, no pipeline to create the deal in, or no label name.
            The review stays pending; reject it instead.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: >-
            The decision could not be passed to the worker's run. Read the
            review before retrying: if it is still `PENDING`, decide it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    ObjectId:
      type: string
      pattern: ^[0-9a-fA-F]{24}$
      description: A 24-character hexadecimal id.
      example: 66f1a8c3e4b0a1b2c3d4e5f6
    ReviewDecisionResult:
      type: object
      properties:
        status:
          type: string
          enum:
            - APPROVED
            - REJECTED
          description: The decision recorded.
        review:
          allOf:
            - $ref: '#/components/schemas/ReviewDetail'
          description: The review after the decision.
        applied:
          type: object
          additionalProperties: true
          description: >-
            Approved `deal_update` and `classification_label` reviews only: what
            Heliyos changed before answering. For a deal, `action` (`Create` or
            `Update`), `dealId`, `schemaId` and `object` (the deal as saved).
            For a label, `action` (`Create`, or `Exists` when a label with that
            name was already there), `labelId` and `name`.
        orchestrator:
          type: object
          nullable: true
          additionalProperties: true
          description: >
            What the worker run did with the decision:

            - `runId` and `resuming: true`: this was the last pending review of
            the run, which now resumes and carries out (or drops) the action.

            - `runId` and `pending`: the run still waits on this many other
            reviews. Nothing runs until they are decided.

            - `runId` alone: the run is no longer waiting, so nothing resumes.

            - `sent`: for a saved email draft, whether it was sent.

            - `error`: for a saved email draft, why sending or discarding
            failed. The decision is still recorded.
        orchestratorError:
          type: string
          description: >-
            Present when a deal or label change was applied and recorded but the
            worker run could not be told yet. The run picks the decision up
            later on its own.
    ErrorEnvelope:
      type: object
      required:
        - message
        - error
      properties:
        message:
          type: string
          description: Same as error.message.
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - VALIDATION_FAILED
                - UNAUTHENTICATED
                - FORBIDDEN_ACTION
                - NOT_FOUND
                - RATE_LIMITED
                - CONFLICT
                - INTERNAL
            message:
              type: string
            details: {}
    ReviewDetail:
      description: A review, with the records and work it refers to resolved.
      allOf:
        - $ref: '#/components/schemas/Review'
        - type: object
          properties:
            relatedObjects:
              type: array
              description: >-
                The company, people and deal records the review is about: those
                in `objectRefs` and those linked to the email thread or meeting
                it sits on. Full records, at most 50.
              items:
                type: object
                additionalProperties: true
            interactionData:
              type: object
              nullable: true
              additionalProperties: true
              description: >-
                The email thread or meeting `objectRef` points at, when it
                points at one.
            taskData:
              type: object
              nullable: true
              additionalProperties: true
              description: >-
                The task `taskMeta.objectId` (or `objectRef`) points at, when it
                points at one.
            previousVersionRelatedObjects:
              type: array
              description: '`deal_update`: the records linked to the deal as it is now.'
              items:
                type: object
                additionalProperties: true
            newVersionRelatedObjects:
              type: array
              description: '`deal_update`: the records linked to the deal as proposed.'
              items:
                type: object
                additionalProperties: true
    Review:
      type: object
      description: >-
        A worker action waiting for, or decided by, a person. Fields beyond the
        common ones depend on `type`. Reviews raised before a field existed may
        not carry it.
      additionalProperties: true
      properties:
        _id:
          $ref: '#/components/schemas/ObjectId'
        id:
          type: string
          description: The review's id, the same value as `_id`.
          example: 6731f0a9b2c4d5e6f7a8b9c0
        organizationId:
          allOf:
            - $ref: '#/components/schemas/ObjectId'
          description: The workspace the review belongs to.
        type:
          type: string
          description: >
            What is being reviewed. The set is open: actions in connected apps
            and actions your workspace defines

            use their own name. Common values:

            - `email_draft`: an email to send.

            - `deal_update`: a deal to create (`dealAction: Create`) or change
            (`dealAction: Update`).

            - `meeting_scheduled`: a meeting to book or reschedule.

            - `task`: a task to create or change.

            - `document`: a file to save on a record or task.

            - `note`: a note to create.

            - `object_create`, `object_update`: a record other than a deal to
            create or change.

            - `schedule`: a scheduled wake-up for a worker to create or cancel.

            - `plan`: a plan the worker wants approved before it acts.

            - `decision`: a question the worker asked (`kind: question`) or an
            approval it asked for before going on.

            - `classification_label`: a new label to create.
          example: email_draft
        kind:
          type: string
          description: |
            - `action`: a paused action. Approving lets it run.
            - `plan`: a plan. Approving lets the worker carry it out.
            - `question`: a question for a person. Answer it in `feedback`.
            - `approval`: a saved email draft. Approving sends it.
          example: action
        origin:
          type: string
          description: >
            - `model`: the worker's run is paused on this action and resumes
            when it is decided.

            - `artifact`: the work is already saved (an email draft on its
            thread) and the decision acts on it. The run does not wait for it.

            - `autopilot`: the action ran without a person under the workspace's
            autopilot settings. Kept for the record, already `APPROVED`.
          example: model
        status:
          type: string
          enum:
            - PENDING
            - APPROVED
            - REJECTED
          description: >-
            The decision, mirrored from `approval.status`. Read
            `approval.status` for the current value.
        approval:
          $ref: '#/components/schemas/ReviewApproval'
        agent:
          type: string
          nullable: true
          description: The name of the worker that raised the review.
          example: Account researcher
        agentRef:
          type: object
          description: The worker that raised the review.
          properties:
            id:
              type: string
              nullable: true
              description: The worker's id. Null when Heliyos itself raised it.
            name:
              type: string
              description: The worker's name.
        runId:
          type: string
          nullable: true
          description: >-
            The run that raised the review. Read it with `GET
            /v1/platform/workers/runs/{id}`. A pending review a later run
            proposed again points at that later run.
          example: 0f1e2d3c4b5a69788766554433221100
        agentRunId:
          type: string
          nullable: true
          description: The same value as `runId`, under its older name.
        previousRunId:
          type: string
          description: >-
            The run the review pointed at before a later run proposed the same
            change again.
        revisions:
          type: integer
          description: >-
            How many times a later run replaced the proposal while the review
            was pending.
        surface:
          type: string
          description: >-
            Where the run that raised it started, for example `chat` or
            `background`.
        taskId:
          type: string
          nullable: true
          description: The task the run worked on, when it worked on one.
        threadId:
          type: string
          nullable: true
          description: The chat conversation the run belongs to, when it started in chat.
        tool:
          type: object
          description: The action the worker wants to take.
          properties:
            name:
              type: string
              description: >-
                The action's name, for example `send_email` or
                `schedule_meeting`.
            callId:
              type: string
              description: Identifies this one call within the run.
        proposal:
          type: object
          description: What the worker proposes.
          properties:
            title:
              type: string
              description: 'A one-line title, for example `Send email: Renewal terms`.'
            summary:
              type: string
              nullable: true
              description: The proposal in a sentence or two.
            args:
              type: object
              additionalProperties: true
              description: >-
                The action's arguments as the worker proposed them. Send changed
                values in `args` when you approve.
        proposedOutput:
          type: object
          additionalProperties: true
          description: The same arguments as `proposal.args`.
        confidence:
          type: number
          nullable: true
          description: >-
            How sure the worker said it was, from 0 to 100. Null when it did not
            say.
          example: 72
        reasoning:
          type: string
          description: >-
            Why the worker proposes the action, in its own words. Empty when it
            gave no reason.
        approvalReason:
          type: string
          nullable: true
          description: >-
            Why the action waits for a person, for example because approval is
            required for this kind of action or the stated confidence is below
            the workspace's threshold.
        objectRef:
          allOf:
            - $ref: '#/components/schemas/ReviewObjectRef'
          description: The first of `objectRefs`.
        objectRefs:
          type: array
          description: The records and tasks the review is about.
          items:
            $ref: '#/components/schemas/ReviewObjectRef'
        dealAction:
          type: string
          enum:
            - Create
            - Update
          description: >-
            `deal_update`: whether the deal is new or an existing one changes.
            `meeting_scheduled`: `Create` for a new meeting, `Update` for a
            reschedule.
        previousVersion:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            `deal_update` with `Update`: the deal as it is now (`_id`, `data`,
            `relationships`). Null for a new deal.
        newVersion:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            `deal_update`: the deal as it would be if approved (`data`,
            `relationships`, and for a new deal the `schemaId` of its pipeline).
            After an approval with edited fields, the fields as approved.
        draftEmail:
          type: object
          additionalProperties: true
          description: >-
            `email_draft`: the email (`subject`, `body`, `from`, `to`, `cc`,
            `bcc`, `attachments`, and `interactionThreadId`, the email thread it
            belongs to). Recipients are email addresses or `{ email, name }`
            objects.
        draft:
          type: object
          additionalProperties: true
          description: >-
            `email_draft` with `origin: artifact`: where the saved draft lives
            (`interactionId` of the email thread, `messageId`).
        meetingDetails:
          type: object
          additionalProperties: true
          description: >-
            `meeting_scheduled`: the proposed event (`title`, `startTime`,
            `endTime`, `timezone`, `participants`, `description`, `location`,
            `conferencing` and the rest of the event's fields).
        taskMeta:
          type: object
          additionalProperties: true
          description: >-
            `task`: the task (`title`, `objectId` of an existing task, `status`,
            `dueDate`, `description`).
        documentMeta:
          type: object
          additionalProperties: true
          description: >-
            `document`: the file (`fileName`, `description`, and when it can be
            opened, `url`, `mimeType`, `size`, `objectAttachmentId`).
        noteMeta:
          type: object
          additionalProperties: true
          description: '`note`: the note (`title`, `content`).'
        categoryName:
          type: string
          description: '`classification_label`: the name of the label to create.'
        categoryDescription:
          type: string
          description: '`classification_label`: the label''s description.'
        outcome:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            What happened after the decision. `ok` (whether it worked), `at`,
            and `error` when it failed. For an action a run carried out,
            `result` with what the action returned. For a deal or label Heliyos
            applied on approval, `appliedBy: platform` with `action`, `dealId`
            or `labelId`. Absent until something happened.
        metadata:
          type: object
          description: When the review was raised and last changed.
          properties:
            created:
              type: object
              properties:
                at:
                  $ref: '#/components/schemas/Timestamp'
            updated:
              type: object
              properties:
                at:
                  $ref: '#/components/schemas/Timestamp'
    ReviewApproval:
      type: object
      description: The decision. This is the review's authoritative status.
      properties:
        status:
          type: string
          enum:
            - PENDING
            - PROCESSING
            - APPROVED
            - REJECTED
          description: >
            - `PENDING`: waiting for a person.

            - `PROCESSING`: a decision on a `deal_update` or
            `classification_label` review is being applied right now. It moves
            to `APPROVED` or `REJECTED` within the same request, or back to
            `PENDING` if applying failed.

            - `APPROVED`: approved by a person, or let through by the
            workspace's autopilot settings (then `by` is `autopilot`).

            - `REJECTED`: rejected by a person.
        by:
          type: string
          nullable: true
          description: >-
            Id of the user who decided. A decision made with an API key is
            recorded under the user who created the key. `autopilot` when the
            workspace's autopilot settings approved the action without a person.
            Null while pending.
          example: 66a0f1e2d3c4b5a697881111
        at:
          allOf:
            - $ref: '#/components/schemas/Timestamp'
          nullable: true
          description: When it was decided. Null while pending.
        comment:
          type: string
          nullable: true
          description: The reviewer's note, kept on the review.
        feedback:
          type: string
          nullable: true
          description: What the reviewer told the worker, for example why it was rejected.
        editedArgs:
          type: object
          additionalProperties: true
          description: >-
            The action's arguments as the reviewer changed them on approval,
            when they changed any.
    ReviewObjectRef:
      type: object
      description: A record or task the review is about.
      additionalProperties: true
      properties:
        objectId:
          type: string
          description: Id of the record or task.
          example: 66f1a8c3e4b0a1b2c3d4e5f6
        objectType:
          type: string
          nullable: true
          description: '`company`, `people`, `deals`, a custom object''s type, or `task`.'
          example: company
        name:
          type: string
          description: The record's display name, when the worker could resolve it.
          example: Northwind Traders
    Timestamp:
      type: string
      format: date-time
      description: An ISO 8601 date-time in UTC.
      example: '2026-11-04T09:30:00.000Z'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A workspace API key, sent as `Authorization: Bearer heliyos_...`. Create
        one in Heliyos under Settings → API keys. A key acts as a workspace
        admin in the one workspace it was created in.

````

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