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

# Manage Outbounds

> Get, cancel, pause, or resume outbound activities for a search

# Manage Outbounds

Use these endpoints when you need to inspect or control outbound verification attempts after an order has already been created.
All six routes are scoped to a search within an order.

<Note>
  Pause and resume operations require the search to be `IN_PROGRESS`. You can list outbounds for a search in any status.
</Note>

## Shared Path Parameters

<ParamField path="orderId" type="string" required>
  Verification order ID (UUID).
</ParamField>

<ParamField path="searchId" type="string" required>
  Search ID (UUID) within the order.
</ParamField>

## Get Outbounds

Returns current actionable outbound work for the search.

<Note>
  Returns current actionable outbounds only (those in `SCHEDULED`, `PENDING`, or `PAUSED` status). Sent, delivered, failed, and
  cancelled records are excluded. Use the returned `id` as the `outboundId` when pausing or resuming a single outbound.
</Note>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X GET "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/outbounds" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Accept: application/json"
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(`https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/outbounds`, {
    method: 'GET',
    headers: {
      Authorization: 'Bearer YOUR_JWT_TOKEN',
      Accept: 'application/json',
    },
  })

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.get(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/outbounds",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Accept": "application/json",
      },
  )

  result = response.json()
  ```
</CodeGroup>

### Response

<ResponseField name="success" type="boolean" />

<ResponseField name="searchId" type="string" />

<ResponseField name="externalSearchId" type="string | null" />

<ResponseField name="outbounds" type="array">
  Current actionable outbound activities and contact attempts for the search.
</ResponseField>

### Outbound Item Fields

<ResponseField name="id" type="string">
  Outbound identifier. Activity records use their UUID. Contact attempts without a matching activity use `attempt-<contactAttemptUuid>`.
</ResponseField>

<ResponseField name="contactId" type="string | null">
  Contact associated with the outbound, when available.
</ResponseField>

<ResponseField name="contactName" type="string | null">
  Contact name associated with the outbound, when available.
</ResponseField>

<ResponseField name="entityName" type="string | null">
  Entity being contacted.
</ResponseField>

<ResponseField name="channel" type="string">
  Outbound channel, such as `EMAIL`, `FAX`, `VOICE`, or a system method.
</ResponseField>

<ResponseField name="channelValue" type="string">
  Destination for the outbound, such as an email address or fax number.
</ResponseField>

<ResponseField name="description" type="string | null">
  Human-readable activity description.
</ResponseField>

<ResponseField name="metadata" type="object">
  Additional status, scheduling, cancellation, or system metadata.
</ResponseField>

<ResponseField name="createdAt" type="string">
  Activity or attempt creation timestamp.
</ResponseField>

<ResponseField name="scheduledAt" type="string | null">
  Scheduled outbound time when the outbound is pending, scheduled, or paused.
</ResponseField>

<ResponseField name="sentAt" type="string | null">
  Send timestamp when the outbound has been sent.
</ResponseField>

<ResponseField name="status" type="string">
  Current actionable status: `SCHEDULED`, `PENDING`, or `PAUSED`.
</ResponseField>

<ResponseField name="attemptNumber" type="number | null">
  Attempt number when available.
</ResponseField>

<ResponseField name="attemptNumberSearch" type="number | null">
  Attempt sequence across all outbound attempts for the search.
</ResponseField>

<ResponseField name="attemptNumberContact" type="number | null">
  Attempt sequence for this contact.
</ResponseField>

<ResponseField name="attemptNumberChannel" type="number | null">
  Attempt sequence for this channel.
</ResponseField>

<ResponseField name="isCancelled" type="boolean">
  Whether this outbound is cancelled.
</ResponseField>

<ResponseField name="cancellationReason" type="string">
  Cancellation reason when available.
</ResponseField>

<ResponseField name="failureReason" type="string">
  Failure reason when available.
</ResponseField>

### Example Response

```json theme={null}
{
  "success": true,
  "searchId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "externalSearchId": "EXT-12345",
  "outbounds": [
    {
      "id": "attempt-e8c015f6-3866-4226-827f-e8e86328ef29",
      "contactId": "996bf751-05b9-424b-8217-44de7742decd",
      "contactName": "HR Department",
      "entityName": "Acme Corporation",
      "channel": "EMAIL",
      "channelValue": "hr@acme.com",
      "description": "System outbound attempt #1",
      "metadata": {
        "source": "system",
        "outcome": "SCHEDULED"
      },
      "createdAt": "2026-06-25T21:41:16.644Z",
      "scheduledAt": "2026-06-25T21:41:16.644Z",
      "sentAt": null,
      "status": "SCHEDULED",
      "attemptNumber": 1,
      "attemptNumberSearch": 1,
      "attemptNumberContact": 1,
      "attemptNumberChannel": 1,
      "isCancelled": false
    }
  ]
}
```

## Cancel Outbounds

Permanently cancels pending outbound work without cancelling the search itself.

### Request Body

<ParamField body="contactDestination" type="string">
  Optional contact destination. When provided, only pending outbound matching this normalized destination is cancelled.
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/cancel-outbounds" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "contactDestination": "hr@acme.com"
    }'
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(
    `https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/cancel-outbounds`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_JWT_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ contactDestination: 'hr@acme.com' }),
    },
  )

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.post(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/cancel-outbounds",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Content-Type": "application/json",
      },
      json={"contactDestination": "hr@acme.com"},
  )

  result = response.json()
  ```
</CodeGroup>

### Behavior

Cancels all pending outbound work — scheduled contact attempts and matching unsent outbound records. When
`contactDestination` is provided, cancellation is scoped to pending outbound matching that normalized destination.

<Note>
  Cancellation is permanent. Resume operations do not recreate cancelled outbound. Cancelling while paused clears pause state and
  marks paused attempts as `CANCELLED`.
</Note>

## Pause Outbounds

Pauses all pending outbound work for the search.

### Request Body

<ParamField body="reason" type="string">
  Optional pause reason stored in outbound control metadata and webhook payloads.
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/pause-outbounds" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "Entity HR department closed for holiday"
    }'
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(
    `https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/pause-outbounds`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_JWT_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ reason: 'Entity HR department closed for holiday' }),
    },
  )

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.post(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/pause-outbounds",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Content-Type": "application/json",
      },
      json={"reason": "Entity HR department closed for holiday"},
  )

  result = response.json()
  ```
</CodeGroup>

### Behavior

`pause-outbounds` affects pending outbound work only. It pauses:

* `SCHEDULED` contact attempts
* `TRIGGERED_BY_SCHEDULER` contact attempts that have been claimed but not completed
* pending delayed or queued outbound jobs
* matching unsent outbound activity records, when a corresponding activity can be identified

Already sent, delivered, failed, cancelled, or superseded activity history is not changed. Calling `pause-outbounds` again while
the search is already paused is idempotent and returns a successful response with `previousOutboundStatus` set to `PAUSED`.

<Note>Repeating a pause when the search is already paused succeeds without changing state or emitting another webhook.</Note>

## Pause Outbound

Pauses one pending outbound while leaving the search-level outbound control status `ACTIVE`.

### Request Body

<ParamField body="outboundId" type="string" required>
  Outbound activity ID, contact attempt ID, or `attempt-` prefixed contact attempt ID. Use `GET .../outbounds` to discover this
  value.
</ParamField>

<ParamField body="reason" type="string">
  Optional pause reason stored in outbound control metadata and webhook payloads.
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/pause-outbound" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "outboundId": "attempt-e8c015f6-3866-4226-827f-e8e86328ef29",
      "reason": "Pause this specific outbound while contact details are reviewed"
    }'
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(
    `https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/pause-outbound`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_JWT_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        outboundId: 'attempt-e8c015f6-3866-4226-827f-e8e86328ef29',
        reason: 'Pause this specific outbound while contact details are reviewed',
      }),
    },
  )

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.post(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/pause-outbound",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "outboundId": "attempt-e8c015f6-3866-4226-827f-e8e86328ef29",
          "reason": "Pause this specific outbound while contact details are reviewed",
      },
  )

  result = response.json()
  ```
</CodeGroup>

### Behavior

`pause-outbound` affects only the matching pending outbound. The search-level outbound control status remains `ACTIVE`, so other
pending outbound attempts for the same search can continue.

The endpoint accepts an activity UUID, a contact attempt UUID, or `attempt-<contactAttemptUuid>`. Already sent, delivered, failed,
cancelled, or superseded history is not changed.

## Resume Outbounds

Restores paused outbound work to an active scheduled state.

### Request Body

<ParamField body="reason" type="string">
  Optional resume reason stored in outbound control metadata and webhook payloads.
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/resume-outbounds" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "Entity HR department reopened"
    }'
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(
    `https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/resume-outbounds`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_JWT_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ reason: 'Entity HR department reopened' }),
    },
  )

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.post(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/resume-outbounds",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Content-Type": "application/json",
      },
      json={"reason": "Entity HR department reopened"},
  )

  result = response.json()
  ```
</CodeGroup>

### Behavior

`resume-outbounds` restores paused outbound work to an active scheduled state. It resumes:

* attempts paused by `pause-outbounds`
* attempts paused individually via the single-outbound endpoint
* delayed outbound jobs captured in the pause snapshot
* matching activity metadata, with the pause marker removed and a resume marker added

Attempts whose original scheduled time is already in the past are restored with an immediate scheduled time so the scheduler can
process them on the next run. Permanently cancelled or superseded attempts are not recreated.

Calling `resume-outbounds` when there is no paused outbound state is idempotent and returns a successful response with
`previousOutboundStatus` set to `ACTIVE`.

<Note>
  Repeating a resume when no paused state exists succeeds without changing state or emitting another webhook. Permanently
  cancelled and superseded attempts are never recreated.
</Note>

## Resume Outbound

Restores one paused outbound identified by `outboundId`.

### Request Body

<ParamField body="outboundId" type="string" required>
  Outbound activity ID, contact attempt ID, or `attempt-` prefixed contact attempt ID. Use `GET .../outbounds` to discover this
  value.
</ParamField>

<ParamField body="reason" type="string">
  Optional resume reason stored in outbound control metadata and webhook payloads.
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "https://sandbox.theary.ai/background-check/v1/orders/550e8400-e29b-41d4-a716-446655440000/searches/7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111/resume-outbound" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "outboundId": "attempt-e8c015f6-3866-4226-827f-e8e86328ef29",
      "reason": "Resume this specific outbound"
    }'
  ```

  ```javascript JavaScript theme={null}
  const orderId = '550e8400-e29b-41d4-a716-446655440000'
  const searchId = '7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111'
  const response = await fetch(
    `https://sandbox.theary.ai/background-check/v1/orders/${orderId}/searches/${searchId}/resume-outbound`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_JWT_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        outboundId: 'attempt-e8c015f6-3866-4226-827f-e8e86328ef29',
        reason: 'Resume this specific outbound',
      }),
    },
  )

  const result = await response.json()
  ```

  ```python Python theme={null}
  import requests

  order_id = "550e8400-e29b-41d4-a716-446655440000"
  search_id = "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111"

  response = requests.post(
      f"https://sandbox.theary.ai/background-check/v1/orders/{order_id}/searches/{search_id}/resume-outbound",
      headers={
          "Authorization": "Bearer YOUR_JWT_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "outboundId": "attempt-e8c015f6-3866-4226-827f-e8e86328ef29",
          "reason": "Resume this specific outbound",
      },
  )

  result = response.json()
  ```
</CodeGroup>

### Behavior

`resume-outbound` restores only the paused outbound tracked for the supplied `outboundId`. If the original scheduled time is
already in the past, the attempt is restored with an immediate scheduled time so the scheduler can process it on the next run.

Calling `resume-outbound` when the supplied outbound is not paused is idempotent and returns a successful response with
`previousOutboundStatus` set to `ACTIVE`.

<Note>
  Repeating this request for an outbound that is already active succeeds without changing state or emitting another webhook.
</Note>

## Mutation Response

<ResponseField name="success" type="boolean">
  Whether the request was processed.
</ResponseField>

<ResponseField name="searchId" type="string">
  Internal search UUID.
</ResponseField>

<ResponseField name="externalSearchId" type="string">
  External search identifier when present.
</ResponseField>

<ResponseField name="outboundId" type="string">
  Single-outbound response only. The outbound identifier supplied in the request.
</ResponseField>

<ResponseField name="action" type="string">
  `PAUSE_OUTBOUND` or `RESUME_OUTBOUND`.
</ResponseField>

<ResponseField name="previousOutboundStatus" type="string">
  Previous outbound control status: `ACTIVE` or `PAUSED`.
</ResponseField>

<ResponseField name="currentOutboundStatus" type="string">
  Current outbound control status: `ACTIVE` or `PAUSED`. For single-outbound pauses, this remains `ACTIVE` because the search is
  not globally paused.
</ResponseField>

<ResponseField name="cancelledCount" type="number">
  Cancel response only. Number of pending outbound jobs plus contact attempts cancelled.
</ResponseField>

<ResponseField name="cancelledActivities" type="number">
  Cancel response only. Number of outbound activity records marked as cancelled.
</ResponseField>

<ResponseField name="pausedCount" type="number">
  Pause response only. Number of queue jobs plus contact attempts paused.
</ResponseField>

<ResponseField name="pausedActivities" type="number">
  Pause response only. Number of outbound activity records marked as paused.
</ResponseField>

<ResponseField name="resumedCount" type="number">
  Resume response only. Number of queue jobs plus contact attempts restored.
</ResponseField>

<ResponseField name="resumedActivities" type="number">
  Resume response only. Number of outbound activity records marked as resumed.
</ResponseField>

<ResponseField name="outbounds" type="array">
  Search-level pause/resume response. Outbound attempts paused or resumed by this request. Each item includes `id`, `method`,
  `contactId`, `attemptDate`, and `destination`.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable summary of the action taken.
</ResponseField>

### Search-Level Pause/Resume Response Shape

```json theme={null}
{
  "outbounds": [
    {
      "id": "17333f98-0226-4142-a8cb-bbb9af936795",
      "method": "THIRD_PARTY_PENDING",
      "contactId": null,
      "attemptDate": "2026-06-25T21:41:16.461Z",
      "destination": null
    },
    {
      "id": "e8c015f6-3866-4226-827f-e8e86328ef29",
      "method": "EMAIL",
      "contactId": "996bf751-05b9-424b-8217-44de7742decd",
      "attemptDate": "2026-06-25T21:41:16.644Z",
      "destination": "hr@acme.com"
    }
  ]
}
```

## Webhook Behavior

<Note>
  Only successful pause and resume operations that change outbound state emit a `verification.notification` webhook. Listing or
  cancelling outbounds does not emit an outbound-control notification, and idempotent pause or resume requests do not emit a
  duplicate event.
</Note>

| Operation            | `notificationType`  |
| -------------------- | ------------------- |
| Pause one outbound   | `OUTBOUND_PAUSED`   |
| Pause all outbounds  | `OUTBOUNDS_PAUSED`  |
| Resume one outbound  | `OUTBOUND_RESUMED`  |
| Resume all outbounds | `OUTBOUNDS_RESUMED` |

The webhook includes an `outboundControl` object with:

* `action`: `PAUSE_OUTBOUND` or `RESUME_OUTBOUND`
* `outboundId`: the requested outbound ID for single-outbound operations
* `reason`: the optional reason supplied in the request
* `count`: number of outbound items paused or resumed
* `activitiesMarked`: number of activity records marked as paused or resumed
* `trigger`: `api`
* `outbounds`: affected outbound summaries for search-level operations

```json theme={null}
{
  "event": "verification.notification",
  "occurredAt": "2026-06-25T21:42:00.000Z",
  "data": {
    "searchId": "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111",
    "externalSearchId": "EXT-12345",
    "searchType": "EMPLOYMENT",
    "notificationType": "OUTBOUNDS_PAUSED",
    "outboundControl": {
      "action": "PAUSE_OUTBOUND",
      "reason": "Entity HR department closed for holiday",
      "count": 2,
      "activitiesMarked": 2,
      "trigger": "api",
      "outbounds": [
        {
          "id": "e8c015f6-3866-4226-827f-e8e86328ef29",
          "method": "EMAIL",
          "contactId": "996bf751-05b9-424b-8217-44de7742decd",
          "attemptDate": "2026-06-25T21:41:16.644Z",
          "destination": "hr@acme.com"
        }
      ]
    }
  }
}
```

`GET .../outbounds` and `cancel-outbounds` do not emit outbound-control webhook notifications. See
[Webhook Events](/webhooks/events#outboundcontrol-object) for the complete payload definition.

## Additional Behavior

* `contactDestination` scoping is supported for cancel operations. Pause and resume always apply to all pending outbound (or a single outbound when using the single-outbound endpoints).
* If a replacement outbound supersedes a paused outbound, the old attempt is marked as superseded and is not recreated on resume.
* Use [Manage Search Contacts](/api-reference/endpoints/manage-search-contacts) to inspect or update the contact plan.
