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:
| Parameter | Type | Required | Description |
|---|---|---|---|
created_after | string | No | Only return leads created at or after this timestamp (inclusive) |
created_before | string | No | Only return leads created at or before this timestamp (inclusive) |
Format Rules
- ISO 8601 with timezone required — e.g.
2026-06-03T00:00:00Zor2026-06-03T00:00:00+00:00 - Both parameters are optional and composable — use one or both to define your window
created_aftermust not be later thancreated_before- URL-encode the
+as%2Bwhen using explicit offset format in query strings
Error Responses (HTTP 400)
| Condition | Error message |
|---|---|
| Invalid format | Invalid ISO 8601 date-time format for 'created_after'. |
| Missing timezone | Timezone 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)
%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
- Time filters narrow the result set first
- Pagination with
after_lead_idoperates within the filtered window - The response includes
has_more(boolean) to indicate whether additional pages exist limitcontrols 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
- Identify the start and end of your outage window
- Request the first page with
created_afterandcreated_before - While
has_moreistrue, take the last lead ID from the response and pass it asafter_lead_id - For each lead ID, call
GET /v3/leads/{lead_id}to fetch full lead details - 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 totime_created— when the lead was createduser— consumer display nameproject— 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 returnsfalse, 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.
Updated about 4 hours ago
