> Tychron Atlas API & Provisioning Reference — chapter 15 of 35 as Markdown. Web version: https://docs.tychron.com/api-reference/bulk-dip-tasks/
> Source: https://docs.tychron.com/api-reference/ · Updated 2026-08-12 · Generated from the Atlas OpenAPI spec (https://api.atlas.tychron.online/api/v1/openapi is the live contract; this file is a dated snapshot of it).
> Source revision: atlas_api_reference_2026-08-12.md · sha256 482ebd3b014af053 · sanitize gate v1 clean · reconciled with OpenAPI 2026.8.25-p01 (spec sha256 cc049ef38c71cd6e) on 2026-09-05 · content last modified 2026-09-09 · newer definition under review since 2026-09-09 (not yet reconciled)
> Scope: the Atlas platform API only. The SMS, MMS, CNAM, LRN and MCL services are separate APIs with their own specifications: https://docs.tychron.com/openapi/
> Machine index: https://docs.tychron.com/llms.txt

# Bulk Dip Tasks

## Schema

A Bulk Dip Task is a long-running asynchronous request, numbers are specified in the request and
will be dipped by the system internally, once completed, the result will be handled via
the on_done_actions.

Note that it is possible to create a Bulk Dip Task without an `on_done_action`, this will
effectively perform a no-op, you will still be charged for the dips, but nothing will be
delivered.


__Type__ Object

| Name                | Type                                   | Description                            |
| ------------------- | -------------------------------------- | -------------------------------------- |
| `done_at`           | String(format:date-time)               | An ISO8601 formatted timestamp         |
| `enable_cdr_export` | Boolean                                | [Desc. `enable_cdr_export`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-206) |
| `enhanced`          | Boolean                                | [Desc. `enhanced`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-207)          |
| `error_code`        | Enum(`OK`):String                      | [Desc. `error_code`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-208)        |
| `format`            | Enum(`CSV`, `MLJSON`):String           | [Desc. `format`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-209)            |
| `id`                | String(format:ulid)                    | [Desc. `id`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-210)                |
| `inserted_at`       | String(format:date-time)               | An ISO8601 formatted timestamp         |
| `messaging_lookup`  | Boolean                                | [Desc. `messaging_lookup`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-211)  |
| `numbers`           | Array(0..20000):String(format:tel)     | Numbers to lookup                      |
| `on_done_actions`   | [OnDoneActions](https://docs.tychron.com/api-reference/schemas/#schema-ondoneactions) |                                        |
| `reference_id`      | String(1..255)                         | [Desc. `reference_id`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-212)      |
| `status`            | [Enum](https://docs.tychron.com/api-reference/bulk-dip-tasks/#enum-213):String               | [Desc. `status`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-214)            |
| `type`              | Enum(`LRN`, `MCL`, `CNAM`):String      | [Desc. `type`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-215)              |
| `updated_at`        | String(format:date-time)               | An ISO8601 formatted timestamp         |

#### Desc. `enable_cdr_export` {#desc-206}

Should CDRs generated by the bulk dip process be sent to the CDR Webhook?

By default this is disabled.

Note. This will generate CDRs while the task is processing.

#### Desc. `enhanced` {#desc-207}

Used for LRN type, enables enhanced lookup.

Please consult the LRN documentation for additional details.

#### Desc. `error_code` {#desc-208}

* `OK` - there was no error
* `BAD_SOURCE_FILE` - there was an issue with the source file

#### Desc. `format` {#desc-209}

The intended exported format, CSV will export a CSV file as expected.
MLJSON exports the cdrs as Multiline-JSON, that is each row in the file is a single record encoded as JSON.

* `CSV`
* `MLJSON`

#### Desc. `id` {#desc-210}

Another format for UUID, used primarily for tasks, requests and messages.

#### Desc. `messaging_lookup` {#desc-211}

Used for LRN type, enables messaging lookup, MCL will be added.

Please consult the LRN documentation for additional details.

#### Desc. `reference_id` {#desc-212}

A unique client provided id for the bulk task.

There is no particular format that is enforced, a general recommendation is to avoid
spaces and non-ASCII characters for best experience.

#### Enum Values status {#enum-213}

Allowed values

* `NEW`
* `SCHEDULED`
* `PROCESSING`
* `STORING`
* `DELIVERING`
* `COMPLETED`
* `ABORTED`
* `ERROR`

#### Desc. `status` {#desc-214}

Status gives a brief overview of the state of the task.

* `NEW` - the export task was freshly created and has not begun processing
* `SCHEDULED` - the task has been scheduled to execute at a later time (see date field for more information)
* `PROCESSING` - the task has begun processing
* `STORING` - the task is currently storing its results on internal storage for later access
* `DELIVERING` - the task is now attempting to deliver the exported file to the given endpoints (or notifying)
* `COMPLETED` - the task is completed and it is safe to delete or retrieve the exported details
* `ABORTED` - the task was aborted, execution was halted
* `ERROR` - the task experienced an error, error_code will have more details if any

#### Desc. `type` {#desc-215}

The type of bulk dip that should be performed:

* `LRN` - Location Routing Number lookups
* `MCL` - Messaging Carrier Lookup
* `CNAM` - Caller Name



__Example__

```json
{
  "done_at": "2021-08-13T04:08:44.762841Z",
  "enable_cdr_export": false,
  "enhanced": false,
  "error_code": "OK",
  "format": "CSV",
  "id": "01EH2Y28M6KXG14QMPM3HSP1Y0",
  "inserted_at": "2021-08-13T04:08:44.762841Z",
  "messaging_lookup": false,
  "numbers": [
    "12003004000"
  ],
  "on_done_actions": [
    {
      "archive_format": "TAR_GZ",
      "auth_identity": "upload-user",
      "auth_method": "BASIC",
      "auth_secret": "supersecretsauce",
      "data": "sftp://example.com:22/sub/path/to/store/exported_file/in",
      "error_code": "OK",
      "filename": "string",
      "protocol": "SFTP",
      "reference_id": "SFTP-export-action",
      "status": "NEW",
      "type": "SEND"
    }
  ],
  "reference_id": "lrn-bulk-LRN-2022-10-14",
  "status": "NEW",
  "type": "LRN",
  "updated_at": "2021-08-13T04:08:44.762841Z"
}
```


## Summary

Bulk Dip Tasks are an experimental feature, they will allow you, the client to perform CNAM, LRN, or MCL dips in bulk, the finished dip will be delivered to a configured endpoint.

Note that the creation API for bulk dip tasks, is asynchronous, it will return immediately after performing basic validation.

## API

### Create Bulk Dip Task

__Data__

| Name               | Type                                               | Description                           |
| ------------------ | -------------------------------------------------- | ------------------------------------- |
| `enhanced`         | Boolean                                            | [Desc. `enhanced`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-216)         |
| `format`           | Enum(`CSV`, `MLJSON`):String                       | [Desc. `format`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-217)           |
| `messaging_lookup` | Boolean                                            | [Desc. `messaging_lookup`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-218) |
| `numbers`          | Array(0..20000):String(format:tel)                 | Numbers to lookup                     |
| `on_done_actions`  | [CreateOnDoneActions](https://docs.tychron.com/api-reference/schemas/#schema-createondoneactions) |                                       |
| `reference_id`     | String(1..255)                                     | [Desc. `reference_id`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-219)     |
| `type`             | Enum(`LRN`, `MCL`, `CNAM`):String                  | [Desc. `type`](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-220)             |

#### Desc. `enhanced` {#desc-216}

Used for LRN type, enables enhanced lookup.

Please consult the LRN documentation for additional details.

#### Desc. `format` {#desc-217}

The intended exported format, CSV will export a CSV file as expected.
MLJSON exports the cdrs as Multiline-JSON, that is each row in the file is a single record encoded as JSON.

* `CSV`
* `MLJSON`

#### Desc. `messaging_lookup` {#desc-218}

Used for LRN type, enables messaging lookup, MCL will be added.

Please consult the LRN documentation for additional details.

#### Desc. `reference_id` {#desc-219}

A unique client provided id for the bulk task.

There is no particular format that is enforced, a general recommendation is to avoid
spaces and non-ASCII characters for best experience.

#### Desc. `type` {#desc-220}

The type of bulk dip that should be performed:

* `LRN` - Location Routing Number lookups
* `MCL` - Messaging Carrier Lookup
* `CNAM` - Caller Name



```http
POST /api/v1/bulk_dip_tasks HTTP/1.1
```

Create a new Bulk Dip Task.

Note that bulk dip tasks can be created without setting any on_done_actions,
however it may prove difficult to retrieve the completed file without assistance if done so.

Therefore it is recommended that an on_done_action is set with an appropriate endpoint to
deliver the completed file to.


#### Request application/json

```http
POST /api/v1/bulk_dip_tasks HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 632
```

```json
{
  "data": {
    "enhanced": false,
    "format": "CSV",
    "messaging_lookup": false,
    "numbers": [
      "12003004000"
    ],
    "on_done_actions": [
      {
        "archive_format": "TAR_GZ",
        "auth_identity": "upload-user",
        "auth_method": "BASIC",
        "auth_secret": "supersecretsauce",
        "data": "sftp://example.com:22/sub/path/to/store/exported_file/in",
        "filename": "string",
        "protocol": "SFTP",
        "reference_id": "SFTP-export-action",
        "type": "SEND"
      }
    ],
    "reference_id": "lrn-bulk-LRN-2022-10-14",
    "type": "LRN"
  },
  "type": "bulk_dip_task"
}
```

#### Response 201

##### application/json

```http
HTTP/1.1 201
Content-Type: application/json
Content-Length: 947
```

```json
{
  "data": {
    "done_at": "2021-08-13T04:08:44.762841Z",
    "enable_cdr_export": false,
    "enhanced": false,
    "error_code": "OK",
    "format": "CSV",
    "id": "01EH2Y28M6KXG14QMPM3HSP1Y0",
    "inserted_at": "2021-08-13T04:08:44.762841Z",
    "messaging_lookup": false,
    "numbers": [
      "12003004000"
    ],
    "on_done_actions": [
      {
        "archive_format": "TAR_GZ",
        "auth_identity": "upload-user",
        "auth_method": "BASIC",
        "auth_secret": "supersecretsauce",
        "data": "sftp://example.com:22/sub/path/to/store/exported_file/in",
        "error_code": "OK",
        "filename": "string",
        "protocol": "SFTP",
        "reference_id": "SFTP-export-action",
        "status": "NEW",
        "type": "SEND"
      }
    ],
    "reference_id": "lrn-bulk-LRN-2022-10-14",
    "status": "NEW",
    "type": "LRN",
    "updated_at": "2021-08-13T04:08:44.762841Z"
  },
  "type": "bulk_dip_task"
}
```
#### Response 403

##### application/json

```http
HTTP/1.1 403
Content-Type: application/json
Content-Length: 312
```

```json
{
  "errors": [
    {
      "code": "access_denied.no_scope",
      "detail": "No scope available to user role",
      "params": {
        "action": "index",
        "level": "guest",
        "resource": "resource"
      },
      "sub_code": "none",
      "title": "Access Denied, no scope available"
    }
  ]
}
```
#### Response 422

##### application/json

```http
HTTP/1.1 422
Content-Type: application/json
Content-Length: 241
```

```json
{
  "errors": [
    {
      "code": "invalid_parameter",
      "detail": "The specified resource could not be found",
      "source": {
        "pointer": "/data/type"
      },
      "sub_code": "none",
      "title": "Not Found"
    }
  ]
}
```


### List Bulk Dip Tasks

```http
GET /api/v1/bulk_dip_tasks HTTP/1.1
```

Retrieve Bulk Dip Tasks


__Query Parameters__

| Name   | Type    | Description                     |
| ------ | ------- | ------------------------------- |
| first  | Integer | [Query Desc. first](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-221)  |
| last   | Integer | [Query Desc. last](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-222)   |
| after  | String  | [Query Desc. after](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-223)  |
| before | String  | [Query Desc. before](https://docs.tychron.com/api-reference/bulk-dip-tasks/#desc-224) |

#### Query Desc. first {#desc-221}

The number of items to return starting from the 'after' cursor

#### Query Desc. last {#desc-222}

The number of items to return behind the 'before' cursor

#### Query Desc. after {#desc-223}

The cursor representing the starting point of a 'first' based paging

#### Query Desc. before {#desc-224}

The cursor representing the starting point of a 'last' based paging

#### Request

```http
GET /api/v1/bulk_dip_tasks HTTP/1.1
Accept: application/json
```
#### Response 200

##### application/json

```http
HTTP/1.1 200
Content-Type: application/json
Content-Length: 1248
```

```json
{
  "count": 1,
  "page_info": {
    "first": "string",
    "has_next_page": true,
    "has_previous_page": true,
    "last": "string"
  },
  "results": [
    {
      "data": {
        "done_at": "2021-08-13T04:08:44.762841Z",
        "enable_cdr_export": false,
        "enhanced": false,
        "error_code": "OK",
        "format": "CSV",
        "id": "01EH2Y28M6KXG14QMPM3HSP1Y0",
        "inserted_at": "2021-08-13T04:08:44.762841Z",
        "messaging_lookup": false,
        "numbers": [
          "12003004000"
        ],
        "on_done_actions": [
          {
            "archive_format": "TAR_GZ",
            "auth_identity": "upload-user",
            "auth_method": "BASIC",
            "auth_secret": "supersecretsauce",
            "data": "sftp://example.com:22/sub/path/to/store/exported_file/in",
            "error_code": "OK",
            "filename": "string",
            "protocol": "SFTP",
            "reference_id": "SFTP-export-action",
            "status": "NEW",
            "type": "SEND"
          }
        ],
        "reference_id": "lrn-bulk-LRN-2022-10-14",
        "status": "NEW",
        "type": "LRN",
        "updated_at": "2021-08-13T04:08:44.762841Z"
      },
      "type": "bulk_dip_task"
    }
  ]
}
```
#### Response 403

##### application/json

```http
HTTP/1.1 403
Content-Type: application/json
Content-Length: 312
```

```json
{
  "errors": [
    {
      "code": "access_denied.no_scope",
      "detail": "No scope available to user role",
      "params": {
        "action": "index",
        "level": "guest",
        "resource": "resource"
      },
      "sub_code": "none",
      "title": "Access Denied, no scope available"
    }
  ]
}
```


### Get Bulk Dip Tasks

```http
GET /api/v1/bulk_dip_tasks/{id} HTTP/1.1
```

Retrieve a Bulk Dip Task by ID


__Path Parameters__

| Name | Type                 | Description      |
| ---- | -------------------- | ---------------- |
| id   | String(format:ulid)! | Bulk Dip Task ID |

#### Request

```http
GET /api/v1/bulk_dip_tasks/{id} HTTP/1.1
Accept: application/json
```
#### Response 200

##### application/json

```http
HTTP/1.1 200
Content-Type: application/json
Content-Length: 947
```

```json
{
  "data": {
    "done_at": "2021-08-13T04:08:44.762841Z",
    "enable_cdr_export": false,
    "enhanced": false,
    "error_code": "OK",
    "format": "CSV",
    "id": "01EH2Y28M6KXG14QMPM3HSP1Y0",
    "inserted_at": "2021-08-13T04:08:44.762841Z",
    "messaging_lookup": false,
    "numbers": [
      "12003004000"
    ],
    "on_done_actions": [
      {
        "archive_format": "TAR_GZ",
        "auth_identity": "upload-user",
        "auth_method": "BASIC",
        "auth_secret": "supersecretsauce",
        "data": "sftp://example.com:22/sub/path/to/store/exported_file/in",
        "error_code": "OK",
        "filename": "string",
        "protocol": "SFTP",
        "reference_id": "SFTP-export-action",
        "status": "NEW",
        "type": "SEND"
      }
    ],
    "reference_id": "lrn-bulk-LRN-2022-10-14",
    "status": "NEW",
    "type": "LRN",
    "updated_at": "2021-08-13T04:08:44.762841Z"
  },
  "type": "bulk_dip_task"
}
```
#### Response 403

##### application/json

```http
HTTP/1.1 403
Content-Type: application/json
Content-Length: 312
```

```json
{
  "errors": [
    {
      "code": "access_denied.no_scope",
      "detail": "No scope available to user role",
      "params": {
        "action": "index",
        "level": "guest",
        "resource": "resource"
      },
      "sub_code": "none",
      "title": "Access Denied, no scope available"
    }
  ]
}
```
#### Response 404

##### application/json

```http
HTTP/1.1 404
Content-Type: application/json
Content-Length: 314
```

```json
{
  "errors": [
    {
      "code": "not_found",
      "detail": "The specified resource could not be found",
      "params": {
        "resource": {
          "id": "3fbb573a-6049-44a0-a12c-d3a1ffae0b69",
          "type": "user"
        }
      },
      "sub_code": "none",
      "title": "Not Found"
    }
  ]
}
```


## Webhook Integration

While tasks are allowed to be created without any `on_done_actions`, it is strongly recommended to do so.

### File Formats

Below are ALL fields that can appear in the CSV and MLJSON file uploaded upon completion.

| Name                     | Type   | Description                                            | Dip Type                              |
| ------------------------ | ------ | ------------------------------------------------------ | ------------------------------------- |
| `number` *               | String | The phone number that was dipped                       | ALL                                   |
| `lrn` *                  | String | The Local Routing Number                               | LRN                                   |
| `lrn_activated_at` *     | String | ISO8601 Timestamp of when the LRN was activated        | LRN                                   |
| `enhanced_carrier`       | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_carrier_type`  | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_city`          | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_zip_code`      | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_county`        | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_timezone`      | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_state`         | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_rate_center`   | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_lata`          | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_ocn`           | String |                                                        | LRN (when enhanced=true)              |
| `enhanced_country_code`  | String |                                                        | LRN (when enhanced=true)              |
| `messaging_enabled`      | String | Is the number messaging capable?                       | LRN (when messaging_lookup=true), MCL |
| `messaging_provider`     | String |                                                        | LRN (when messaging_lookup=true), MCL |
| `messaging_country`      | String |                                                        | LRN (when messaging_lookup=true), MCL |
| `messaging_country_code` | String | ISO Country Code (e.g. US)                             | LRN (when messaging_lookup=true), MCL |
| `messaging_reference_id` | String | Tychron Assigned Internal ID                           | LRN (when messaging_lookup=true), MCL |
| `cnam`                   | String | The Caller ID result                                   | CNAM                                  |
| `spam_type`              | String | Spam type hint                                         | CNAM                                  |
| `cdr_id`                 | String | The CDR for the row, can be empty if there is an error | ALL                                   |
| `errors`                 | String | A semi-colon separated list of error codes             | ALL                                   |

Note that depending on the Dip Type, some fields may be omitted or included in the file.

For example if LRN is performed without enhanced and messaging_lookup, it will look like this:

__CSV__

```csv
number,lrn,cdr_id,errros
12003004000,12003004001,01GFRKXW88KFERW32T79AGZXHE,
```

__MLJSON__

```json
{"number":"12003004000","lrn":"12003004001","cdr_id":"01GFRKXW88KFERW32T79AGZXHE","errors":""}
```

But, if enhanced was enabled:

__CSV__

```csv
number,lrn,enhanced_carrier,enhanced_carrier_type,enhanced_city,enhanced_zip_code,enhanced_county,enhanced_timezone,enhanced_state,enhanced_rate_center,enhanced_lata,enhanced_ocn,cdr_id,errors
```

A keen eye may realize that this mostly a 1:1 mapping with the existing CNAM, LRN, and MCL APIs, without sub objects.

__Carrier Types__

| Value    | Description                                       |
| -------- | ------------------------------------------------- |
| ILEC     | Incumbent Local Exchange Carrier                  |
| ICO      | Independent Telephone Company                     |
| ULEC     | Unbundled Local Exchange Carrier                  |
| RBOC     | Regional Bell Operating Company                   |
| CLEC     | Competitive Local Exchange Carrier                |
| CAP      | Competitive Access Provider                       |
| IXC      | Inter-exchange Carrier                            |
| WRSL     | Wireless Reseller                                 |
| IPES     | Internet Protocol Enabled Services                |
| ETHX     | Ethernet Exchange                                 |
| INTL     | International Telecommunications Service Provider |
| LRSL     | Local Reseller                                    |
| WIRELESS | Wireless                                          |
| PCS      | Personal Communications Service                   |
| PCSR     | Personal Communications Service Reseller          |
| PAGING   | Paging and messaging                              |

### Errors

* `account_balance_insufficient` - the dip was aborted because the parent account did not have a sufficient balance to perform it

### Protocols

While the protocols were covered in the Open API spec, this section will give some additional details on each field present in the OnDoneAction.

#### Archive Format

__Required__ NO

In case an archive containing the final file is needed, an archive format can be specified for the specific action.

The file will be the only content of that archive.

For example, if `ZIP` is requested, a `.zip` file will be uploaded to the specified path, or sent via the specified channel.

Without an Archive Format, the file will be uploaded as is.

#### Auth Method, Auth Identity, Auth Secret

As with most webhook formats, some form of Authorization fields are provided.

Auth Method denotes what kind of authorization should be done (if any), while Auth Identity and Auth Secret act as the username and password respectively.

Basic uses both, and Bearer only uses the Auth Secret.

Some protocols may not support both method/schemes, in those cases the missing value will be a placeholder, the client is expected to ignore the placeholder.

HTTP supports both, while SFTP only works with Basic, the username will be a placeholder.

#### Protocol & Data

Protocol and Data denote, how and where a notification or file should be uploaded.

If one is familiar with the switch, the protocol and data here should feel right at home.

* `HTTP` - `http://example.com:port/path/to/upload?query_params#fragment` the url will be maintained as given.
* `SFTP` - `sftp://example.com:port/path/to/upload` - sftp is special in that it will be deconstructed into host:port finally the SFTP client will change directories to the specified path component.

#### Reference ID

Unlike the parent record (BulkDipTask), the reference id here is optional, it is provided for the client to identify a specific action that may be causing problems with delivery.

#### Type

Type denotes what kind of action will be taken, either NONE, NOTIFY or SEND.

NONE is effectively a no-op, the action will be marked as completed regardless.

NOTIFY will only tell the endpoint that the dip was completed.

SEND will attempt to upload the completed file or archive to the endpoint.

#### Status

Status provides a rough overview of the current state of the action.

* `NEW` means the action hasn't been executed yet
* `REJECTED` generally happens before any dipping is performed in case the source data has errors
* `ERROR` can either be a permanent error or a temporary error
* `COMPLETED` the action was completed successfully

---

Previous chapter: https://docs.tychron.com/api-reference/api-keys.md  
Next chapter: https://docs.tychron.com/api-reference/call-data-webhooks.md  
Complete reference in one file: https://docs.tychron.com/llms-full.txt
