SOURCE_ID: search_local_businesses NAME: Search Local Businesses CATEGORY: List Building Build a static list of local businesses around a map location by running a map search query at a given latitude/longitude and zoom. Imported records become available to your Floqer workflows for enrichment, scoring, outreach, and the like. INDEX: 1. Endpoints 2. Body shape (preview + create) 3. Filter fields catalogue 4. Dynamic options 5. How to configure end-to-end 6. Key notes 7. When to use ================================================================================ 1. ENDPOINTS ================================================================================ Source identifier (used in every endpoint path): `search_local_businesses`. POST /api/v1/sources/search_local_businesses/preview Scope: sources:read Returns the first page of businesses that WOULD be imported for the given location + query, without creating anything. Use this to validate the coordinates, zoom, and query before committing. POST /api/v1/sources/search_local_businesses Scope: sources:write Creates the source and imports matching businesses (up to `max_count`). Returns `source_instance_id` (the new source's UUID). GET /api/v1/sources//data Scope: sources:read Paginated rows imported into the created source. `` is the UUID returned by Create. Query: `page_no` (default 1), `page_size` (default 20, max 200). Source-agnostic; see concepts.txt §10. POST /api/v1/sources//sync Scope: sources:write Connects the created source to a workflow and (by default) backfills it with the source's current rows. `` here is the UUID returned by Create. Body: { workflow_id, field_mapping, push_existing?, run? } — `field_mapping` keys are `input.` references on the target workflow, values are the source fields to pull. This step is source-agnostic; see concepts.txt §10 for the full shape. No connection is required. There is no dynamic-options endpoint for this source (see §4). ================================================================================ 2. BODY SHAPE (PREVIEW + CREATE) ================================================================================ Search Local Businesses is always a one-time static import — there is no `pull_mode`, `schedule`, or recurring re-pull. `max_count` caps the import size. The four search fields (`lat`, `lng`, `api_zoom`, `search_query`) may be sent at the TOP LEVEL of the body OR nested inside a `filters` object — both shapes are accepted. All four are required; a missing one is rejected with 400 naming the missing field. Preview accepts (all snake_case): lat required: latitude (number) lng required: longitude (number) api_zoom required: map zoom level (number) search_query required: search text (string) max_count optional: integer | string; ignored on preview (or all of the above nested under a `filters` object) Create accepts all the preview fields plus: name required: display name for the new source max_count optional: cap on rows imported; default 20 Example create body (top-level fields): { "name": "Coffee shops near downtown SF", "max_count": 100, "lat": 37.7749, "lng": -122.4194, "api_zoom": 14, "search_query": "coffee shop" } Equivalent body (nested under filters): { "name": "Coffee shops near downtown SF", "max_count": 100, "filters": { "lat": 37.7749, "lng": -122.4194, "api_zoom": 14, "search_query": "coffee shop" } } Preview response envelope: { "status": 200, "data": { "data": [ { "position": 1, "title": "Blue Bottle Coffee", "place_id": "...", "gps_coordinates": { "latitude": 37.77, "longitude": -122.41 }, "rating": 4.5, "reviews": 1200, "business_type": "Coffee shop", "address": "66 Mint St, San Francisco, CA", "phone": "+1 ...", "website": "https://...", "google_maps_link": "https://www.google.com/maps?cid=...", ... } ], "metadata": { "total_results": 20 } } } Rows are plain key/value objects: position, title, place_id, data_id, data_cid, gps_coordinates, rating, reviews, business_type, types, address, open_state, hours, operating_hours, phone, extensions, service_options, thumbnail, google_maps_link, website. Preview returns the first page of results. Create response envelope: { "status": 201, "data": { "source_instance_id": "", "name": "Coffee shops near downtown SF", "created_at": "2026-06-02T12:00:00.000Z" } } ================================================================================ 3. FILTER FIELDS CATALOGUE ================================================================================ The four search fields (top-level or under `filters`): lat (number) REQUIRED Latitude of the search center. Example: 37.7749 lng (number) REQUIRED Longitude of the search center. Example: -122.4194 api_zoom (number) REQUIRED Map zoom level — controls how wide the search radius is. Lower zoom covers a larger area; higher zoom is tighter around the center. Typical city-level searches use ~12-15. Example: 14 search_query (string) REQUIRED The business type / search text, exactly as you'd type into a map search. Examples: "coffee shop", "dentist", "plumber near me", "italian restaurant". There are no other filter keys (no separate country, rating, or category filters) — narrow the result set by choosing the center, zoom, and a specific `search_query`. Examples: Coffee shops around downtown San Francisco: { "lat": 37.7749, "lng": -122.4194, "api_zoom": 14, "search_query": "coffee shop" } Dentists in central London: { "filters": { "lat": 51.5074, "lng": -0.1278, "api_zoom": 13, "search_query": "dentist" } } ================================================================================ 4. DYNAMIC OPTIONS ================================================================================ No dynamic-options endpoint is registered for this source. All four search fields are supplied directly: pick a center (`lat`/`lng`), a `api_zoom` level for the radius, and a `search_query`. Preview to confirm the area and query return the businesses you expect. ================================================================================ 5. HOW TO CONFIGURE END-TO-END ================================================================================ Step 1 — Preview before committing POST /api/v1/sources/search_local_businesses/preview Body: { "lat": 37.7749, "lng": -122.4194, "api_zoom": 14, "search_query": "coffee shop" } Check the returned `data[]`. Adjust the center, zoom, or query until the results match the area/businesses you want — preview never creates anything. Step 2 — Create the source POST /api/v1/sources/search_local_businesses Body: { "name": "Coffee shops near downtown SF", "max_count": 100, "lat": 37.7749, "lng": -122.4194, "api_zoom": 14, "search_query": "coffee shop" } `max_count` defaults to 20 when omitted; results are pulled page by page up to `max_count`. Response: { "status": 201, "data": { "source_instance_id": "", "name", "created_at" }} Step 2b — (Optional) Poll imported rows GET /api/v1/sources//data?page_no=1&page_size=20 ( = UUID from Step 2) Step 3 — Sync the source into a workflow POST /api/v1/sources//sync ( = the UUID from Step 2 ) Build `field_mapping`: a. GET /api/v1/workflows → pick the destination workflow_id. b. GET /api/v1/workflows//sheets//inputs → each input has a `reference` like `{{input.business_name}}`. c. Map each workflow input (reference WITHOUT braces) to a source field. Body: { "workflow_id": "", "field_mapping": { "input.business_name": "title", "input.website": "website", "input.phone": "phone" }, "push_existing": true, "run": "all" } See concepts.txt §10 for the full sync semantics (source-agnostic). ================================================================================ 6. KEY NOTES ================================================================================ - No connection required. This endpoint does NOT return 424. - All four fields (`lat`, `lng`, `api_zoom`, `search_query`) are required. A missing field is rejected with 400 naming the field. - Fields may be sent at the top level OR nested under `filters` — both shapes work. `lat`/`lng`/`api_zoom` must be numbers; `search_query` a non-empty string. - `api_zoom` controls the search radius, not a result count. Use a lower zoom for a wider area and a higher zoom to stay tight around the center. - One-time static import. There is no `pull_mode` or `schedule`; re-run Create for a fresh pull. `max_count` defaults to 20 when omitted. - Credits are consumed on create (scaled by how many result pages `max_count` requires). Insufficient balance surfaces as 402. - A rate limit on the underlying search surfaces as a transient error; retry shortly. ================================================================================ 7. WHEN TO USE ================================================================================ - Local prospecting: "Coffee shops in downtown SF", "Dentists in Austin": pick the center coords + zoom + a specific search_query. - Field-sales territory building: list every business of a type in an area, then Sync into a workflow to enrich phone/website and run outreach. - Local market research: rating/reviews/business_type come back on each row for scoring and segmentation downstream. When you want B2B firmographic targeting (size, revenue, industry, tech) rather than map-based local businesses, use `find_companies`. ================================================================================ Last updated: 2026-06-02. Reference: https://floqer.com/docs/reference