Backfilling Leads with Time-Based Filtering

If your integration missed leads — for example, due to a webhook processing outage or a deployment issue — you can retrieve them yourself using time-based filters on the Lead IDs endpoint. No need to contact Yelp support.

Time Filter Parameters

The GET /v3/businesses/{business_id}/lead_ids endpoint accepts two optional query parameters for filtering by lead creation time:

ParameterTypeRequiredDescription
created_afterstringNoOnly return leads created at or after this timestamp (inclusive)
created_beforestringNoOnly return leads created at or before this timestamp (inclusive)

Format Rules

  • ISO 8601 with timezone required — e.g. 2026-06-03T00:00:00Z or 2026-06-03T00:00:00+00:00
  • Both parameters are optional and composable — use one or both to define your window
  • created_after must not be later than created_before
  • URL-encode the + as %2B when using explicit offset format in query strings

Error Responses (HTTP 400)

ConditionError message
Invalid formatInvalid ISO 8601 date-time format for 'created_after'.
Missing timezoneTimezone is required for 'created_after', e.g. '2024-06-30T23:59:59Z' or '2024-06-30T23:59:59+00:00'.
Inverted range'created_after' must not be later than 'created_before'.

Example Requests

All leads created after a specific time

GET /v3/businesses/{business_id}/lead_ids?created_after=2026-06-03T00:00:00Z

All leads created before a specific time

GET /v3/businesses/{business_id}/lead_ids?created_before=2026-06-04T23:59:59Z

Leads within a time window (e.g., June 3-4 outage)

GET /v3/businesses/{business_id}/lead_ids?created_after=2026-06-03T00:00:00Z&created_before=2026-06-04T23:59:59Z

Using explicit UTC offset (note %2B encoding)

GET /v3/businesses/{business_id}/lead_ids?created_after=2026-06-03T00:00:00%2B00:00&created_before=2026-06-04T23:59:59%2B00:00

How Pagination Works with Time Filters

  1. Time filters narrow the result set first
  2. Pagination with after_lead_id operates within the filtered window
  3. The response includes has_more (boolean) to indicate whether additional pages exist
  4. limit controls page size (1-20, default 20)

Walk-through

First request — get the first page of leads in your window:

GET /v3/businesses/{business_id}/lead_ids?created_after=2026-06-03T00:00:00Z&created_before=2026-06-04T23:59:59Z&limit=20
{
  "lead_ids": ["AVR752Y-h-OnR5mRnPSb9Q", "EB0kXICqQNxgkgdfe2BFPA", "...", "EOXly16w2XXmNc7T25e1iw"],
  "has_more": true
}

Next request — pass the last ID as cursor:

GET /v3/businesses/{business_id}/lead_ids?created_after=2026-06-03T00:00:00Z&created_before=2026-06-04T23:59:59Z&limit=20&after_lead_id=xyz789
{
  "lead_ids": ["aaa111", "bbb222"],
  "has_more": false
}

When has_more is false, you have retrieved all leads in the window.

Recommended Backfilling Pattern

Step-by-step

  1. Identify the start and end of your outage window
  2. Request the first page with created_after and created_before
  3. While has_more is true, take the last lead ID from the response and pass it as after_lead_id
  4. For each lead ID, call GET /v3/leads/{lead_id} to fetch full lead details
  5. If you receive HTTP 429 (rate limit), wait and retry

What to do with the Lead IDs

Once you have the list of lead IDs from your time window, you'll need to fetch the full details and conversation history for each one to replicate what your webhook handler would have processed.

Step 1: Fetch lead details

For each lead ID, call:

GET /v3/leads/{lead_id}

This returns the full lead object including:

  • business_id — the business the lead belongs to
  • time_created — when the lead was created
  • user — consumer display name
  • project — job details (location, availability, job names, survey answers, attachments)

Step 2: Fetch events

If your integration processes message history (e.g., the initial consumer message), call:

GET /v3/leads/{lead_id}/events?limit=20

This returns the conversation events in chronological order. Paginate with older_than_cursor / newer_than_cursor if the lead has more than 20 events.

The first event typically contains the consumer's initial request with survey answers — this is the equivalent of what arrives in a NEW_EVENT webhook notification.

Step 3: Process as if received via webhook

Feed each lead + its events through the same code path your webhook handler uses. Since you're pulling (not receiving a push), you can process them sequentially or in small batches.

Tips

  • Use narrow time windows for large backlogs. If you were down for a week, process one day at a time to stay under rate limits.
  • Sliding window pattern: Start with the first day of your outage, fully paginate it, then move the window forward by one day. Repeat until you've covered the full outage period.
  • Safe to retry. The same parameters always return the same leads. Requests are idempotent — you can re-run your backfill safely if it gets interrupted.
  • Monitor has_more. When it returns false, you've retrieved everything in that window.
  • Rate limits (HTTP 429). Back off and retry. Do not retry immediately in a tight loop.
  • Deduplicate. If your system already processed some leads before the outage, check against your local records before re-processing to avoid duplicates.

Did this page help you?