Skip to content

MaintenanceThe former company search endpoint goes into maintenance on November 9Migration guide

SDKs // TypeScript // Guides

Async tasks

Last verified

Wait for live profiles, Find Email, Verify Email and Find Phone with the TypeScript SDK, resume saved task ids, and parse webhook deliveries.

Live fetches and contact lookups return a Task before the result is ready.

Start and wait for a task

fetch.personLive, fetch.companyLive, contact.findEmail, contact.verifyEmail and contact.findPhone start a task and return a Task right away. task.id is the task's webhookId.

Call task.wait() to poll until the task ends. When the task succeeds, the method returns its final state (data.status, data.result, data.creditsConsumed). When the task fails, the method raises TaskFailedError. Polling is free and does not count toward your rate limit.

TypeScript SDK

Live fetch

import ReverseContact, { TaskFailedError, TaskTimeoutError } from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const task = await client.fetch.personLive({ url: "https://social.com/in/janedoe" });
// Save the id first: after a restart, client.tasks.wait(id) resumes without paying for a new task.
console.log("Task id:", task.id);

try {
  const done = await task.wait({ timeout: 30 * 60 * 1000 });
  console.log(done.data.result?.firstName, "credits:", done.data.creditsConsumed);
} catch (error) {
  if (error instanceof TaskFailedError) {
    console.log("Task failed:", error.errorCode, "credits:", error.creditsConsumed);
  } else if (error instanceof TaskTimeoutError) {
    console.log("Still running, resume later with client.tasks.wait:", error.taskId);
  } else {
    throw error;
  }
}

How wait() behaves:

  • Each poll asks the API to hold the answer for up to 20 seconds (pollWait, 0 to 20), so the result arrives as soon as the task ends. Two polls start at least Retry-After seconds apart, 2 seconds when the header is missing.
  • timeout is the overall deadline in milliseconds, 30 minutes by default. When it passes, wait() raises TaskTimeoutError with taskId and lastStatus. The task may still finish: resume it with client.tasks.wait(taskId).
  • A task that ends with status: "errored" raises TaskFailedError, with errorCode, creditsConsumed, result and notFound. The notFound field is true for data-not-found, person-not-found, company-not-found, email-not-found and phone-not-found.
  • onPoll is called with each state the SDK reads, and signal stops the wait (see Timeouts and cancellation).
  • The SDK never starts a new task after a failure. Your code decides whether to start another task, which can be billed again.

client.tasks.retrieve(id, { wait: 20 }) reads one state of a task without waiting for the end. Polling describes the task lifecycle and how long a result stays available.

Webhook delivery instead of polling

Pass webhookUrl when you create the task to receive the result at that HTTPS URL as { webhookId, data }. Use parseWebhookDelivery to check the payload shape and read webhookId, data and isError. The isError field is true when data.errorCode is a non-empty string. The helper does not validate the profile itself.

TypeScript SDK

Webhook delivery

import ReverseContact, { parseWebhookDelivery } from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const task = await client.fetch.personLive({
  url: "https://social.com/in/janedoe",
  webhookUrl: "https://your-app.com/webhooks/reversecontact"
});
console.log("Store this id to match the delivery:", task.id);

// The route behind webhookUrl, as a Fetch API handler (Bun, Deno, edge runtimes).
async function handleWebhook(request: Request): Promise<Response> {
  const delivery = parseWebhookDelivery(await request.json());
  if (delivery.isError) console.log(delivery.webhookId, "failed:", delivery.data);
  else console.log(delivery.webhookId, "result:", delivery.data);
  // Answer within 10 seconds, then process the data: deduplicate on webhookId.
  return new Response(null, { status: 200 });
}

A task created with webhookUrl can still be polled with task.wait(). See Webhooks for delivery failures and retries.

Read a task without waiting for completion

task.retrieve({ wait: 20 }) reads one snapshot of the same task. task.status holds the initial acknowledgement status. Read snapshot.data.status for the current state. To retrieve or wait for a saved task id, use the retrieve() and wait() methods in the client.tasks reference.

TypeScript SDK

Verify an email

import ReverseContact from "@reverse-contact/sdk";

const client = new ReverseContact();
const task = await client.contact.verifyEmail({ email: "jane@acme.com" });
const snapshot = await task.retrieve({ wait: 20 });
console.log(snapshot.data.status);
const done = await task.wait();
console.log(done.data.result?.status);

Verify Email returns email and a status of valid, risky, invalid or unknown. Find Email and Find Phone return arrays of { value, type }. See client.contact and client.fetch for their parameters.

parseWebhookDelivery raises ReverseContactError if the delivery envelope is invalid. List operations and Bulk tasks use separate wait methods, described in Lists and Bulk enrichment.

Return to the TypeScript SDK overview.

FAQ

How do I wait for a live profile or Find Email result?

Call task.wait() on the Task returned by a live fetch or contact lookup. The SDK polls for free, for up to 30 minutes by default.

How do I resume waiting after my process restarts?

Save task.id before waiting, then call client.tasks.wait(taskId) after restarting. Resuming a task avoids creating another paid lookup.

What happens when an asynchronous SDK task fails?

task.wait() raises TaskFailedError with the task error code, credits consumed and any result. The SDK does not start a replacement task.

Can I poll a task that also uses a webhook?

A task created with webhookUrl can still be polled with task.wait(). parseWebhookDelivery checks the callback envelope and identifies error deliveries.