---
title: "List the approval queue"
method: GET
path: "/outreach-tasks/"
tags: ["outreach"]
---

# List the approval queue

`GET /outreach-tasks/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/outreach-tasks/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

One list across every channel: LinkedIn steps and emails, each waiting on a person, waiting on its channel, or settled. Newest first by default, the order the Tasks page opens in; order by `created_at` or `contact_label`, which sorts by the contact as the Tasks page's Contact column shows them (a LinkedIn profile address by its slug, letters in any case together, a task about nobody as the empty name). Pending by default; pass `status` (repeatable) for the other tabs, and narrow by channel, task kind, sender, sequence, how it ended (`outcome`; the failed steps are `status=cancelled&outcome=failed`), why it waits for a person (`ask_reason`), words in the contact or the subject (`search`) or how long it has been waiting. Our own LinkedIn reads of the account (the inbox, sent invitations, new connections, one conversation) are left out unless `background_checks` asks for them. `GET /outreach-tasks/length/` counts the same filters. Every name the row shows (the sequence, the step, the sender, who decided) is resolved here, and every approved, finished or cancelled task says where its work stands (`progress`: queued with its expected start, running, held by the sending window, sent, failed and whether it can be retried).

## Query parameters

- `filters` ListOutreachTasksFilterParamsSchema, required: Query parameters narrowing the queue. ``status`` defaults to pending because that is the queue: what is waiting on a person. The other tabs pass their own statuses, several at once for a history view.
  - `ask_reason` AskReason[], nullable: Only tasks held for a person for one of these reasons (repeatable): the Tasks page's Held because. Omit for every reason.
  - `background_checks` 'hide' | 'include' | 'only': Whether a reading of Activity lists our own LinkedIn reads of the sender's account. The reads (``BACKGROUND_CHECK_KINDS``: the inbox, the sent invitations, the newest connections, one conversation) act on nobody, so every Activity page hides them unless a person turns them on (Utku, 2026-10-19: behind a filter, so a customer worried about their LinkedIn account can see every time we touched it). ``HIDE`` leaves them out, ``INCLUDE`` lists them with everything else, ``ONLY`` lists them alone.
  - `channel` TaskChannel[], nullable: Only these channels; omit for every channel.
  - `enrolment_id` string[], nullable: Only the tasks of these contacts, by their enrolment in a sequence; omit for everyone.
  - `kind` string[], nullable: Only these kinds: a LinkedIn action slug (`profile_view`, `connection_request`, …) or `email`. Omit for every kind.
  - `outcome` string[], nullable: Only tasks that ended with one of these words (repeatable): `failed`, `skipped`, `stopped`, `succeeded` and the like. The tasks that failed are `status=cancelled` with `outcome=failed`. Omit for however they ended.
  - `search` string, nullable: Words that must each appear in the contact's name, address or LinkedIn profile, or in the subject.
  - `sender_profile_id` string[], nullable: Only these senders; omit for everyone.
  - `sequence_id` string[], nullable: Only these sequences; omit for all of them.
  - `status` TaskStatus[]: Only these statuses; repeat the parameter for several. Defaults to pending.
  - `waiting_since_before` string, date-time, nullable: Only tasks that entered the queue before this instant, which is 'waiting longer than'. Read off when the task was created, not when its channel would run it. Omit for however long they have been here.
- `limit` integer: The number of items to return.
- `order_by` 'created_at' | 'contact_label'
- `order_direction` 'asc' | 'desc'
- `cursor` string, nullable: Set the cursor to the next or previous page. You can get the cursor from the previous page's response.

## Response `200`

Successful Response

- PaginatedResponseOutreachTaskReadSchema
  - `data` OutreachTaskReadSchema[]: The list of ResponseItems.
    - `approved_at` string, date-time, nullable, required
    - `approved_by_display_name` string, nullable, required: Who approved it, as a name. Null when nobody has, or the person could not be resolved.
    - `ask_reason` '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', required: 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.
    - `body` string, nullable, required: The rendered message as it will send: an email body, a note, a LinkedIn message.
    - `channel` 'linkedin' | 'email', required: Which channel performs the task once it is allowed to run.
    - `confidence` string, nullable, required: 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.
    - `confidence_score` integer, nullable, required: 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.
    - `contact_company` string, nullable: 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.
    - `contact_fields` OutreachTaskContactFieldSchema[]: Every filled column of the contact's audience row, in the table's order. Empty for housekeeping work and for a row since deleted.
      - `name` string, required: The column's header, as the table names it.
      - `value` string, required: What the row holds there, as text; long values are cut.
    - `contact_identity` string, nullable: 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.
    - `contact_label` string, nullable, required: The contact as the queue names them: a name, else an address or a profile URL.
    - `contact_title` string, nullable: 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.
    - `created_at` string, date-time, required
    - `due_at` string, date-time, required: When the channel would run it if nobody were in the way.
    - `editable` boolean, required: Whether the queue may rewrite the message before approving: pending, and a kind that carries text.
    - `enrolment_id` string, uuid, nullable, required
    - `flagged` boolean, required: 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.
    - `id` string, uuid, required
    - `kind` string, required: The LinkedIn action kind slug or `email`.
    - `linkedin_action_id` string, uuid, nullable, required
    - `note` string, nullable, required: What the person wrote when settling it: why they rejected it.
    - `outbound_message_id` string, uuid, nullable, required: 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.
    - `outcome` string, nullable, required: How it ended: the channel's own terminal word.
    - `progress` OutreachTaskProgressReadSchema: Where an approved, finished or failed task's work stands, read from its channel.
      - `error_code` string, nullable, required: Why a failed LinkedIn step failed, as the channel's error code; null otherwise.
      - `error_message` string, nullable, required: Why it failed, as a sentence from the channel or the send engine; null otherwise.
      - `hold` 'sequence_paused' | 'contact_paused': 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).
      - `hold_reason` 'window' | 'approved_window' | 'daily_cap' | 'no_mailbox' | 'pacing' | 'agent_unavailable' | 'no_message' | 'agent_writing' | 'agent_queued' | 'mailbox_waiting' | 'no_linkedin_account' | 'confirming_send' | 'email_check', required: 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.
      - `linkedin_queue` 'running' | 'queued' | 'checking_replies' | 'outside_window' | 'daily_limit' | 'weekly_limit' | 'kind_disabled' | 'browser_offline' | 'verify_account' | 'disconnected', required: 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.
      - `may_have_sent` boolean, required: 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.
      - `pause_reason` string, nullable: 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.
      - `resets_at` string, date-time, nullable, required: The reset that frees a LinkedIn step a daily or weekly limit holds, midnight in the sender's timezone; null otherwise.
      - `retryable` boolean, required: 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.
      - `starts_at` string, date-time, nullable, required: 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.
      - `state` 'queued' | 'running' | 'sent' | 'skipped' | 'failed' | 'stopped' | 'rejected' | 'sending' | 'held' | 'paused' | 'writing', required: 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).
      - `steps_ahead` integer, nullable, required: How many of the sender's LinkedIn steps run before this one; null otherwise.
    - `quality_score` integer, nullable, required: A separate AI review's score for the agent's message, from 0 to 100: how likely a busy person in the recipient's role is to read it to the end and reply. Null when no agent wrote the message, or when it was not reviewed.
    - `reasoning` string, nullable, required: The agent's own note on its message: what it built the message on and what it was unsure about. Null when no agent wrote the message.
    - `record_id` string, uuid, nullable, required
    - `rejected_at` string, date-time, nullable, required
    - `rejected_by_display_name` string, nullable, required
    - `reply_subject` string, nullable: 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.
    - `resolved_at` string, date-time, nullable, required
    - `sender_browser_online` boolean, nullable: 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.
    - `sender_profile_id` string, uuid, nullable, required
    - `sender_profile_name` string, nullable, required: Null when nobody in particular sends it, or the sender was deleted.
    - `sequence_id` string, uuid, nullable, required
    - `sequence_name` string, nullable, required: Null for housekeeping work, or for a sequence since deleted.
    - `sequence_paused` boolean: 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.
    - `status` 'pending' | 'scheduled' | 'done' | 'rejected' | 'cancelled', required: 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.
    - `step_id` string, uuid, nullable, required
    - `step_name` string, nullable, required: The step as the builder names it; null when the step no longer exists.
    - `step_position` integer, nullable, required: The step's customer-visible ordinal, zero-based; null with the name.
    - `subject` string, nullable, required
    - `updated_at` string, date-time, required
  - `next_page_cursor` string, nullable: The cursor to the next page. If there are no more pages, this is None.
  - `previous_page_cursor` string, nullable: The cursor to the previous page. If there are no previous pages, this is None.

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/dc5ac3c84444?raw)
