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

# Mark a Needs human task done

> Say a person handled what a Browser use run could not (a task whose `channel` is `browser`). It leaves the Open tab and changes nothing about the contact, who already went on down the Needs human arm. 409 when it is already done or was withdrawn with its sequence; 422 for any other task, which is approved or rejected instead.



## OpenAPI

````yaml /openapi.json post /outreach-tasks/{task_id}/complete/
openapi: 3.1.0
info:
  contact:
    email: support@getoneprofile.ai
    name: Oneprofile Support
  description: >-
    REST API reference for Oneprofile, the GTM data layer for your CRM. Manage
    tables, enrichments, and integrations. Authenticate with an API key to get
    started.
  termsOfService: https://www.getoneprofile.ai/terms
  title: API Reference | Oneprofile
  version: '0.0'
servers:
  - url: https://api.getoneprofile.ai
security: []
tags:
  - description: >-
      The docked AI Assistant: its general chat about the workspace and the
      product, streamed as Server-Sent Events, and the one list of a person's
      threads across every assistant, with pin, rename, delete and the
      search-to-table link.
    name: assistant
  - description: >-
      The messages a person keeps to send the assistant again: the ones the
      workspace saved and the ones that ship with the product, with save,
      rename, edit and delete.
    name: assistant-prompt
  - description: >-
      Granted workspace actions: what the AI Assistant proposed or applied in a
      conversation, the approve and dismiss decisions on each card, the
      workspace's spend threshold and default grants, and the eight verbs.
    name: workspace-actions
  - description: >-
      The Getting started checklist: a workspace's progress through the six
      steps from its first people search to its first launched sequence.
    name: onboarding
  - description: Senders, connected mailboxes, tags, and the Google connect flow.
    name: senders
  - description: The workspace do-not-contact list, enforced before every send.
    name: suppression
  - description: >-
      The workspace's recontact rule: how long before anyone hears from us
      again.
    name: contact_cooldown
  - description: 'Sequence authoring: the graph, the table-backed audience, previews.'
    name: sequences
  - description: >-
      The outbound agent behind a sequence: the voice it writes in, its
      per-message prompts, what it wrote and what people told it.
    name: outbound-agents
  - description: >-
      The LinkedIn channel: connecting an account to a sender, its safety limits
      and history, and the protocol the browser extension speaks.
    name: linkedin
  - description: >-
      The approval queue: everything waiting on a person across every sender and
      channel, and the workspace's manual or automatic modes per channel.
    name: outreach
  - description: 'The unified outreach inbox: threads, replies, labels, events.'
    name: inbox
  - description: 'The AI reply layer: workspace settings, drafts, and approval.'
    name: inbox-ai
  - description: Notification rules, per-user preferences, and the Slack connection.
    name: notifications
  - description: Endpoints for seeing all available integration types.
    name: integration-types
  - description: Endpoints for listing, checking and deleting integrations.
    name: integrations
  - description: >-
      Create, preview and update an integration of any type: the body's
      integration_type picks the config and credentials it takes.
    name: integration-specific
  - description: Endpoints for the generic OAuth install/claim app-listings engine.
    name: app-listings
  - description: Endpoints for creating and managing API keys.
    name: apikey
  - description: >-
      AI apps connected to the workspace: Claude, ChatGPT, Claude Code or any
      other MCP client a person signed in to Oneprofile's MCP server with.
    name: ai_apps
  - description: Endpoints for managing billing and subscription information.
    name: billing
  - description: >-
      Accounts: every company the workspace's tables name, with the people at
      it, its key facts, its tables, its org chart and what went to its people;
      the tables that feed it (Sources) and the merges a person made.
    name: accounts
  - description: Endpoints for creating and managing tables.
    name: tables
  - description: Endpoints for table columns, formula previews, and on-demand column runs.
    name: table-columns
  - description: Endpoints for table rows and manual cell edits.
    name: table-rows
  - description: Endpoints for observing and cancelling table recompute runs.
    name: table-runs
  - description: >-
      Endpoints for org-shared per-column display preferences: hidden, pinned,
      width, and colour tint.
    name: table-ui-prefs
  - description: >-
      Endpoints for the org-shared names given to the column tint palette: what
      this organisation calls each colour. Org-level, not per-table.
    name: table-column-color-labels
  - description: >-
      Endpoints for the enrichment action catalog, model list, presets, draft
      generation, and saved agents.
    name: table-enrichments
  - description: >-
      Endpoints for an agent's Preview: example rows run one at a time, and a
      Looks good on each. Needs work lives under agent-learnings.
    name: agent-training
  - description: >-
      An agent's learnings, the one-line rules it follows on every output, and
      the thumbs down that teaches them: give one with what was wrong, list the
      ones on a subject, Undo one, and price the redo it would run.
    name: agent-learnings
  - description: >-
      The durable audit trail of a table's enrichment actions: configured,
      edited, run, cancelled, and settled cost.
    name: table-enrichment-audit-logs
  - description: Endpoints for saving and applying column templates.
    name: table-templates
  - description: Server-sent change feed for a table's grid.
    name: table-events
  - description: 'Endpoints for org-shared saved table views: sort, filters, hidden columns.'
    name: table-views
  - description: >-
      Endpoints for PER-USER table preferences: favourites and recently opened.
      Unlike the rest of the table surface these are personal, so two members of
      one organisation legitimately see different answers.
    name: table-user-prefs
  - description: >-
      Endpoints for building a table from an uploaded CSV: upload and preview
      the inferred columns, commit the reviewed mapping, then poll the row load.
    name: table-imports
  - description: Endpoint for downloading a table's rows as CSV.
    name: table-export
  - description: >-
      Endpoints for the integration a table imports from: attach and preview it,
      promote imported fields into columns, and run the import on demand.
    name: table-sources
  - description: >-
      Endpoints for a table's recurring import cadence: set it, pause it, and
      read the next fire times.
    name: table-schedules
  - description: >-
      Endpoints for pushing a table's rows out to a connected integration: list
      writable destinations, derive their write capabilities, and map export
      columns.
    name: table-writeback
  - description: >-
      Endpoints backing a lookup column's setup: the connections whose records a
      column could read, and the identity fields one record type can be looked
      up by.
    name: table-integration-lookup
  - description: >-
      Endpoints for sourcing leads from the lead database: count and preview
      matches, land them in a table, and keep saved searches. Alongside people
      and company searches, leads can be sourced from buying signals (what a
      company or person just did), with a catalogue endpoint behind the picker
      that builds them.
    name: find-leads
  - description: >-
      Endpoints for discovering a domain's subdomains from public certificate
      logs and landing the results in a table.
    name: find-subdomains
  - description: Endpoints for the credit balance meter and usage reporting.
    name: credits
  - description: >-
      Endpoints for the workspace referral program: the shareable link, the
      friends who joined through it, and claiming a code after signup.
    name: referral
  - description: >-
      Endpoints for the affiliate program's own dashboard: enrolling and
      claiming a code, the summary, stats and activity feed, the commission
      ledger, and identity verification and payouts.
    name: affiliate
  - description: >-
      Endpoints for recording where a new workspace came from: the marketing
      page or campaign its signup link carried, sent once after signup.
    name: attribution
  - description: >-
      Endpoints for the design partner program's customer surface: whether this
      workspace is a design partner, the badges its feedback has earned, and
      sending and reading that feedback.
    name: design-partner
  - description: >-
      Endpoints for the org-level AI business context (company description,
      ideal customer profile, buyer personas, interest signals and social
      proof), plus domain-based generation and the reference documents whose
      summaries ride alongside those fields.
    name: ai-context
  - description: >-
      Endpoints for the signed-in user's Google Drive connection: starting and
      finishing the OAuth grant, checking or dropping it, and minting the
      short-lived token the Google Picker needs.
    name: google-drive
paths:
  /outreach-tasks/{task_id}/complete/:
    post:
      tags:
        - outreach
      summary: Mark a Needs human task done
      description: >-
        Say a person handled what a Browser use run could not (a task whose
        `channel` is `browser`). It leaves the Open tab and changes nothing
        about the contact, who already went on down the Needs human arm. 409
        when it is already done or was withdrawn with its sequence; 422 for any
        other task, which is approved or rejected instead.
      operationId: complete_outreach_task
      parameters:
        - in: path
          name: task_id
          required: true
          schema:
            format: uuid
            title: Task Id
            type: string
        - description: >-
            Answer what the decision would do, exactly as the real call answers
            it, and change nothing.
          in: query
          name: dry_run
          required: false
          schema:
            default: false
            description: >-
              Answer what the decision would do, exactly as the real call
              answers it, and change nothing.
            title: Dry Run
            type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OutreachTaskReadSchema'
          description: Successful Response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedResponse'
          description: Unauthorized
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
          description: Task not found.
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
          description: The task is no longer in a state this decision applies to.
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableEntityResponse'
          description: The task is not a Needs human task.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Internal server error.
        '502':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Bad gateway error.
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Service unavailable.
      security:
        - APIKeyHeader: []
        - HTTPBearer: []
components:
  schemas:
    OutreachTaskReadSchema:
      description: >-
        One row of the approval queue, every name the page shows resolved
        server-side.


        The task table stores ids; the page shows names. The sequence, the step,

        the sender and the deciding person are all resolved here rather than by

        the client, so no raw actor id ever crosses the wire and a sequence or

        sender since deleted reads as a blank rather than a broken lookup.
      properties:
        approved_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Approved At
        approved_by_display_name:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Who approved it (who marked a Needs human task done), as a name.
            Null when nobody has, or the person could not be resolved.
          title: Approved By Display Name
        ask_reason:
          anyOf:
            - $ref: '#/components/schemas/AskReason'
            - type: 'null'
          description: >-
            Why this message or step is waiting for a person instead of running
            on its own. It stays on the task after it is decided, so the history
            still says why it was asked. Null when no reason was recorded.


            About the message: `low_confidence` the agent did not rate it high;
            `insufficient_data` the agent knew too little about the contact to
            write something only they could receive. Only older tasks carry
            `findings` (a check found a problem in it, such as a placeholder
            that never filled in) or `policy` (it broke one of the agent's
            content rules): checks no longer hold a message.


            About the settings: `always_ask` the sender has a person approve
            every email, or every LinkedIn step; `sequence_manual` the sequence
            asks for approval of every email or LinkedIn step;
            `step_requires_approval` this step asks for approval;
            `sender_switched_to_manual` the LinkedIn step was on its way
            unattended when its sender switched to asking first, so it waits for
            a person again.


            About sending limits: `daily_cap` the mailbox has reached its daily
            limit; `consecutive_cap` the agent sent the last reply and nobody
            has written since; `thread_cap` the conversation has had as many
            unattended replies as it may; `hourly_cap` the mailbox has reached
            its hourly reply limit; `org_daily_cap` the workspace has reached
            its daily reply limit.


            About the conversation: `stale_inbound` a newer message arrived, or
            the one being answered is too old; `unverified_sender` the reply
            could not be confirmed as coming from the contact;
            `different_sender` someone other than the contact wrote it;
            `authentication` it failed email authentication or was marked as
            spam; `label` the reply is not one the agent answers on its own;
            `suppressed` the contact is on the do-not-contact list;
            `sequence_gone` the sequence or the agent's message no longer
            exists; `linkedin_only` the contact is known only by LinkedIn, so no
            unsubscribe could be honoured.


            About the other side: `bot_question` the contact asked whether they
            are talking to a bot or an AI; `question` the contact asked
            something a person should answer; `automated_counterparty` the other
            side appears to be an automated system; `language` the message is
            not in the expected language.


            `kill_switch` unattended sending is paused for the workspace or the
            platform.
        body:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The rendered message as it will send: an email body, a note, a
            LinkedIn message.
          title: Body
        browser_has_replay:
          anyOf:
            - type: boolean
            - type: 'null'
          description: >-
            On a Needs human task: whether its Browser use run opened a browser,
            so a recording may be watched (true), or never opened one and has
            nothing to watch (false). Null on every other task.
          title: Browser Has Replay
        browser_run_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            On a Needs human task: the Browser use run it is about. Its replay
            is GET
            /sequences/{sequence_id}/browser-runs/{browser_run_id}/replay/. Null
            on every other task.
          title: Browser Run Id
        channel:
          $ref: '#/components/schemas/TaskChannel'
          description: >-
            `email` or `linkedin` for outreach a person approves; `browser` for
            a Needs human task: a Browser use run that needed a person. Its
            contact already went on down the Needs human arm, so it is never
            approved or rejected, only marked done (POST
            /outreach-tasks/{id}/complete/), which changes nothing about the
            contact.
        confidence:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            How sure the agent was that its message could go out unedited:
            `high` (a person could send it unread), `medium` (worth a glance) or
            `low` (needs work). Null when no agent wrote the message.
          title: Confidence
        confidence_score:
          anyOf:
            - type: integer
            - type: 'null'
          description: >-
            The number behind `confidence`: the agent's own score for its
            message, from 0 to 100. Read from the agent's message as it stands
            now. Null when no agent wrote the message, or the agent gave no
            score.
          title: Confidence Score
        contact_company:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The contact's company, from whichever column of the audience table
            holds it ('Company', 'Company Name', 'Organization' and the like).
            Null when the table has none or leaves it blank.
          title: Contact Company
        contact_fields:
          description: >-
            Every filled column of the contact's audience row, in the table's
            order. Empty for housekeeping work and for a row since deleted.
          items:
            $ref: '#/components/schemas/OutreachTaskContactFieldSchema'
          title: Contact Fields
          type: array
        contact_identity:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The address, profile slug or number behind the label, so a row can
            show the name and still say who that is. Equal to the label where no
            name was found; null for housekeeping.
          title: Contact Identity
        contact_label:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The contact as the queue names them: a name, else an address or a
            profile URL.
          title: Contact Label
        contact_title:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The contact's job title, from whichever column of the audience table
            holds it ('Job Title', 'Title', 'Position' and the like). Null when
            the table has none or leaves it blank.
          title: Contact Title
        created_at:
          format: date-time
          title: Created At
          type: string
        due_at:
          description: When the channel would run it if nobody were in the way.
          format: date-time
          title: Due At
          type: string
        editable:
          description: >-
            Whether the queue may rewrite the message before approving: pending,
            and a kind that carries text.
          title: Editable
          type: boolean
        enrolment_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Enrolment Id
        flagged:
          description: >-
            Whether a check found a problem in the agent's message (any finding
            at warning strength), whatever `ask_reason` says: a task held for a
            setting can still carry a message with a placeholder that never
            filled in. False when no agent wrote the message.
          title: Flagged
          type: boolean
        id:
          format: uuid
          title: Id
          type: string
        kind:
          description: >-
            The LinkedIn action kind slug, `email`, or `needs_human` on a
            `browser` task.
          title: Kind
          type: string
        linkedin_action_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Linkedin Action Id
        note:
          anyOf:
            - type: string
            - type: 'null'
          description: 'What the person wrote when settling it: why they rejected it.'
          title: Note
        outbound_message_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The message the Outbound Agent wrote for this task. Null when a
            person wrote the words, and on a LinkedIn step that carries no
            message.
          title: Outbound Message Id
        outcome:
          anyOf:
            - type: string
            - type: 'null'
          description: 'How it ended: the channel''s own terminal word.'
          title: Outcome
        progress:
          anyOf:
            - $ref: '#/components/schemas/OutreachTaskProgressReadSchema'
            - type: 'null'
          description: >-
            Where the work stands once the queue has let it go, read from the
            channel: set on approved, finished and cancelled tasks, null on a
            task still waiting on a person and on one a person rejected.
        proposed_learning_changes:
          default: 0
          description: >-
            How many learnings approving the card saves: the adds, rewrites and
            removes the waiting Needs work proposes (a session can make
            several). 0 when none waits, or when its learner could not work out
            what to learn.
          title: Proposed Learning Changes
          type: integer
        proposed_learning_event_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          description: >-
            The feedback session waiting on this task (its Unfinished feedback),
            from a note or from a person's edit of its words: a person's
            approval saves it. Read it with GET /agent-learnings/thumbs-downs/
            (`subject_key` `task:<id>`). Null when none waits.
          title: Proposed Learning Event Id
        proposed_learning_redo_state:
          anyOf:
            - $ref: '#/components/schemas/RedoState'
            - type: 'null'
          description: >-
            How the rewrite that waiting learning asked for stands: `started`
            while the card is written again, `written` once its new words are
            in, `refused` when the rewrite didn't go through (or never started),
            so the learning waits for Retry or Discard and approving the card
            saves nothing with it. Null when no learning waits.
        reasoning:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The agent's reason for its `confidence`, given after it wrote the
            message: what the message rests on and what it was unsure about.
            Null when no agent wrote the message. On a Needs human task: why the
            Browser use run needed a person, in the run's words.
          title: Reasoning
        record_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Record Id
        rejected_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Rejected At
        rejected_by_display_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Rejected By Display Name
        reply_subject:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            For an email that replies in the contact's existing thread, the
            subject it will go out with, such as 'Re: Quick question'. Null for
            a first email, which carries its own `subject`, and for anything
            that is not an email.
          title: Reply Subject
        resolved_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Resolved At
        sender_browser_online:
          anyOf:
            - type: boolean
            - type: 'null'
          description: >-
            For a LinkedIn task still waiting on a person: whether a browser is
            checked in for its sender right now, so approving it would run it
            soon. False means an approved step waits until a browser is open.
            Null for every other task.
          title: Sender Browser Online
        sender_profile_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Sender Profile Id
        sender_profile_name:
          anyOf:
            - type: string
            - type: 'null'
          description: Null when nobody in particular sends it, or the sender was deleted.
          title: Sender Profile Name
        sequence_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Sequence Id
        sequence_name:
          anyOf:
            - type: string
            - type: 'null'
          description: Null for housekeeping work, or for a sequence since deleted.
          title: Sequence Name
        sequence_paused:
          default: false
          description: >-
            Its sequence is paused right now: approving the task records the
            approval, and the step waits for Resume sequence before it runs, on
            either channel.
          title: Sequence Paused
          type: boolean
        status:
          $ref: '#/components/schemas/TaskStatus'
        step_id:
          anyOf:
            - format: uuid
              type: string
            - type: 'null'
          title: Step Id
        step_name:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The step as the builder names it; null when the step no longer
            exists.
          title: Step Name
        step_position:
          anyOf:
            - type: integer
            - type: 'null'
          description: The step's customer-visible ordinal, zero-based; null with the name.
          title: Step Position
        subject:
          anyOf:
            - type: string
            - type: 'null'
          title: Subject
        updated_at:
          format: date-time
          title: Updated At
          type: string
        words_edited:
          description: >-
            Whether a person changed the words the card shows (an edit saved
            before approving). Needs work is refused on such a card: the edit
            proposes its own learning instead. False again once the agent writes
            the card's words anew.
          title: Words Edited
          type: boolean
      required:
        - id
        - channel
        - kind
        - status
        - sequence_id
        - sequence_name
        - step_id
        - step_name
        - step_position
        - enrolment_id
        - record_id
        - sender_profile_id
        - sender_profile_name
        - contact_label
        - subject
        - body
        - due_at
        - created_at
        - updated_at
        - approved_at
        - approved_by_display_name
        - rejected_at
        - rejected_by_display_name
        - resolved_at
        - outcome
        - note
        - linkedin_action_id
        - editable
        - outbound_message_id
        - words_edited
        - confidence
        - confidence_score
        - flagged
        - reasoning
        - ask_reason
      title: OutreachTaskReadSchema
      type: object
    UnauthorizedResponse:
      properties:
        detail:
          description: The detail of why the request is unauthorized.
          title: Detail
          type: string
      required:
        - detail
      title: UnauthorizedResponse
      type: object
    ForbiddenResponse:
      properties:
        detail:
          description: The detail of why the request is forbidden.
          title: Detail
          type: string
      required:
        - detail
      title: ForbiddenResponse
      type: object
    NotFoundResponse:
      properties:
        detail:
          description: The detail of why the resource was not found.
          title: Detail
          type: string
      required:
        - detail
      title: NotFoundResponse
      type: object
    UnprocessableEntityResponse:
      properties:
        detail:
          description: >-
            The detail of the error. This is the error message to show to the
            user. You should also use the issues field to show more detailed
            error messages per field. Use this field for a single liner error
            message.
          title: Detail
          type: string
        issues:
          description: >-
            The issues that caused the error. There can be multiple issues. Each
            issue is a user-facing error message.
          items:
            $ref: '#/components/schemas/UnprocessableEntityIssue'
          title: Issues
          type: array
      required:
        - detail
        - issues
      title: UnprocessableEntityResponse
      type: object
    ServerErrorResponse:
      properties:
        detail:
          description: The detail of why the server returned an error.
          title: Detail
          type: string
      required:
        - detail
      title: ServerErrorResponse
      type: object
    AskReason:
      description: >-
        Why a message that could have sent unattended was put in front of a
        person.


        One vocabulary for every gate between an agent writing a message and the

        message leaving: what the agent itself said about the draft

        (``LOW_CONFIDENCE``, ``FINDINGS``, ``INSUFFICIENT_DATA``, ``POLICY``),
        what

        the sender or the cadence asked for (``ALWAYS_ASK``,
        ``SEQUENCE_MANUAL``,

        ``STEP_REQUIRES_APPROVAL``), what the pacing rules refused

        (``DAILY_CAP``, ``CONSECUTIVE_CAP``, ``THREAD_CAP``, ``HOURLY_CAP``,

        ``ORG_DAILY_CAP``), what the mailbox or the thread made unsafe

        (``UNVERIFIED_SENDER``, ``DIFFERENT_SENDER``, ``LABEL``, ``QUESTION``,

        ``STALE_INBOUND``, ``SEQUENCE_GONE``), and what the counterparty turned
        out to be

        (``BOT_QUESTION``, ``AUTOMATED_COUNTERPARTY``, ``AUTHENTICATION``,

        ``LANGUAGE``, ``LINKEDIN_ONLY``). ``KILL_SWITCH`` is the platform switch

        that stops unattended sending outright, and ``SEND_INTERRUPTED`` an

        unattended reply whose send never got as far as a provider.

        ``SENDER_SWITCHED_TO_MANUAL`` is a LinkedIn step queued unasked that
        went

        back to a person because its sender switched to manual before it ran.


        Stored on the task so the queue can say why each row is there, and so

        "why did nothing send" is answerable by counting rows rather than by

        reading logs.
      enum:
        - low_confidence
        - findings
        - insufficient_data
        - policy
        - always_ask
        - sequence_manual
        - step_requires_approval
        - daily_cap
        - unverified_sender
        - suppressed
        - different_sender
        - label
        - question
        - consecutive_cap
        - thread_cap
        - hourly_cap
        - org_daily_cap
        - stale_inbound
        - sequence_gone
        - bot_question
        - automated_counterparty
        - kill_switch
        - authentication
        - language
        - linkedin_only
        - send_interrupted
        - sender_switched_to_manual
      title: AskReason
      type: string
    TaskChannel:
      description: >-
        Which channel performs the task once it is allowed to run.


        ``BROWSER`` is the one channel that performs nothing: a Browser use run

        that settled on Needs human leaves a task for a person to pick up what
        the

        agent could not do (BU-08). Its contact already went on down the Needs

        human arm, so the task is a to-do with one verb, done, and no approval
        or

        rejection reaches it.
      enum:
        - linkedin
        - email
        - browser
      title: TaskChannel
      type: string
    OutreachTaskContactFieldSchema:
      description: One filled column of the contact's audience row.
      properties:
        name:
          description: The column's header, as the table names it.
          title: Name
          type: string
        value:
          description: What the row holds there, as text; long values are cut.
          title: Value
          type: string
      required:
        - name
        - value
      title: OutreachTaskContactFieldSchema
      type: object
    OutreachTaskProgressReadSchema:
      description: >-
        Where an approved, finished or failed task's work stands, read from its
        channel.
      properties:
        error_code:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Why a failed LinkedIn step failed, as the channel's error code; null
            otherwise.
          title: Error Code
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Why it failed, as a sentence from the channel or the send engine;
            null otherwise.
          title: Error Message
        hold:
          anyOf:
            - $ref: '#/components/schemas/StepHold'
            - type: 'null'
          description: >-
            For a `paused` task, what holds it: `sequence_paused` its sequence
            is paused, `contact_paused` its contact is. Null otherwise.
        hold_reason:
          anyOf:
            - $ref: '#/components/schemas/HoldReason'
            - type: 'null'
          description: >-
            Why a held email waits: `window` the sequence's sending window is
            closed, `daily_cap` its mailboxes are out of today's capacity,
            `pacing` the mailbox's next slot is later, `no_mailbox` no mailbox
            is connected, `agent_writing` / `agent_queued` / `agent_unavailable`
            / `no_message` its words are not ready (`agent_queued`: in line to
            be written, behind the messages the sequence already keeps written
            ahead), `confirming_send` Gmail never confirmed the last send and it
            is being checked before anything is sent again; and why a held
            LinkedIn step waits: `no_linkedin_account` no sender on the sequence
            has LinkedIn connected. Null otherwise.
        linkedin_queue:
          anyOf:
            - $ref: '#/components/schemas/LinkedInQueueState'
            - type: 'null'
          description: >-
            For a queued or running LinkedIn step, where it stands in its
            account's line: `queued` (with `starts_at` and `steps_ahead`),
            `running`, `outside_window` (its sequence's sending hours are shut
            in the sender's timezone; `starts_at` is when it is expected to
            start once they open), `daily_limit` or `weekly_limit` (with
            `resets_at`), `kind_disabled` (this kind's limit is 0),
            `browser_offline` (no browser checked in for the sender),
            `verify_account` (LinkedIn is asking the member to verify the
            account) or `disconnected` (the account is not connected). Null
            otherwise.
        may_have_sent:
          description: >-
            A failed LinkedIn message or InMail that may have reached the person
            anyway (the browser timed out, lost its tab or went silent
            mid-step): a retry could send it twice, so confirm first.
          title: May Have Sent
          type: boolean
        pause_reason:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            For a task its paused sequence holds, why the sequence paused, as
            the sequence's own `pause_reason` (`manual`, `credits`,
            `spending_limit`, `bounces`, `mailboxes`, `linkedin`). Null
            otherwise.
          title: Pause Reason
        resets_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            The reset that frees a LinkedIn step a daily or weekly limit holds,
            midnight in the sender's timezone; null otherwise.
          title: Resets At
        retryable:
          description: >-
            The contact is stopped as failed at this moment, so a retry of their
            journey (the `retry` journey action on their enrolment) runs the
            step again.
          title: Retryable
          type: boolean
        starts_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            When it is expected to start: a LinkedIn step's forecast, or when a
            held email's wait ends. An estimate; null when no time can honestly
            be named.
          title: Starts At
        state:
          $ref: '#/components/schemas/TaskProgressState'
          description: >-
            Where the work stands. `queued` it is in its sender's LinkedIn line
            (see `linkedin_queue`), or approved and about to join it; `running`
            a browser is doing it now; `sending` an approved email is going out
            now; `held` an approved email, or an approved LinkedIn step not yet
            in its sender's line, waits (see `hold_reason` and `starts_at`);
            `paused` an approved step on either channel waits for its paused
            sequence or paused contact to be resumed (see `hold` and
            `pause_reason`) and is in no line until then; `sent` it happened;
            `skipped` it did not apply, or was passed over in the extension;
            `failed` it could not be done (see `error_code`, `retryable`);
            `rejected` a person refused it; `stopped` the contact was stopped
            under it, or it was replaced.
        steps_ahead:
          anyOf:
            - type: integer
            - type: 'null'
          description: >-
            How many of the sender's LinkedIn steps run before this one; null
            otherwise.
          title: Steps Ahead
      required:
        - state
        - linkedin_queue
        - starts_at
        - steps_ahead
        - resets_at
        - hold_reason
        - error_code
        - error_message
        - retryable
        - may_have_sent
      title: OutreachTaskProgressReadSchema
      type: object
    RedoState:
      description: How the redo a thumbs down asked for went.
      enum:
        - none
        - started
        - written
        - refused
      title: RedoState
      type: string
    TaskStatus:
      description: >-
        Where one task stands.


        PENDING is waiting on a person. SCHEDULED is approved, or never needed

        approval, and is waiting on the channel to execute it: the browser to
        run

        the LinkedIn step, the engine to send the email. The task is where a

        LinkedIn step's approval lives: while it is PENDING no step exists, and

        the step is queued only once it is SCHEDULED. A LinkedIn task nobody is

        asked about (a sender on automatic, a housekeeping read, a Try click) is

        BORN scheduled, pointing at the step it queued. Who approved it is a
        stamp

        on the row, not a status of its own.


        DONE, REJECTED and CANCELLED are terminal. DONE is the channel executed

        it; REJECTED is a person refused it; CANCELLED is the channel gave up on

        it (failed, skipped, expired), or the contact was stopped underneath it.
      enum:
        - pending
        - scheduled
        - done
        - rejected
        - cancelled
      title: TaskStatus
      type: string
    UnprocessableEntityIssue:
      properties:
        input:
          anyOf:
            - type: string
            - type: integer
            - type: number
            - type: boolean
            - items: {}
              type: array
            - additionalProperties: true
              type: object
          description: The user's input that caused the error.
          title: Input
        loc:
          description: >-
            The location of the error. Always contains 1 or 2 elements. The
            first element is the type of location (e.g. 'body', 'query', 'path',
            'header'). The second element is the name of the field that caused
            the error. If the error is not related to a specific field, the
            second element is not present.
          items:
            type: string
          title: Loc
          type: array
        msg:
          description: The message of the error. The error message to show to the user.
          title: Msg
          type: string
        type:
          description: >-
            The type of the error. Useful for frontend code to handle different
            types of errors.
          title: Type
          type: string
      required:
        - loc
        - msg
        - type
        - input
      title: UnprocessableEntityIssue
      type: object
    StepHold:
      description: >-
        Why a sequence's step may not run now, whatever its approval says.


        A paused sequence or a paused contact sends nothing on either channel;
        an

        approval given meanwhile waits for **Resume sequence** (or the contact's

        own resume).
      enum:
        - sequence_paused
        - contact_paused
      title: StepHold
      type: string
    HoldReason:
      description: >-
        Why the send path pushed a live contact's ``due_at`` out instead of
        sending.


        Stored beside the date it explains so the Contacts tab can say
        "Approved,

        window opens in 3 hours" rather than a bare date. Only ever meaningful
        on

        an ACTIVE row whose date is still ahead; any other write clears it.
      enum:
        - window
        - approved_window
        - daily_cap
        - no_mailbox
        - pacing
        - agent_unavailable
        - no_message
        - agent_writing
        - agent_queued
        - approval_queued
        - mailbox_waiting
        - no_linkedin_account
        - confirming_send
        - email_check
        - out_of_office
        - browser_queued
        - browser_running
        - browser_unavailable
      title: HoldReason
      type: string
    LinkedInQueueState:
      description: >-
        Where one step stands in its account's line, for the people waiting on
        it.


        ``RUNNING`` is in a browser now. ``QUEUED`` is in line, with how many
        are

        ahead of it and when it is expected to start. The rest say why the line
        is

        not moving for it: a daily or weekly limit reached for its kind, a limit

        set to zero (``KIND_DISABLED``, which no reset lifts), no browser
        checked

        in for longer than ``offline_warning_seconds``, LinkedIn asking the
        member

        to verify the account (a checkpoint), or the account disconnected. Not

        "paused", which is already what a sequence is when a person stops it.


        The last two were one "account blocked" state. They are two because the
        fix

        is different and the words have to say which: a checkpoint is cleared in

        the connected Chrome, a disconnect by connecting again.


        ``OUTSIDE_WINDOW`` is a step whose sequence's sending hours are shut now
        in

        its sender's timezone (2026-10-01); it outranks every state but the

        account's own, since nothing else moves it before the hours open.


        ``CHECKING_REPLIES`` is a LinkedIn message in line that waits for its

        sender's inbox to be read first (2026-10-05): no time is named, since it

        goes once a check reads the whole inbox.
      enum:
        - running
        - queued
        - checking_replies
        - outside_window
        - daily_limit
        - weekly_limit
        - kind_disabled
        - browser_offline
        - verify_account
        - disconnected
      title: LinkedInQueueState
      type: string
    TaskProgressState:
      description: >-
        Where a task's work stands once the queue has let it go, for the Tasks
        page's Detail column.


        Finer than ``TaskStatus``, and read from the channel rather than the
        row:

        a LinkedIn step's own phase and outcome first (the task's status can lag

        it), the contact's enrolment for an email.


        ``QUEUED`` in its sender's line, with a forecast, or approved and about
        to

        join it; ``RUNNING`` in a browser now; ``SENDING`` an approved email the

        engine is sending; ``HELD`` an approved email waiting for the sending

        window, pacing or a daily cap, or an approved LinkedIn step waiting for

        something its contact names (a connected account); ``PAUSED`` an
        approved

        step on either channel that waits for its paused sequence or paused

        contact to be resumed, in no line until then. ``WRITING`` a task Write

        again withdrew while the agent writes its contact's words for that step

        again, or the engine is about to ask with them: the same task comes back

        waiting on a person. The rest are how it ended: ``SENT``, ``SKIPPED``
        (not

        applicable, or passed over in the extension), ``FAILED``, ``REJECTED``
        and

        ``STOPPED`` (the contact was stopped under it, or it was replaced and
        the

        rewrite ended without asking again).
      enum:
        - queued
        - running
        - sent
        - skipped
        - failed
        - stopped
        - rejected
        - sending
        - held
        - paused
        - writing
      title: TaskProgressState
      type: string
  securitySchemes:
    APIKeyHeader:
      in: header
      name: X-API-Key
      type: apiKey
    HTTPBearer:
      scheme: bearer
      type: http

````

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