SDKs // TypeScript // Resources
client.bulk
Last verified
Use client.bulk in the Reverse Contact TypeScript SDK to enrich people in bulk, wait for the job, and read results as they come or as CSV or NDJSON.
Submit people for Bulk enrichment, then check progress, wait for the job to stop, cancel the job, read its results as they come or download them.
| Method | Endpoint | Cost |
|---|---|---|
client.bulk.enrichPersons() | Bulk enrichment | Free to send. Each item costs the same as its individual API call. Credits are reserved when the job is created and refunded for data that is not found. |
client.bulk.list() | Job history | Free. |
client.bulk.retrieve() | Get a job | Free even with a zero balance. Does not count against rate limits. |
client.bulk.results() | Download job results | Free even with a zero balance. |
client.bulk.rows() | Read job results by page | Free even with a zero balance. Each page counts toward rate limits. |
client.bulk.iterateRows() | Read job results by page | Free even with a zero balance. Each page counts toward rate limits. |
client.bulk.cancel() | Cancel a job | Free. Items that had not started are never charged. |
client.bulk.wait() | Get a job | Free even with a zero balance. Does not count against rate limits. |
client.bulk.listAll() | Job history | Free. |
Create client by following Install and configure. The examples use a saved jobId from the relevant job family. The @reverse-contact/sdk package exports Body, Data, Query and the other types used in the signatures.
JSON responses contain data and optional quotas and metadata. They also include the original response, with its body already read. See First call for response handling.
HTTP errors use the APIError subclasses and retry rules: BadRequestError, AuthenticationError, InsufficientCreditsError, PermissionDeniedError, NotFoundError, ConflictError, GoneError, UnprocessableEntityError, RateLimitError, DailyLimitError, KeyCreditLimitError, UnavailableForLegalReasonsError and InternalServerError, according to the API response. Other statuses use APIError.
enrichPersons()
Send 1 to 25,000 items. The SDK generates an Idempotency-Key if you omit it and reuses the key on automatic retries. Save your own key to repeat the same submission after a restart.
Signature
client.bulk.enrichPersons(
params: Body<"bulkEnrichPersons">,
options?: IdempotentRequestOptions
): Promise<Result<Data<"bulkEnrichPersons">>>Parameters
| Name | Type | Description |
|---|---|---|
params required | Body<"bulkEnrichPersons"> | Request body. See the fields and their requirements below. |
params.items required | Body<"bulkEnrichPersons">["items"] | 1 to 25,000 people, see Items |
params.families | ("profile" | "contact_email" | "contact_phone")[] | What to look up for each item: profile, contact_email, contact_phone. Defaults to ["profile"]. |
params.emailType | string | With contact_email, the kind of email to find: professional (default), personal or any |
params.live | boolean | true fetches the profile of a Social profile URL item live. Omitted or false, saved data is used. |
params.name | string | A name for the job, up to 255 characters, shown in the job history and in the app. Defaults to Sent via API. |
params.webhookUrl | string | Public HTTPS URL that receives one POST when the job settles. See Webhook callback |
options | IdempotentRequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. Also accepts idempotencyKey. The SDK generates a key if you omit it. |
Returns
A response envelope with the background job in data.job. Save data.job.id, then call client.bulk.wait(id). See Lists and Bulk enrichment. This is not a Job object.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response.
Example
Example
const created = await client.bulk.enrichPersons({
items: [{ linkedinUrl: "https://social.com/in/janedoe", externalId: "crm-001" }],
families: ["profile"]
}, { idempotencyKey: "crm-export-2026-11-04" });
console.log("Save job id:", created.data.job.id);
const progress = await client.bulk.wait(created.data.job.id);
console.log(progress.data.status);list()
Read background job history, including Bulk enrichment and List jobs allowed by the API key permissions.
Signature
client.bulk.list(
params?: Query<"listJobs">,
options?: RequestOptions
): Promise<Page<Data<"listJobs">["items"][number], undefined>>Parameters
| Name | Type | Description |
|---|---|---|
params | Query<"listJobs"> | Query parameters. Omit to use the defaults. |
params.type | string | Filter by these comma-separated job types. See Job types |
params.status | string | Filter by these comma-separated statuses: queued, running, paused, completed, cancelled, failed |
params.listId | string | Return only jobs for this List (UUID) |
params.perPage | number | Jobs per page, from 1 to 100. Defaults to 50. |
params.cursor | string | The nextCursor of the previous page, sent with the same filters. A malformed cursor, or one sent with other filters, returns 400. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. |
Returns
A Page with results in data and pagination through nextCursor, hasNextPage() and getNextPage(). The page also includes optional quotas and metadata, and the original response.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response.
Example
Example
const page = await client.bulk.list({ type: "enrich_persons", perPage: 20 });
console.log(page.data);retrieve()
Read the current state of a background job. Use wait to hold the request while the job is queued or running.
Signature
client.bulk.retrieve(
jobId: string,
params?: Query<"getJob">,
options?: RequestOptions
): Promise<Result<Data<"getJob">>>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
params | Query<"getJob"> | Query parameters. Omit to use the defaults. |
params.wait | number | Hold the request up to this many seconds, 0 to 20, while the job is queued or running. It answers as soon as the job settles or pauses, or with the job still running when the wait ends. Defaults to 0. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. |
Returns
Result<BulkJob> with the current status, progress, credit usage and result links in data.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response.
Example
Example
const result = await client.bulk.retrieve(jobId, { wait: 20 });
console.log(result.data.status, result.data.credits);results()
Download only when links.results is set, after the job completes or is cancelled. Failed jobs have no results file.
Signature
client.bulk.results(
jobId: string,
params?: Query<"getJobResults">,
options?: RequestOptions
): Promise<string>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
params | Query<"getJobResults"> | Query parameters. Omit to use the defaults. |
params.format | "csv" | "ndjson" | csv for the CSV file, ndjson for one JobResultLine JSON object per line. Defaults to csv. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. |
Returns
A string: the CSV without its byte order mark, or with format: "ndjson" one JSON object per line. Prepend "\uFEFF" when saving the CSV for spreadsheet applications.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options. ConflictError with JOB_RESULTS_NOT_READY means the file is not ready. ConflictError with JOB_RESULTS_FORMAT_UNAVAILABLE means the job was stored before NDJSON existed: download its CSV.
Example
Example
const job = await client.bulk.retrieve(jobId);
if (job.data.links.results) {
const csv = await client.bulk.results(jobId);
const ndjson = await client.bulk.results(jobId, { format: "ndjson" });
const items = ndjson.split("\n").filter(Boolean).map((line) => JSON.parse(line));
console.log(csv.length, items.length);
}rows()
Read one page of results, in the order sent, from the start of the run. While the job runs, a page stops at the first item not finished: data is empty and nextCursor is set while the next item runs, so read it again after Retry-After. nextCursor is null once nothing more will come. Available from SDK 0.3.0.
Signature
client.bulk.rows(
jobId: string,
params?: Query<"getJobRows">,
options?: RequestOptions
): Promise<Page<PageItem<Data<"getJobRows">>, Interpretation<Data<"getJobRows">>>>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
params | Query<"getJobRows"> | Query parameters. Omit to read from the first item. |
params.cursor | string | nextCursor of the previous page, up to 512 characters. Without it, the page starts at the first item. |
params.limit | number | Items per page, 1 to 100. Defaults to 100. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. |
Returns
A Page with JobResultLine items in data, nextCursor and getNextPage(), like list(). extras.status is the job status when the page was read. A page can hold fewer items than limit. The page also includes optional quotas and metadata, and the original response.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response. ConflictError with JOB_RESULTS_FORMAT_UNAVAILABLE means the job was stored before reading by page existed: download its CSV with results(). RateLimitError with JOB_ROWS_BUSY means too many pages are being read at once: the SDK retries it after Retry-After, as Errors and retries describes.
Example
Example
const page = await client.bulk.rows(jobId, { limit: 100 });
for (const item of page.data) console.log(item.row, item.status);
console.log(page.extras.status, page.nextCursor);iterateRows()
Read the results one item at a time, as they become ready, whatever the job is doing. While the next item runs, the iterator waits Retry-After (2 seconds by default) and reads the same position again. It ends with the job, or when the job is paused, since nothing moves until someone resumes it: read on later with rows() and the last cursor. A cancelled job still finishes the items it had started, within the hour, and the iterator waits for them too. Available from SDK 0.3.0.
Signature
client.bulk.iterateRows(
jobId: string,
params?: Query<"getJobRows">,
options?: RequestOptions
): AsyncGenerator<JobResultLine, void, unknown>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
params | Query<"getJobRows"> | cursor to start after a page you already read, and limit, 1 to 100 items per page. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. The signal also stops the wait between pages. See Client options. |
Returns
An AsyncGenerator of JobResultLine items, in the order sent. The @reverse-contact/sdk package exports the JobResultLine type.
Errors
The errors of rows(). Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError.
Example
Example
for await (const item of client.bulk.iterateRows(jobId)) {
console.log(item.row, item.input.externalId, item.status, item.creditsConsumed);
}cancel()
Request a server-side stop. Items that have not started are not charged.
Signature
client.bulk.cancel(
jobId: string,
options?: RequestOptions
): Promise<Result<Data<"cancelJob">>>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
options | RequestOptions | Optional per-request timeout, maxRetries, headers and signal. See Client options. |
Returns
A response envelope with the cancellation acknowledgement in data.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response.
Example
Example
const result = await client.bulk.cancel(jobId);
console.log(result.data);wait()
Wait while the background job is queued or running. A paused job returns control to your code even though the job can resume later.
Signature
client.bulk.wait(
jobId: string,
options?: WaitOptions<BulkJob>
): Promise<Result<BulkJob>>Parameters
| Name | Type | Description |
|---|---|---|
jobId required | string | Background job id from created.data.job.id or job history. |
options | WaitOptions<BulkJob> | Optional overall timeout, pollWait, onPoll, headers and signal. See Wait options. |
Returns
Result<BulkJob> when the status is completed, cancelled, failed or paused. A failed status does not raise JobFailedError. Check data.status.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response. JobTimeoutError means the overall wait deadline has expired. An unsuccessful terminal state does not raise JobFailedError.
Example
Example
const result = await client.bulk.wait(jobId, { timeout: 30 * 60 * 1000 });
console.log(result.data.status, result.data.links.results);listAll()
Signature
client.bulk.listAll(
params?: Query<"listJobs">,
options?: ListIteratorOptions
): AsyncGenerator<Data<"listJobs">["items"][number], void, unknown>Parameters
| Name | Type | Description |
|---|---|---|
params | Query<"listJobs"> | Query parameters. Omit to use the defaults. |
params.type | string | Filter by these comma-separated job types. See Job types |
params.status | string | Filter by these comma-separated statuses: queued, running, paused, completed, cancelled, failed |
params.listId | string | Return only jobs for this List (UUID) |
params.perPage | number | Jobs per page, from 1 to 100. Defaults to 50. |
params.cursor | string | The nextCursor of the previous page, sent with the same filters. A malformed cursor, or one sent with other filters, returns 400. |
options | ListIteratorOptions | Optional maxResults, a nonnegative safe integer. Omit to read all pages. Also accepts request options. |
Returns
An AsyncGenerator of individual results. The iterator requests pages as needed. A repeated cursor raises ReverseContactError.
Errors
Calls can raise the HTTP APIError subclasses listed above. Network failures or cancellation raise APIConnectionError, and attempt timeouts raise APITimeoutError. ReverseContactError reports invalid SDK options or an invalid successful JSON response. ReverseContactError also reports invalid perPage or maxResults values and repeated cursors.
Example
Example
for await (const job of client.bulk.listAll({ type: "enrich_persons" })) {
console.log(job.id, job.status);
}Related guides
Lists and Bulk enrichment, Timeouts and cancellation. Return to the TypeScript SDK overview.
FAQ
How do I start a Bulk enrichment job in TypeScript?
Call client.bulk.enrichPersons() with 1 to 25,000 items. Save created.data.job.id and use client.bulk.wait() to follow progress.
Does client.bulk.wait throw when a Bulk job fails?
client.bulk.wait() returns jobs in completed, cancelled, failed or paused states. Check result.data.status. A failed state does not raise JobFailedError.
When can I download Bulk results?
Call client.bulk.results() when links.results is set, after the job completes or is cancelled. The method returns CSV text, or NDJSON with format: "ndjson".
Can I read Bulk results before the job ends in TypeScript?
Yes, from SDK 0.3.0. client.bulk.iterateRows() yields each result as soon as it is ready, in the order sent, and client.bulk.rows() reads one page at a time with a cursor.