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

# End to end contact workflow

The contact workflow follows three stages: search for the contact you want to enrich, submit the record for research, and retrieve the completed result. Each stage produces an identifier you carry into the next step — losing either identifier breaks the chain, so save both as soon as you receive them. This page walks through the full workflow, explains your two result-delivery options, and covers what to do once research is complete.

## Before you start

* Choose your authentication method: [API key](/authentication/api-keys) (`Token` header) or [OAuth](/authentication/oauth) (`Authorization: Bearer`).
* Open the reference pages you'll use: [Search contacts](/searchcontacts), [Research contacts](/researchcontacts), [Poll contact research results](/pollcontactsresearchresults).

## Workflow

<Steps>
  <Step title="Search for contacts">
    Call [Search contacts](/searchcontacts) with filters such as `jobTitle`, `companyName`, or `location`. The response returns a list of matching records, each with a `searchResultId`.
  </Step>

  <Step title="Save the search result identifier">
    Review the response and identify the record you want to enrich. Save its `searchResultId` — you'll pass this to the research endpoint in the next step.

    <Note>
      Keep the `searchResultId` from the search response and the `requestId` from the research response. Each identifier serves a different purpose: the search result ID initiates research; the request ID tracks the result. Do not discard either until your workflow is complete.
    </Note>
  </Step>

  <Step title="Submit a research request">
    Pass your `searchResultId` to [Research contacts](/researchcontacts). The API queues the record for enrichment and returns a `requestId`.
  </Step>

  <Step title="Save the request identifier">
    Save the `requestId` returned by the research endpoint. You need it to retrieve the completed result, whether you're using webhooks or polling.
  </Step>

  <Step title="Choose a result delivery method">
    Select one delivery method per request. Both return the same enriched data — the difference is whether Seamless pushes the result to you or you pull it on demand.

    <Tabs>
      <Tab title="Webhooks (async)">
        Configure a webhook endpoint in **Settings → Webhooks** and select the `contact-researched` event type. When research completes, Seamless sends a `POST` request to your endpoint with the full result.

        Use webhooks when you want near-instant delivery without polling overhead. See [Receive research results with webhooks](/receive-research-results-with-webhooks) for setup instructions, a receiver code example, and validation guidance.
      </Tab>

      <Tab title="Polling (on demand)">
        Call [Poll contact research results](/pollcontactsresearchresults) with your `requestId` at a regular interval. Check the `status` field in the response: continue polling while status is `researching` and stop when it returns `done`.

        Use polling for scripts, notebooks, and simple integrations that don't require a public HTTPS endpoint.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Retrieve the result and continue">
    Once research is complete, the enriched contact record is available in the poll response or delivered to your webhook endpoint. Read the data and continue your application workflow.
  </Step>
</Steps>

## What to do after research completes

<CardGroup cols={2}>
  <Card title="Get org contacts" icon="user" href="/getcontacts">
    Retrieve enriched contact records already stored in your organization without starting a new research request.
  </Card>

  <Card title="Understand identifiers and request flow" icon="id-card" href="/understand-identifiers-and-request-flow">
    Learn how the search result ID and request ID relate to each other and where each one appears in the workflow.
  </Card>

  <Card title="Build a deterministic agent workflow" icon="robot" href="/build-a-deterministic-agent-workflow">
    Automate the contact workflow with an AI agent using a structured, repeatable sequence of API calls.
  </Card>

  <Card title="Receive results with webhooks" icon="webhook" href="/receive-research-results-with-webhooks">
    Set up an HTTPS endpoint to receive completed research results asynchronously.
  </Card>
</CardGroup>

## AI agent guidance

<AccordionGroup>
  <Accordion title="What an agent must save at each step">
    Save the `searchResultId` immediately after the search response. Save the `requestId` immediately after the research response. Both identifiers are required to complete the workflow — do not proceed to the next step until the current identifier is stored.
  </Accordion>

  <Accordion title="When to submit the research request">
    Do not submit a research request until the agent holds a valid `searchResultId` from a successful search response. Submitting without a confirmed identifier causes the request to fail.
  </Accordion>

  <Accordion title="How to choose a result delivery method">
    Choose one delivery method — webhooks or polling — per research request. Do not mix both for the same `requestId`. If your agent environment supports receiving inbound HTTP requests, prefer webhooks. Otherwise, use polling.
  </Accordion>

  <Accordion title="When to stop polling">
    Poll the [Poll contact research results](/pollcontactsresearchresults) endpoint until the `status` field returns `done`, `missing`, `error`, or `duplicate`. Stop polling as soon as a terminal status is received — do not continue polling after the request completes.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="You do not know which identifier to keep">
    Two identifiers exist in this workflow. After calling [Search contacts](/searchcontacts), save the `searchResultId` from the matching record — this goes into the research step. After calling [Research contacts](/researchcontacts), save the `requestId` from the response — this is used for polling or tracking webhook delivery.
  </Accordion>

  <Accordion title="Your workflow stops after research starts">
    A research submission is asynchronous — the research endpoint returns a `requestId` but does not wait for enrichment to complete. You must use either webhooks or polling to retrieve the result. See [Receive research results with webhooks](/receive-research-results-with-webhooks) for push delivery, or call [Poll contact research results](/pollcontactsresearchresults) to pull the result on demand. If you continue to have trouble, see [Troubleshoot authentication and request failures](/troubleshoot-authentication-and-request-failures).
  </Accordion>
</AccordionGroup>
