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 |
enhanced |
Boolean | Desc. enhanced |
error_code |
Enum(OK):String |
Desc. error_code |
format |
Enum(CSV, MLJSON):String |
Desc. format |
id |
String(format:ulid) | Desc. id |
inserted_at |
String(format:date-time) | An ISO8601 formatted timestamp |
messaging_lookup |
Boolean | Desc. messaging_lookup |
numbers |
Array(0..20000):String(format:tel) | Numbers to lookup |
on_done_actions |
OnDoneActions | |
reference_id |
String(1..255) | Desc. reference_id |
status |
Enum:String | Desc. status |
type |
Enum(LRN, MCL, CNAM):String |
Desc. type |
updated_at |
String(format:date-time) | An ISO8601 formatted timestamp |
Desc. enable_cdr_export
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
Used for LRN type, enables enhanced lookup.
Please consult the LRN documentation for additional details.
Desc. error_code
OK- there was no errorBAD_SOURCE_FILE- there was an issue with the source file
Desc. format
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.
CSVMLJSON
Desc. id
Another format for UUID, used primarily for tasks, requests and messages.
Desc. messaging_lookup
Used for LRN type, enables messaging lookup, MCL will be added.
Please consult the LRN documentation for additional details.
Desc. reference_id
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
Allowed values
NEWSCHEDULEDPROCESSINGSTORINGDELIVERINGCOMPLETEDABORTEDERROR
Desc. status
Status gives a brief overview of the state of the task.
NEW- the export task was freshly created and has not begun processingSCHEDULED- the task has been scheduled to execute at a later time (see date field for more information)PROCESSING- the task has begun processingSTORING- the task is currently storing its results on internal storage for later accessDELIVERING- 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 detailsABORTED- the task was aborted, execution was haltedERROR- the task experienced an error, error_code will have more details if any
Desc. type
The type of bulk dip that should be performed:
LRN- Location Routing Number lookupsMCL- Messaging Carrier LookupCNAM- Caller Name
Example
{
"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 |
format |
Enum(CSV, MLJSON):String |
Desc. format |
messaging_lookup |
Boolean | Desc. messaging_lookup |
numbers |
Array(0..20000):String(format:tel) | Numbers to lookup |
on_done_actions |
CreateOnDoneActions | |
reference_id |
String(1..255) | Desc. reference_id |
type |
Enum(LRN, MCL, CNAM):String |
Desc. type |
Desc. enhanced
Used for LRN type, enables enhanced lookup.
Please consult the LRN documentation for additional details.
Desc. format
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.
CSVMLJSON
Desc. messaging_lookup
Used for LRN type, enables messaging lookup, MCL will be added.
Please consult the LRN documentation for additional details.
Desc. reference_id
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
The type of bulk dip that should be performed:
LRN- Location Routing Number lookupsMCL- Messaging Carrier LookupCNAM- Caller Name
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
POST /api/v1/bulk_dip_tasks HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 632
{
"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/1.1 201
Content-Type: application/json
Content-Length: 947
{
"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/1.1 403
Content-Type: application/json
Content-Length: 312
{
"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/1.1 422
Content-Type: application/json
Content-Length: 241
{
"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
GET /api/v1/bulk_dip_tasks HTTP/1.1
Retrieve Bulk Dip Tasks
Query Parameters
| Name | Type | Description |
|---|---|---|
| first | Integer | Query Desc. first |
| last | Integer | Query Desc. last |
| after | String | Query Desc. after |
| before | String | Query Desc. before |
Query Desc. first
The number of items to return starting from the 'after' cursor
Query Desc. last
The number of items to return behind the 'before' cursor
Query Desc. after
The cursor representing the starting point of a 'first' based paging
Query Desc. before
The cursor representing the starting point of a 'last' based paging
Request
GET /api/v1/bulk_dip_tasks HTTP/1.1
Accept: application/json
Response 200
application/json
HTTP/1.1 200
Content-Type: application/json
Content-Length: 1248
{
"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/1.1 403
Content-Type: application/json
Content-Length: 312
{
"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
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
GET /api/v1/bulk_dip_tasks/{id} HTTP/1.1
Accept: application/json
Response 200
application/json
HTTP/1.1 200
Content-Type: application/json
Content-Length: 947
{
"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/1.1 403
Content-Type: application/json
Content-Length: 312
{
"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/1.1 404
Content-Type: application/json
Content-Length: 314
{
"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
number,lrn,cdr_id,errros
12003004000,12003004001,01GFRKXW88KFERW32T79AGZXHE,
MLJSON
{"number":"12003004000","lrn":"12003004001","cdr_id":"01GFRKXW88KFERW32T79AGZXHE","errors":""}
But, if enhanced was enabled:
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#fragmentthe 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.
NEWmeans the action hasn't been executed yetREJECTEDgenerally happens before any dipping is performed in case the source data has errorsERRORcan either be a permanent error or a temporary errorCOMPLETEDthe action was completed successfully