# Places

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 26-35 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 36-47 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 48-62 |
| [Mental Model](#mental-model) | Concepts and state boundaries needed for correct operation. | 63-83 |
| [Preflight](#preflight) | State, authority, inputs, and readiness to verify before execution. | 84-98 |
| [Risk And Side Effects](#risk-and-side-effects) | Effects, approvals, cost, privacy, and retry boundaries. | 99-108 |
| [Canonical Operating Pattern](#canonical-operating-pattern) | The normal end-to-end execution sequence. | 109-125 |
| [Core SDK Surfaces](#core-sdk-surfaces) | Exact source-backed callable contracts owned by this guide. | 126-136 |
| [Data Contracts](#data-contracts) | Required identities, fields, evidence, handles, and durable shapes. | 137-149 |
| [Examples](#examples) | Representative usage patterns and code. | 150-205 |
| [Verification](#verification) | Evidence required before reporting success. | 206-220 |
| [Troubleshooting](#troubleshooting) | Failure diagnosis and corrective routes. | 221-233 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 234-245 |
<!-- END GENERATED: guide-map -->

## Purpose

Use `vf.sources.places.*` for provider-neutral local-business and place
research through Bridge-backed Growth capabilities: place search first, then
review collection for selected place ids.

This guide owns place-specific acquisition semantics. It does not own general
company/person discovery, arbitrary web extraction, CRM suppression, final Play
UI/report rendering, or sequence activation.

## Use This When

- The target audience is location/place based: restaurants, clinics, agencies,
  stores, practices, local services, venues, or other businesses where a place
  listing and reviews are useful evidence.
- You need provider-neutral place rows with stable `place_id` values before
  collecting reviews.
- You need review text, ratings, dates, or review metadata as evidence for a
  GTM workflow, report, qualification pass, or local audit.
- A repeatable Workflow Play needs a bounded place source step with preserved
  `job_id`, `artifact_id`, counts, and usage.

## Do Not Use This For

- General software-company, account, or person discovery. Use
  `audience_discovery.md`, `web.md`, `linkedin.md`, `crunchbase.md`, or
  `crm.md` depending on the source.
- Browser-backed evidence capture, logged-in provider sessions, screenshots, or
  rendered DOM inspection. Use `host_browser.md`; use `web.md` for explicit
  URL page capture/screenshots.
- Geography containment over already-acquired rows. Use `geo.md` and
  `row_operations.md`.
- Final Workflow Play report UI. Use `workflow_reports.md`; places jobs only
  produce source/review artifacts.
- Sequence staging, publish, sends, or purchases. Use `sequences.md`,
  `sequence_authoring.md`, `senders.md`, and `safety.md`.

## Mental Model

Places work is a two-job pipeline:

1. Search with `vf.sources.places.search_start(...)` or
   `vf.sources.places.search(...)` to create a provider-neutral places artifact.
2. Select bounded `place_id` values from those rows.
3. Collect reviews with `vf.sources.places.reviews_start(...)` or
   `vf.sources.places.reviews(...)`.
4. Page/export artifact rows, qualify or shape them, then render reports or
   continue the workflow.

The `_start` functions default to returning immediately with a `PendingJob`.
The non-`_start` convenience functions default to waiting. Both still start
Bridge-backed artifact jobs and can consume credits. In this namespace,
`wait=True` means the SDK uses its default 30-second poll; pass an integer
timeout or use `vf.jobs.result(job).wait(timeout=...)` for longer jobs.
Search accepts one complete query string or a sequence; reviews likewise
accept one `place_id` or a sequence. Scalar strings are never split into
characters.

## Preflight

1. Confirm the workspace with `auth.md` when live platform state matters.
2. Write specific place queries and a location hint. Avoid broad generic
   queries such as `businesses in California`.
3. Bound search size before the call. `queries` must contain 1-10 non-empty
   strings; `limit` must be 1-100.
4. Plan how review IDs will be selected. Reviews require 1-50 `place_id`
   values; `max_reviews` must be 1-100 per call.
5. Decide whether this is an ad hoc place search or a repeatable Workflow Play.
   For repeatable work, run through `workflow_operations.md` and collect the
   job with `ctx.collect_artifact_job(...)`.
6. Print query/location/limit before starting the job, then preserve `job_id`,
   `artifact_id`, status, usage, and row counts afterward.

## Risk And Side Effects

| Operation | Risk | Rule |
| --- | --- | --- |
| `vf.sources.places.search_start(...)` / `.search(...)` | Bridge-backed source job, credit usage, artifact rows | Can consume credits. Preview query count and limit first; preserve job/artifact handles. |
| `vf.sources.places.reviews_start(...)` / `.reviews(...)` | Bridge-backed source job, credit usage, artifact rows | Can consume credits. Only call after selecting bounded place ids from search rows or explicit user input. |
| Reading job/artifact rows | platform read | Use `artifacts_jobs.md`; do not assume preview rows are the full artifact. |
| Local row filtering/qualification/reporting | local or separate job depending on call | Use `row_operations.md`, `geo.md`, `testing.md`, and `workflow_reports.md` as appropriate. |
| Sequence/source staging or publish | out of scope mutation | Use sequence references and explicit confirmation gates. |

## Canonical Operating Pattern

1. Start search with explicit `queries`, `location`, and `limit`.
2. Wait or poll using `vf.jobs.result(job).wait(...)` when downstream logic
   needs committed artifact rows.
3. Read/page artifact rows via `JobResult.rows(...)`, `iter_rows(...)`, or
   artifact helpers; do not rely only on inline preview rows.
4. Inspect `place_id`, name/title, address/location fields, category/type,
   rating/review counts, source URL, and duplicates before review collection.
5. Select place IDs intentionally, then start reviews with a bounded
   `max_reviews` and optional `since` date.
6. Preserve both search and review job/artifact handles in workflow outputs,
   reports, or status messages.
7. Render final review/place outputs through `workflow_reports.md` when the
   result should be a Play UI; use `dashboard.md` only for quick local HTML
   inspection.

## Core SDK Surfaces

<!-- BEGIN GENERATED: core-sdk-surfaces -->
| Function | Use When | Inputs | Output And Handles To Preserve | Side Effect | Source |
| --- | --- | --- | --- | --- | --- |
| `vf.sources.places.reviews` | Use for reviews collection when the caller wants the completed or started job handle. | <strong>Required</strong>: `place_ids` (str \| Sequence[str]; required): Place ids parameter for `sources.places.reviews`.<br><strong>Optional</strong>: `extra` (Mapping[str, object] \| None; optional; default `None`): Advanced provider/backend options passed through deliberately; prefer typed args when available.; `max_reviews` (int; optional; default `50`): Max reviews parameter for `sources.places.reviews`.; `since` (str \| None; optional; default `None`): Since parameter for `sources.places.reviews`.; `wait` (bool \| int; optional; default `True`): If false, return immediately with a job/status handle; if true or a timeout integer, poll until completion or timeout. | `PendingJob` with provider-neutral review rows, job id, preview rows, and usage summary. Wrap with `vf.jobs.result(job)` before waiting or paging committed artifact rows.<br><strong>Common next calls</strong>: `vf.reports.define`, `vf.rows.ai_analyze` | artifact_job | installed SDK: `verbiflow/sources.py:943-989` |
| `vf.sources.places.reviews_start` | Use after places search to collect reviews for selected place ids through Bridge policy. | <strong>Required</strong>: `place_ids` (str \| Sequence[str]; required): One provider-neutral place id or a sequence of place ids.<br><strong>Optional</strong>: `extra` (Mapping[str, object] \| None; optional; default `None`): Advanced provider/backend options passed through deliberately; prefer typed args when available.; `max_reviews` (int; optional; default `50`): Maximum reviews per place.; `since` (str \| None; optional; default `None`): Optional lower bound date for reviews, e.g. 2024-01-01.; `wait` (bool \| int; optional; default `False`): If false, return immediately with a job/status handle; if true or a timeout integer, poll until completion or timeout. | `PendingJob` with provider-neutral review rows, job id, preview rows, and usage summary. Wrap with `vf.jobs.result(job)` before waiting or paging committed artifact rows.<br><strong>Common next calls</strong>: `vf.jobs.result`, `vf.artifacts.inspect`, `vf.reports.define` | artifact_job | installed SDK: `verbiflow/sources.py:872-941` |
| `vf.sources.places.search` | Use for Bridge-backed places search when the caller wants the completed or started job handle. | <strong>Required</strong>: `queries` (str \| Sequence[str]; required): Queries parameter for `sources.places.search`.<br><strong>Optional</strong>: `extra` (Mapping[str, object] \| None; optional; default `None`): Advanced provider/backend options passed through deliberately; prefer typed args when available.; `limit` (int; optional; default `50`): Maximum number of records, preview rows, or results to request.; `location` (str \| None; optional; default `None`): Location parameter for `sources.places.search`.; `wait` (bool \| int; optional; default `True`): If false, return immediately with a job/status handle; if true or a timeout integer, poll until completion or timeout. | `PendingJob` with provider-neutral place rows, job id, preview rows, and usage summary. Wrap with `vf.jobs.result(job)` before waiting or paging committed artifact rows.<br><strong>Common next calls</strong>: `vf.sources.places.reviews_start`, `vf.rows.ai_analyze` | artifact_job | installed SDK: `verbiflow/sources.py:824-870` |
| `vf.sources.places.search_start` | Use for Bridge-backed places search at scale; provider choice, policy, audit, and usage stay in Bridge. | <strong>Required</strong>: `queries` (str \| Sequence[str]; required): One provider-neutral place query or a sequence of queries.<br><strong>Optional</strong>: `extra` (Mapping[str, object] \| None; optional; default `None`): Advanced provider/backend options passed through deliberately; prefer typed args when available.; `limit` (int; optional; default `50`): Maximum places to return across all queries.; `location` (str \| None; optional; default `None`): Optional geographic location hint such as city, state, or country.; `wait` (bool \| int; optional; default `False`): When true, poll the returned job before returning. | `PendingJob` with provider-neutral place rows, job id, preview rows, and usage summary. Wrap with `vf.jobs.result(job)` before waiting or paging committed artifact rows.<br><strong>Common next calls</strong>: `vf.jobs.result`, `vf.artifacts.inspect`, `vf.sources.places.reviews_start` | artifact_job | installed SDK: `verbiflow/sources.py:751-822` |
<!-- END GENERATED: core-sdk-surfaces -->

## Data Contracts

| Contract | Meaning |
| --- | --- |
| `queries` | 1-10 non-empty place search strings. Use concrete category + location intent. |
| `location` | Optional location hint sent with search. It is not a post-filter guarantee; verify returned rows. |
| `limit` | Maximum requested places across queries; SDK validates 1-100. Usage is `limit * credit_unit_cost`, where `credit_unit_cost` is the live server-published rate snapshot. |
| `place_id` | Provider-neutral identifier returned by places search and required for review collection. Preserve it exactly. |
| `max_reviews` | Maximum reviews per selected place; SDK validates 1-100. |
| `since` | Optional lower bound date string for reviews, such as `2024-01-01`. Verify backend/provider support before treating it as strict legal/compliance filtering. |
| `PendingJob` | Job handle with `job_id`, optional `artifact_id`, status fields, preview rows, and summary/usage. Wrap it with `vf.jobs.result(...)` for waiting and paging. |
| Artifact rows | Search/review records committed by Bridge. Page them through job/artifact helpers when completeness matters. |

## Examples

### Search Places And Inspect Rows

```python
import verbiflow as vf

job = vf.sources.places.search_start(
    ["orthodontists accepting Invisalign"],
    location="Austin, TX",
    limit=25,
)
result = vf.jobs.result(job)
print({"job_id": result.job_id, "status": result.job.status, "finished": result.job.finished})

result.wait(timeout=300)
rows = result.rows(limit=25)
print({"job_id": result.job_id, "row_count": len(rows)})
print(rows[:3])
```

### Collect Reviews For Selected Place IDs

```python
import verbiflow as vf

place_ids = ["place_123", "place_456"]
job = vf.sources.places.reviews_start(
    place_ids,
    max_reviews=50,
    since="2024-01-01",
)
result = vf.jobs.result(job).wait(timeout=300)
reviews = result.rows(limit=100)
print({"job_id": result.job_id, "reviews": len(reviews)})
```

### Workflow Collection Pattern

```python
pending = vf.sources.places.search_start(
    queries,
    location=location,
    limit=25,
)
ctx.collect_artifact_job(
    pending,
    name="places_search",
    table="places",
    key="place_id",
    object_type="account",
    identities=("place_id", "company_domain"),
    downstream_ready=True,
)
```

## Verification

- Query count, location, and limit were printed before search.
- `job_id` and any `artifact_id` were preserved for every search/review job.
- Search results contain usable `place_id` values before review collection.
- Returned places are actually in the intended geography/category; do not trust
  query wording alone.
- Review collection used a bounded `place_ids` list and `max_reviews`.
- Artifact row count was checked separately from preview rows when completeness
  mattered.
- Workflow outputs/reports include source query, location, limits, job ids,
  artifact ids, and row counts.
- Final Play UI/report output, if needed, was rendered through
  `workflow_reports.md`.

## Troubleshooting

| Symptom | Likely Cause | Fix |
| --- | --- | --- |
| `places search requires at least one query` | Empty or whitespace-only queries | Build and print the cleaned query list before calling search. |
| `places search accepts at most 10 queries` | Too many queries in one call | Chunk deliberately and read `parallelism.md` before fan-out. |
| `places search limit must be between 1 and 100` | Invalid limit | Clamp intentionally and print the final limit; do not silently broaden. |
| `places reviews accepts at most 50 place ids` | Too many selected places | Select a smaller reviewed cohort or batch with preserved job ids. |
| `max_reviews must be between 1 and 100` | Invalid review cap | Set a bounded cap and explain coverage expectations. |
| Review job returns few/no rows | Place IDs are invalid, provider has no reviews, or `since` is too restrictive | Inspect selected search rows and retry with a smaller known-good place set. |
| Agent wants every matching place | Preview rows are not full artifact pagination | Use `artifacts_jobs.md` to page/export committed artifact rows. |
| User wants screenshots/rendered evidence | Places source is not a browser capture tool | Use `host_browser.md` or `web.md` depending on auth/rendering needs. |

## Related References

| If you are doing this | Read next |
| --- | --- |
| General audience/account/person discovery | `audience_discovery.md` |
| Waiting, paging, exporting, or staging job artifacts | `artifacts_jobs.md` |
| Filtering already-acquired rows by geography | `geo.md`, `row_operations.md` |
| Building a repeatable Workflow Play around places | `workflow_operations.md`, `workflow_sources.md`, `workflow_composition.md` |
| Rendering final Play UI/report outputs from place/review rows | `workflow_reports.md` |
| Quick local HTML inspection of place rows | `dashboard.md` |
| Reviewing row quality and counts | `testing.md` |
| Sequence staging or activation | `sequences.md`, `sequence_authoring.md`, `safety.md` |
