# Get all available attributes
Source: https://docs.repromptai.com/api-reference/attributes/get-all-available-attributes
/openapi-v1.json get /place_enrichment/attributes
Get metadata for all available enrichment attributes
# Delete a batch
Source: https://docs.repromptai.com/api-reference/batches/delete-a-batch
/openapi-v1.json delete /place_enrichment/batches/{batch_id}
# Get batch status
Source: https://docs.repromptai.com/api-reference/batches/get-batch-status
/openapi-v1.json get /place_enrichment/batches/{batch_id}
# List batches
Source: https://docs.repromptai.com/api-reference/batches/list-batches
/openapi-v1.json get /place_enrichment/batches
Retrieve batches for an organization with pagination and optional search by name.
Returns a paginated list of batch jobs with their metadata including batch ID,
creation timestamp, and job counts. If 'query' is provided, only batches whose name matches (case-insensitive, substring) will be returned.
# Mark batches for refresh
Source: https://docs.repromptai.com/api-reference/batches/mark-batches-for-refresh
/openapi-v1.json post /place_enrichment/batches/refresh
Mark a list of batch IDs for refresh.
Sets the `refresh` flag on PlaceEnrichmentBatchJob for the provided batch IDs.
Only batches belonging to the organization tied to the API key are updated.
The response includes which batch IDs were updated and which were missing.
What refresh does: https://docs.repromptai.com/guides/monthly-refresh
Refreshes re-run enrichment for places you've marked to detect changes over time.
Runs execute on the 9th of every month, and by default re-run only the attributes
that were already enriched for that place.
Pass refresh=true to turn refresh on, or refresh=false to turn it off.
# Rename or update a batch
Source: https://docs.repromptai.com/api-reference/batches/rename-or-update-a-batch
/openapi-v1.json put /place_enrichment/batches/{batch_id}
Update batch name and/or refresh flag; omitted fields keep their current value.
# Reprocess a batch
Source: https://docs.repromptai.com/api-reference/batches/reprocess-a-batch
/openapi-v1.json post /place_enrichment/batches/{batch_id}/reprocess
Reprocess jobs in a specific batch.
You can specify which attributes to process by providing:
- 'attributes': A list of specific attributes to enrich (e.g., ["websites", "phoneNumbers", "categories"])
If not provided, "core" attributes will be processed: websites, phoneNumbers, openingHours, names, address, categories, closed_permanently
Options:
- failed_only: When true, only reprocess jobs with 'failed' status. When false, reprocess all jobs in the batch.
- incomplete_only: When true, only reprocess jobs with 'pending' or 'in_progress' status. When false, reprocess all jobs in the batch (unless failed_only is true).
# Submit a batch of places for enrichment
Source: https://docs.repromptai.com/api-reference/batches/submit-a-batch-of-places-for-enrichment
/openapi-v1.json post /place_enrichment/batches
Submit a batch of places for enrichment
```
# Enrich a single place synchronously
Source: https://docs.repromptai.com/api-reference/enrich-a-single-place-synchronously
/openapi-v1.json post /place_enrichment/enrich
# Create a CSV export
Source: https://docs.repromptai.com/api-reference/exports/create-a-csv-export
/openapi-v1.json post /place_enrichment/exports
Unified export endpoint. Small requests return 200 text/csv inline; large requests
create a durable async job and return 202 + status url. Idempotency-Key is optional but
recommended: send the same key on every retry of a create so a lost response can't spawn a
duplicate job (the client can't know the delivery mode in advance). Omit it and the request
still succeeds, just without that retry-safety.
# Download a completed export
Source: https://docs.repromptai.com/api-reference/exports/download-a-completed-export
/openapi-v1.json get /place_enrichment/exports/{export_id}/download
# Get export status
Source: https://docs.repromptai.com/api-reference/exports/get-export-status
/openapi-v1.json get /place_enrichment/exports/{export_id}
# List durable exports
Source: https://docs.repromptai.com/api-reference/exports/list-durable-exports
/openapi-v1.json get /place_enrichment/exports
# Delete a job
Source: https://docs.repromptai.com/api-reference/jobs/delete-a-job
/openapi-v1.json delete /place_enrichment/jobs/{place_id}
# Get a single enrichment job
Source: https://docs.repromptai.com/api-reference/jobs/get-a-single-enrichment-job
/openapi-v1.json get /place_enrichment/jobs/{place_id}
# Get enrichment jobs
Source: https://docs.repromptai.com/api-reference/jobs/get-enrichment-jobs
/openapi-v1.json get /place_enrichment/jobs
Returns a `JobListResponse` by default. With `groupBy=day` returns a `PaginatedBatchesResponse` of one synthetic batch per UTC day.
# Reprocess Jobs
Source: https://docs.repromptai.com/api-reference/jobs/reprocess-jobs
/openapi-v1.json post /place_enrichment/jobs/reprocess
# Submit a single enrichment job
Source: https://docs.repromptai.com/api-reference/jobs/submit-a-single-enrichment-job
/openapi-v1.json post /place_enrichment/jobs
Submit a place for asynchronous enrichment processing.
# Get a fast, source-backed answer
Source: https://docs.repromptai.com/api-reference/search-&-answers/get-a-fast-source-backed-answer
/openapi-search-ask-v1.json post /ask
Retrieves web results and generates a concise single-hop answer. This endpoint is not intended for deep research.
# Search the web
Source: https://docs.repromptai.com/api-reference/search-&-answers/search-the-web
/openapi-search-ask-v1.json post /search
Returns a stable, normalized list of web search results.
# Batch Processing
Source: https://docs.repromptai.com/guides/batch-processing
Submit places for enrichment asynchronously via batch endpoints.
### Endpoints
| Action | Method & Path |
| ----------------- | ---------------------------------------------------------------------------------- |
| Create batch | `POST /v1/{org_slug}/place_enrichment/batches` |
| Get batch status | `GET /v1/{org_slug}/place_enrichment/batches/{batch_id}` |
| Get batch results | `GET /v1/{org_slug}/place_enrichment/jobs?batchId={batch_id}&limit={n}&offset={n}` |
| Reprocess batch | `POST /v1/{org_slug}/place_enrichment/batches/{batch_id}/reprocess` |
| List batches | `GET /v1/{org_slug}/place_enrichment/batches?limit={n}&offset={n}` |
## Quick Start
Submit a minimal batch via the **Create batch** endpoint:
```json Request theme={null}
{
"batch_name": "Q1 Store Locations",
"jobs": [
{
"place_id": "store_001",
"inputs": {
"name": "Downtown Store",
"full_address": "123 Main St, New York, NY 10001",
"latitude": 40.7128,
"longitude": -74.0060
}
}
],
"attributes": ["websites", "phoneNumbers", "categories"]
}
```
Include `full_address` in `jobs[].inputs` when available — it improves enrichment accuracy.
The same response shape is returned by **Create batch** and **Get batch status**. The `jobs` object lists place IDs grouped by their job status (see [Monitoring Progress](#monitoring-progress)).
```json Response theme={null}
{
"id": "d98e206f-ff1d-4b5a-b0d8-18fff0757fef",
"batch_name": "Q1 Store Locations",
"status": "pending",
"jobs": {
"pending": ["store_001"],
"queued": [],
"in_progress": [],
"completed": [],
"failed": []
}
}
```
## Batch Limits
**Maximum places per request**: 50,000
Requests exceeding this limit return `400 Bad Request`. Split larger datasets into multiple batches (for example, up to 50,000 places per batch).
## Batch Status Lifecycle
Batches move through a small set of statuses driven by job state. The top-level `status` aggregates all jobs in the batch (e.g. `in_progress` if any job is still running). A batch is finished when `status` is `completed` or `failed`.
1. Not Started: Batch created; jobs are pending and not yet queued for processing.
2. Queued: Jobs are scheduled and waiting to be picked up by workers.
3. Processing: Jobs are actively being enriched by workers.
4. Completed: All jobs finished successfully.
5. Failed: Batch failed (e.g. too many job failures).
## Monitoring Progress
Call `GET /batches/{batch_id}` on an interval (e.g. every 5–10 seconds).
Stop polling when top-level `status` is `completed` or `failed`.
### Batch status response
The response exposes job-level status via the `jobs` object. Each key is a **job status**; each value is an array of place IDs whose enrichment job is in that status. Use the array lengths to derive progress (e.g. `jobs.completed.length + jobs.failed.length` over total).
| Field | Description |
| ------------ | ---------------------------------------------------------------------------------------------- |
| `id` | Batch identifier |
| `batch_name` | Display name |
| `status` | Aggregated batch status (`pending`, `queued`, `in_progress`, `completed`, `failed`) |
| `jobs` | Place IDs grouped by **job status**: `pending`, `queued`, `in_progress`, `completed`, `failed` |
| `metadata` | Optional: `total_jobs`, `completed_jobs`, `status_counts`, `success_rate` |
| `created_at` | Batch creation timestamp |
`jobs` is keyed by job status, not counts. Each array contains the `place_id` values for jobs in that status. Total jobs = sum of lengths across all job arrays.
```json theme={null}
{
"id": "d98e206f-ff1d-4b5a-b0d8-18fff0757fef",
"batch_name": "Q1 2024 Store Locations",
"status": "in_progress",
"jobs": {
"pending": ["store_001", "store_002"],
"queued": ["store_003", "store_004"],
"in_progress": ["store_005"],
"completed": ["store_006", "store_007"],
"failed": []
},
"created_at": "2024-01-15T10:00:00Z"
}
```
## Handling Results
### Fetch results
Use the **Get batch results** endpoint with `batchId`, `limit`, and `offset`. Returns `{ jobs, total, limit, offset }`.
Increment `offset` by `limit` until `offset + jobs.length >= total`.
### Success vs failed jobs
Each job in the `jobs` array has a `status` field. Filter by:
* `status === "completed"` — successful enrichments; use `outputs` for enriched data
* `status === "failed"` — failures; inspect for retry or manual review
Per-attribute run status (e.g. which enrichments ran or failed) lives under `job_metadata.attribute_status`. Use this for partial successes or to decide which attributes to reprocess.
| Value | Meaning |
| ---------------------- | --------------------------------- |
| `RUN` | Enrichment ran successfully |
| `NOT_RUN` | Enrichment was not executed |
| `ERROR` | Enrichment failed |
| `RUN_CONDITION_FAILED` | Skipped (missing required inputs) |
## Reprocessing Failed Items
`POST /batches/{batch_id}/reprocess` re-queues jobs for enrichment. Key options:
| Param | Default | Description |
| ----------------- | ------- | ------------------------------------------------ |
| `failed_only` | `true` | Only reprocess jobs with `failed` status |
| `incomplete_only` | `false` | Only reprocess pending/queued/in\_progress |
| `refresh` | `false` | Force fresh enrichment, ignore cached data |
| `attributes` | — | Override attributes to enrich |
| `attribute_set` | — | Use predefined set: `core`, `all`, `open_closed` |
Set `failed_only: false` and `incomplete_only: false` to reprocess all jobs in the batch.
## Listing Batches
`GET /batches?limit={n}&offset={n}&query={search}` returns paginated batches. Each batch includes `id`, `batch_name`, `status`, `status_counts`, `created_at`, and optional `metadata`.
## Best Practices
* **Descriptive batch names** — Use names that identify the batch or run so you can find them in the list.
* **Chunk large datasets** — Stay under 50K jobs per request; split into multiple batches or append via repeated requests with the same `batch_id`.
* **Handle failures** — Check `jobs.failed` after completion; use the reprocess endpoint to retry with `failed_only: true`.
## Next Steps
* Learn about [Place Enrichment](/guides/place-enrichment) for single-item enrichment
* Explore [Geofencing](/guides/geofencing) for location-based batch queries
* Check the [API Reference](/api-reference) for complete endpoint documentation
# CSV Export
Source: https://docs.repromptai.com/guides/csv-export
Export enriched place data for one or more batches as a single CSV, delivered inline or as a background job.
### Endpoints
| Action | Method & Path |
| ----------------- | -------------------------------------------------------------------- |
| Create export | `POST /v1/{org_slug}/place_enrichment/exports` |
| List exports | `GET /v1/{org_slug}/place_enrichment/exports?status=&cursor=&limit=` |
| Get export status | `GET /v1/{org_slug}/place_enrichment/exports/{export_id}` |
| Download export | `GET /v1/{org_slug}/place_enrichment/exports/{export_id}/download` |
Auth is the same as the batch endpoints: `Authorization: Bearer {YOUR_API_KEY}` or the `apiKey` header.
**Sync vs. Async export:**
| Selection | Response |
| ------------------------------------------------------------ | --------------------------- |
| ≤ \~50,000 rows (\~120 MB) — a single batch always qualifies | `200` — CSV inline |
| Bigger, spanning multiple batches | `202` — poll, then download |
## Quick Start
Call `POST /exports` with the `batch_ids` you want combined into one CSV; delivery mode is decided for you by size.
Prefer clicking through instead? See [Using the Dashboard](#using-the-dashboard) for the same flow with checkboxes and an **Export N Batches** button.
```bash Request theme={null}
curl -X POST \
'https://api.repromptai.com/v1/{org_slug}/place_enrichment/exports' \
-H 'Authorization: Bearer {YOUR_API_KEY}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 4a7c1e02-3f3d-4b1a-9c2e-8f6d2b1a9e40' \
-d '{
"batch_ids": ["batch_2024_03_15_123456", "batch_2024_03_16_654321"]
}'
```
```json 202 Response theme={null}
{
"id": "e59f3b9a-6b7d-4e21-9d34-9d1b6c9b6a41",
"status": "queued",
"batch_ids": ["batch_2024_03_15_123456", "batch_2024_03_16_654321"],
"batch_names": {
"batch_2024_03_15_123456": "NYC Restaurants March 2024",
"batch_2024_03_16_654321": "Chicago Retail March 2024"
},
"created_at": "2024-03-15T10:00:00Z",
"updated_at": "2024-03-15T10:00:00Z",
"status_url": "/v1/{org_slug}/place_enrichment/exports/e59f3b9a-6b7d-4e21-9d34-9d1b6c9b6a41",
"download_url": null,
"error": null,
"metadata": null,
"expired": false
}
```
`Idempotency-Key` is optional but recommended for async requests — see [Async Exports](#async-exports) for how it works.
## Sync Exports
Small exports skip the export job entirely. A single batch (max 50,000 places) always qualifies; so does any combination of batches that stays roughly under 50,000 rows and 120 MB. You get `200` back with the CSV already in the body:
```bash theme={null}
curl -X POST \
'https://api.repromptai.com/v1/{org_slug}/place_enrichment/exports' \
-H 'Authorization: Bearer {YOUR_API_KEY}' \
-H 'Content-Type: application/json' \
-d '{"batch_ids": ["batch_2024_03_15_123456"]}' \
-o place-enrichment.csv
```
## Async Exports
Larger selections return `202` immediately: `status: queued`, a `status_url` to poll, and `download_url: null` until the job finishes.
There is no set limit to number of batches or total jobs to export, async export comfortably handles exports >1M jobs across many batches.
### Idempotency-Key
Sending an `Idempotency-Key` is optional, not required. Its only job is to make retries safe:
* **With a key**: retry the same request (same key, same `batch_ids`) as many times as you want, like after a timeout, and you'll get back the original export job instead of a new one. Reuse the key with a *different* `batch_ids` set and you'll get `409`, since that's not a retry.
* **Without a key**: every request creates a new export job, including retries. Fine for one-off calls; risky if your client retries automatically.
We recommend a UUID v4, generated once per export attempt and reused across that attempt's retries — not a new one per HTTP call.
If your HTTP client already retries on timeout, generate the key before the first attempt and pass the same value through every retry it makes.
## Export Lifecycle
1. Queued: Export Job accepted; waiting for a worker to pick it up.
2. Running: A worker is generating the CSV.
3. Completed: `download_url` is set. Download it before the retention window closes.
4. Failed: Something went wrong — check `error`. Worker dispatch failures return `502` on create and mark the export job `failed` immediately; it's safe to retry.
5. Expired: The artifact aged past its 7-day retention window. `download_url` is `null` and `expired` is `true`.
| Status | `download_url` | `error` | `metadata` |
| ----------- | ------------------------ | ------------- | ------------------------------- |
| `queued` | `null` | `null` | `null` |
| `running` | `null` | `null` | `null` or partial |
| `completed` | signed URL (1h validity) | `null` | `rows_exported` + stage timings |
| `failed` | `null` | reason string | may include partial stats |
| `expired` | `null` | `null` | retained from `completed` |
## Polling & Downloading
Call `GET /exports/{export_id}` (or follow `status_url` from the create response) every few seconds. Don't poll faster than that.
Stop once `status` is `completed`, `failed`, or `expired`.
Call `GET /exports/{export_id}/download`. It returns `307` with a `Location` pointing at a short-lived signed S3 URL. Most HTTP clients (curl, `requests`, `fetch`) follow the redirect automatically, and the body that arrives is `text/csv`.
The signed URL from `/download` is valid for 1 hour. The underlying artifact is retained for 7 days; call `/download` again to get a fresh URL as long as the export hasn't expired.
Calling `/download` before `status` is `completed` returns `409`. Calling it after the 7-day retention window returns `410`.
## Status Response Fields
| Field | Description |
| --------------------------- | ------------------------------------------------------------------------------------- |
| `id` | Export identifier (UUID) |
| `status` | `queued`, `running`, `completed`, `failed`, or `expired` |
| `batch_ids` | Batch IDs included in this export |
| `batch_names` | Best-effort `{batch_id → name}` map; a batch is omitted if its name can't be resolved |
| `created_at` / `updated_at` | ISO-8601 timestamps |
| `status_url` | URL to poll this export's status |
| `download_url` | Download URL; present only while `status` is `completed` and unexpired |
| `error` | Failure reason, set when `status` is `failed` |
| `metadata` | Worker-reported stats: `rows_exported` plus per-stage timings |
| `expired` | `true` once the artifact has aged past its 7-day retention window |
This is the shape returned by the `202` on create, by **Get export status**, and by each element of **List exports**.
## Listing Exports
`GET /exports?status=&cursor=&limit=` returns `{ exports: [...], next_cursor }`, newest first.
| Param | Default | Description |
| -------- | ------- | ----------------------------------------------------------------------- |
| `status` | — | Filter by status: `queued`, `running`, `completed`, `failed`, `expired` |
| `cursor` | — | Opaque cursor from a previous page's `next_cursor` |
| `limit` | `50` | Max results per page (max `200`) |
`next_cursor` is `null` on the last page. Keep passing it back as `cursor` until then.
## CSV Columns
Every export has the same shape: `batch_id`, `batch_name`, `place_id`, `status`, then per-attribute columns — `{field}_original` (your inputs), `{field}_enriched` (the enriched value), `{field}_status`, plus confidence and reasoning columns. Columns that are blank across every row are dropped.
For what each attribute returns, see [Place Job Results](/guides/place-job-results).
## Errors
| Code | Meaning |
| ----- | --------------------------------------------------------------------------------------------------- |
| `404` | A `batch_id` isn't owned by the org, or the export doesn't exist |
| `409` | `Idempotency-Key` reused with a different `batch_ids` set, or `/download` called before `completed` |
| `410` | Export artifact has expired |
| `502` | Worker dispatch failed; the export job is marked `failed` — safe to retry |
## Using the Dashboard
Exports work the same way without writing any code.
On **Place Enrichment → Run Batches**, check one or more batches and click **Export N Batches**. A confirm dialog — "Export N batches (\~X jobs) as a single CSV. Large selections generate in the background…" — kicks off the same `POST /exports` under the hood.
* **Small exports** download instantly in the browser.
* **Large exports** show a "queued" toast with a **View** link to the **Exports** screen (sidebar → Exports, `/place-enrichment/exports`).
* The Exports screen lists background exports with status pills — Queued / Generating / Ready / Failed / Expired — and auto-polls until each one finishes. Ready rows get a **Download** button (a plain link that follows the `307` to S3); failed rows get **Retry**.
* Its subtitle states the rule plainly: "Background CSV exports, kept 7 days. Small exports download instantly and aren't listed here."
Idempotency is handled for you — the dashboard sends one key per export attempt.
## Best Practices
* **Send an Idempotency-Key for anything you might retry** — a UUID v4 per export attempt, reused across that attempt's retries, not generated per HTTP call.
* **Poll politely** — every few seconds is enough; the export runs as a background export job either way.
* **Download promptly** — the signed URL expires in 1 hour. Call `/download` again for a fresh one if you miss the window.
* **Check `metadata.rows_exported`** — confirms the export covered the rows you expected before you rely on the file.
## Next Steps
* [Batch Processing](/guides/batch-processing) - create the batches you're exporting
* [Place Job Results](/guides/place-job-results) - full schema of the enriched attributes behind each CSV column
# Upload Large Files
Source: https://docs.repromptai.com/guides/csv-upload
Upload and enrich large CSV files through the Reprompt dashboard.
Upload a CSV of places and enrich them in bulk — no code required. Files must be under **200 MB** and include a header row.
Go to **[Place Enrichment → Upload](https://app.repromptai.com/place-enrichment/upload-csv)** to get started.
## Map Your Columns
After uploading, map your CSV columns to Reprompt fields. The dashboard auto-detects columns where possible.
### Essential Fields
All five fields below are required for best results. You can technically omit either coordinates or address, but enrichment accuracy drops significantly — always provide both when possible.
| Field | Description |
| -------------- | ----------------------------------------------------------------------------- |
| `id` | Unique identifier for each place |
| `name` | Business or place name |
| `full_address` | Full street address as a single string (or map individual components instead) |
| `latitude` | Latitude coordinate |
| `longitude` | Longitude coordinate |
### Additional Options
Expand **Additional Options** to map extra columns. The more fields you map, the better your results.
| Field | Description |
| -------------- | --------------------- |
| `phone` | Phone number |
| `website` | Official website URL |
| `category` | Place category |
| `house` | House/building number |
| `street` | Street name |
| `city` | City |
| `postalCode` | Postal / zip code |
| `state` | State or province |
| `country_code` | ISO country code |
| `country` | Country name |
Map **every field you have**. Unmapped columns are ignored during enrichment, which reduces match quality.
## Preview and Import
After mapping, review the **Preview**, click **Select All**, and confirm the import. The platform automatically splits large files into batches of \~5,000 rows each.
## Run Enrichment
Select batches from the list, click **Enrich N batches of places...**, choose **Enrich Place**, and start processing.
## Files Over 200 MB
Split files exceeding 200 MB before uploading. You can use a tool like [`csv-split`](https://www.npmjs.com/package/csv-split) from npm, then upload each part separately.
## Best Practices
* **Map every column** — unmapped columns are ignored, reducing match quality.
* **Provide both address and coordinates** — this gives the best enrichment accuracy.
* **Use descriptive batch names** — name by geography, date, or purpose (e.g. "texas" or "Q1 2025 Store Locations").
* **Start with a sample** — upload 100–1,000 rows first to verify column mapping.
## Next Steps
* [Batch Processing](/guides/batch-processing) - Monitor batches, paginate results, and reprocess failures via the API
* [Place Job Results](/guides/place-job-results) - Understand the enrichment output schema
* [Troubleshooting 40x Errors](/guides/troubleshooting-40x) - Debug common API and upload errors
# Monthly Refresh
Source: https://docs.repromptai.com/guides/monthly-refresh
How place enrichment refreshes run and how to review what changed
## Overview
Monthly refreshes re-run enrichment for places you’ve marked, so you can detect changes over time. Refresh runs execute on the **9th of every month**.
Refresh behavior:
* By default, we refresh **only the attributes that were already enriched** for that place.
* If you have a custom agreement with Reprompt, we can scope refreshes to specific attributes (for example, only `open_closed_status`).
## 1) Mark places for refresh
To include places in the monthly refresh, use the batch actions menu in the UI:
Click the **Actions** button.
Then select **Mark for refresh** in the dropdown.
## 2) Check what changed
To see updates, list your refresh batches, then inspect the jobs inside each batch. For each place, compare the `job_metadata.last_enriched` timestamp (and, if needed, the output values) against your prior snapshot.
### List recent batches
Use this to find the batch IDs you want to review (especially the batches you marked for refresh).
Expect `batches[]` with `id`, `status`, `status_counts`, and `refresh` so you can pick the batch IDs to inspect.
[List batches API reference](https://docs.repromptai.com/api-reference/batches/list-batches)
```bash theme={null}
curl --request GET \
--url 'https://api.repromptai.com/v1/reprompt/place_enrichment/batches?limit=10' \
--header 'Authorization: Bearer YOUR_API_KEY'
```
### Fetch a batch to get its place IDs
Use this to see which place IDs are included in a specific batch.
Expect a `jobs` object with arrays by status; `jobs.completed` can be large, so you’ll typically sample or page through.
[Get batch status API reference](https://docs.repromptai.com/api-reference/batches/get-batch-status)
```bash theme={null}
curl --request GET \
--url 'https://api.repromptai.com/v1/reprompt/place_enrichment/batches/{batch_id}' \
--header 'Authorization: Bearer YOUR_API_KEY'
```
### Fetch a job by place ID
Use this to inspect the updated enrichment results for each place so you can scan for changes.
Expect `job_metadata.last_enriched` (timestamp with microseconds) plus `attribute_status` and `outputs` for validation.
[Get a single enrichment job API reference](https://docs.repromptai.com/api-reference/jobs/get-a-single-enrichment-job)
```bash theme={null}
curl --request GET \
--url 'https://api.repromptai.com/v1/reprompt/place_enrichment/jobs/{place_id}' \
--header 'Authorization: Bearer YOUR_API_KEY'
```
### Inspect `last_enriched`
Example response (trimmed). Focus on `job_metadata.last_enriched`:
```jsonc theme={null}
{
"place_id": "place_123",
"status": "completed",
"job_metadata": {
"attribute_status": {},
"last_enriched": "2023-11-07T05:31:56Z", // last refresh time
"enrichment_metadata": {},
"country_code": "US"
},
"inputs": {
"type": ""
},
"outputs": {},
"reasoning": {},
"confidence_scores": {
"open_closed_status": "VERY_HIGH",
"phone": "VERY_HIGH",
"website": "VERY_HIGH",
"address": "VERY_HIGH",
"categories": "VERY_HIGH",
"opening_hours": "VERY_HIGH",
"entity_type": "VERY_HIGH",
"name": "VERY_HIGH",
"parking_spaces": "VERY_HIGH",
"parking_spaces_total": "VERY_HIGH",
"parking_spaces_street": "VERY_HIGH",
"parking_spaces_shared": "VERY_HIGH",
"parking_spaces_dedicated": "VERY_HIGH",
"chain": "VERY_HIGH",
"tiktok": "VERY_HIGH",
"price_tier": "VERY_HIGH",
"approximate_user_reviews": "VERY_HIGH",
"menu": "VERY_HIGH",
"school_geofence": "VERY_HIGH"
}
}
```
Notes:
* **Key field**: `job_metadata.last_enriched` indicates the most recent enrichment timestamp for that place.
* A refresh can complete **without** changing `last_enriched`. That means the data matched the prior enrichment and **you are not charged** for that refresh.
* Use `job_metadata.last_enriched` to confirm a refresh ran (e.g., a timestamp on or after the 9th of the month).
* If you need a deeper diff, compare the `outputs` object to your stored snapshot.
# Place Status - Open/Closed
Source: https://docs.repromptai.com/guides/open-closed
Enrich whether a place is open, permanently closed, or has no discernible internet presence.
## Overview
Reprompt determines business status and returns a structured `open_closed_status` with:
* `status` (enum): One of `"Open"`, `"Closed"`, `"Temporarily Closed"`, or `"No Internet Presence"`
* `reasoning` (string): Explanation with referenced sources
* `confidence` (enum): `VERY_HIGH`, `HIGH`, `MEDIUM`, `LOW`, or `NONE`
## Status Values
```python theme={null}
class OpenClosedStatus(str, Enum):
NO_INTERNET_PRESENCE = "No Internet Presence"
OPEN = "Open"
CLOSED = "Closed"
TEMPORARILY_CLOSED = "Temporarily Closed"
```
## Usage Example
To enrich a place with open/closed status information:
```bash cURL theme={null}
curl -X POST \
'https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich' \
-H 'Authorization: Bearer {YOUR_API_KEY}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {
"place_id": "my_place_123",
"name": "Joe'\''s Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
},
"attributes": ["closed_permanently"]
}'
```
**Response:**
```json theme={null}
{
"place_id": "my_place_123",
"outputs": {
"closed_permanently": {
"status": "Open",
"confidence": "HIGH",
"reasoning": "Recent activity confirmed from multiple credible sources; business appears to be operating normally."
}
}
}
```
### Determining Status
#### No Internet Presence
* **Places are defined as having no internet presence if**:
* Web sources have no exact or near exact business name match and
* Web sources have no near partial address match tied to the business name
#### Permanently Closed vs Temporarily Closed vs Open
* **Permanently closed**: Reprompt will return Closed if there is evidence of:
* Explicit closure signals from official first-party web or social sources (Business website, business official social media page, etc.)
* Explicit closure signals from multiple corroborated unofficial web sources (public news articles, goverment web portals, public aggregator websites, etc.)
* Specifically for businesses with a customer-facing storefront: Lack of official web or social presence and lack of corroborated 3rd party sources will mark the business as permanently closed. For instance, a Joe's Pizza in New York City that has no official first-party presence and is only listed on MapQuest and Better Business Bureau from 2009 will be marked as permanently closed without an explicit signal, based on absense of information from up to date sources.
* **Temporarily Closed**: Requires official temporary closure signals from official web or social sources
* **Bias**: There is a high bar for marking a business as permanently closed. The agent will bias towards Open if there is sufficient evidence of existence and operation from up to date web sources.
Specific cases:
* **Minor name variations**: Slight variations in the name will be treated as the same place. For example, "Joe's Pizza" and "Joseph Hot Wings and Pizza" at the same address will be treated as the same place. A closure announcement of "Joe's Pizza" will impact "Joseph Hot Wings and Pizza"
* **Significant name variations**: If the name is significantly different, the agent will treat the business as a different place. For example, "Joe's Pizza" and "Mystic Pizza" at the same address will be treated as different places. A closure announcement of "Joe's Pizza" will not impact "Mystic Pizza"
#### Example cases
| Place | Status | Reasoning |
| ---------------------------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Joe's Pizza, 7 carmine st, new york, ny | Open | Joe's Pizza has a significant digital presence with an official first-party website (joespizzanyc.com) and official social media with posts in the last 6 months. They are mentioned by multiple news articles and listed on multiple review aggregator websites. The agent finds no evidence of closure or temporary closure. |
| Iza Ramen, 237 Fillmore St, San Francisco, CA | Closed | Iza Ramen has news articles mentioning closure of the business during COVID. The business has official social media with no mention of the closure. There is no evidence of reopening or that the closure is temporary. The agent marks the business as permanently closed. |
| Terry's Donuts, 712 steiner st, Seattle, WA | Closed | Terry's Donuts has no official web or social presence. It is not listed on review aggregator websites. It's only listed on Better Business Bureau from 2009. The agent marks the business as permanently closed without an explicit signal, based on absence of information from up to date sources. Special case: no recent digital presence. |
| Robertson Commercial Construction, 701 Power Line Rd, Winter Haven, FL | Open | Robertson Commercial Construction has an official website which lists its office address as 701 Power Line Rd, Winter Haven, FL, and a county filing from 2021. It has very little internet presence otherwise. The agent marks the business as open with medium confidence since this is not a customer-facing business. |
# Place Job Results
Source: https://docs.repromptai.com/guides/place-job-results
Understand the structure of job results returned by batch endpoints
## Overview
When you retrieve jobs from the batch endpoints, each job includes inputs, outputs, reasoning, and confidence scores. This guide explains those sections and provides a clean example.
* **Batch docs**: [Batch Processing](/guides/batch-processing)
* **API reference**: See the Place Enrichment Batch endpoints in the API reference for your version.
## Sections
* **Inputs**: What you submitted for a place. These are the fields we use to locate and enrich the place (e.g., name, coordinates, address, country).
* **Outputs**: The enriched attributes we found, such as website, phone, opening\_hours, categories, ratings, and review counts.
* **Reasoning**: Brief, structured notes explaining how each attribute was determined (when available).
* **Confidence scores**: A per-attribute confidence level reflecting the reliability of the result.
## Example Response
The example below removes internal processing metadata and focuses on what your application will typically use.
```json theme={null}
{
"jobs": [
{
"place_id": "place_123",
"status": "completed",
"job_metadata": {
"last_enriched": "2025-03-10T15:35:00Z",
"country_code": "US",
"attribute_status": {
"website": "RUN",
"phoneNumbers": "RUN",
"openingHours": "RUN",
"categories": "RUN"
}
},
"inputs": {
"id": "place_123",
"name": "Joe's Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014",
"country_code": "US"
},
"outputs": {
"website": "https://www.joespizzanyc.com",
"phone": null,
"opening_hours": { "Monday": "11:00-23:00", "Tuesday": "11:00-23:00" },
"categories": ["restaurant", "pizza"],
"average_rating": 4.5,
"review_count": 1200
},
"reasoning": {
"websites": "Structured reasoning…",
"phone": "No phone found on official site.",
"opening_hours": "Structured reasoning…",
"categories": "Structured reasoning…"
},
"confidence_scores": {
"website": "HIGH",
"phone": "LOW",
"opening_hours": "MEDIUM",
"categories": "HIGH"
}
}
],
"total": 1,
"limit": 10000,
"offset": 0
}
```
## Schemas
### Confidence Scores
Confidence levels indicate how reliable a given attribute is:
```python theme={null}
class ConfidenceScore(str, Enum):
VERY_HIGH = "VERY_HIGH"
HIGH = "HIGH"
MEDIUM = "MEDIUM"
LOW = "LOW"
NONE = "NONE"
```
* **VERY\_HIGH/HIGH**: Safe to use directly
* **MEDIUM**: Generally reliable; consider validation for critical use cases
* **LOW**: Use with caution; may require manual review
* **NONE**: No reliable data found
### Attribute Statuses
Each attribute can include a processing status in `job_metadata.attribute_status` to indicate how enrichment proceeded:
```ts theme={null}
export type AttributeStatus = 'RUN' | 'RUN_CONDITION_FAILED' | 'NOT_RUN' | 'ERROR'
```
* **RUN**: Enrichment was attempted (and completed); the attribute value may be present or null.
* **RUN\_CONDITION\_FAILED**: Skipped because preconditions were not met (e.g., missing inputs or failing filters).
* **NOT\_RUN**: Not attempted (e.g., disabled, out of scope, or limits).
* **ERROR**: Attempted but failed due to an error.
Attributes that commonly include a status entry include `website`, `phoneNumbers`, `openingHours`, and `categories`.
## Next Steps
* Submit a batch following the [Batch Processing](/guides/batch-processing) guide, then poll for completion and retrieve results.
* Use the `confidence_scores` and `attribute_status` to drive QA workflows or manual review where needed.
## Attribute Outputs
Types: `string` | `number` | `list of strings`
**Core Attributes**
`closed_permanently` attribute returns:
* open\_closed\_status `string`
* open\_closed\_status\_confidence\_score `string`
`address` attribute returns:
* `address` `string`
* `address_localized` `string`
`categories` attribute returns:
* `categories` `list of strings`
`coordinates` attribute returns:
* coordinates `string`
* coordinates\_distance `number`
`websites` attribute returns:
* website `string`
`email_address` attribute returns:
* email `string`
`phoneNumbers` attribute returns:
* phone `string`
* phone\_additional `list of strings`
`openingHours` attribute returns:
* opening\_hours `list of strings`
* opening\_hours\_grouped\_by\_hours `list of strings`
* is\_open\_24h `string`
`names` attribute returns:
* name `string`
* multilingual\_names `list of strings`
* alt\_name `string`
* official\_name `string`
* brand\_name `string`
**Rich Attributes**
`menu` attribute returns:
* menu\_urls `list of strings`
* menu\_url\_official `string`
* menu\_content `string`
* menu\_images `list of strings`
`price_tier` attribute returns:
* price\_tier `string`
* average\_price `number`
* currency `string`
`user_reviews` attribute returns:
* user\_review\_count `number`
* user\_average\_rating `number`
* user\_wilson\_score `number`
* user\_popularity `number`
* user\_review\_summary `string`
* user\_summary `string`
`approximate_user_reviews` attribute returns:
* approximate\_review\_count `number`
* approximate\_average\_rating `number`
`chain` attribute returns:
* chain\_id `string`
* chain\_name `string`
* chain\_domains `list of strings`
* alternative\_names `list of strings`
* chain\_wikipedia\_url `string`
* number\_of\_locations `number`
* logo\_url `string`
`reprompt_id` attribute returns:
* reprompt\_id `string`
`naics` attribute returns:
* naics\_code `string`
* naics\_description `string`
`merchant` attribute returns:
* merchant\_category\_code `string`
* mcc\_description `string`
* merchant\_category\_group `string`
* merchant\_super\_industry `string`
`name_translations` attribute returns:
* name\_translations `list of strings`
`socialHandles` attribute returns:
* instagram `string`
* facebook `string`
* tiktok `string`
`tiktok` attribute returns:
* tiktok: string
`social_media_profile` attribute returns:
* facebook\_followers: number
* facebook\_likes `number`
* facebook\_page\_id `string`
* facebook\_bio `string`
`website_traffic` attribute returns:
* website\_traffic\_monthly\_visits `number`
`parking_spaces` attribute returns:
* parking\_spaces\_total `number`
* parking\_spaces\_street `number`
* parking\_spaces\_shared `number`
* parking\_spaces\_dedicated `number`
* parking\_spaces\_image\_url `string`
`one_line_summary` attribute returns:
* one\_line\_summary `string`
`geometry` attribute returns:
* buildings\_geojson `string`
`located_within` attribute returns:
* located\_within\_name `string`
* located\_within\_type `string`
* located\_within\_floor\_or\_level `string`
`storefrontImages` attribute returns:
* storefront\_images `list of strings`
`place_existence` attribute returns:
* entity\_type `string`
* digital\_footprint `string`
* place\_definition `string`
* place\_reality `string`
# Quickstart
Source: https://docs.repromptai.com/guides/quickstart
Supercharge place data with Reprompt
## 1. Enrich place data
If you already have place data, you can enrich it with over 40 attributes using Reprompt
* [Live Enrichment API](#2-live-enrichment)
* [Batch Processing API](#5-batch-processing)
**Don't have place data yet?** You can experiment with csv data and custom AI attributes in our [Workbooks](https://app.repromptai.com/workbooks).
***
## 2. Live Enrichment
Let's enrich a single place with basic information. The `inputs` object requires a place **name** along with either **coordinates (latitude/longitude)** or an **address**.
```bash cURL theme={null}
curl -X POST \
'https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich' \
-H 'Authorization: Bearer {YOUR_API_KEY}' \
-H 'Content-Type: application/json' \
-d '{
"place_id": "my_place_123",
"inputs": {
"name": "Joe'\''s Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
},
"attributes": ["websites", "phoneNumbers", "openingHours", "closed_permanently"]
}'
```
```python Python theme={null}
import requests
url = "https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich"
headers = {
"Authorization": "Bearer {YOUR_API_KEY}",
"Content-Type": "application/json"
}
data = {
"place_id": "my_place_123",
"inputs": {
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
},
"attributes": ["websites", "phoneNumbers", "openingHours", "closed_permanently"]
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich', {
method: 'POST',
headers: {
'Authorization': 'Bearer {YOUR_API_KEY}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
place_id: "my_place_123",
inputs: {
name: "Joes Pizza",
latitude: 40.7359,
longitude: -73.9911,
full_address: "7 Carmine St, New York, NY 10014"
},
attributes: ["websites", "phoneNumbers", "openingHours", "closed_permanently"]
})
});
const result = await response.json();
console.log(result);
```
Replace `{org_slug}` with your actual organization slug. The API key variable will be automatically populated.
**Include a `place_id`**: The `place_id` field is required at the top level of your request (alongside `inputs`, not inside it). We recommend providing your own stable identifier (like your database ID). This makes it easy to join enriched results back to your data.
### Input Flexibility
The `inputs` object accepts different combinations:
**Option 1: Name + Coordinates**
```json theme={null}
{
"place_id": "my_place_123",
"inputs": {
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911
}
}
```
**Option 2: Name + Address**
```json theme={null}
{
"place_id": "my_place_123",
"inputs": {
"name": "Joes Pizza",
"full_address": "7 Carmine St, New York, NY 10014"
}
}
```
**Option 3: Name + Address + Coordinates (Most accurate)**
```json theme={null}
{
"place_id": "my_place_123",
"inputs": {
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
}
}
```
Providing more input fields (e.g. `full_address` together with coordinates, or `type`, `country_code`, `website`) helps our systems resolve and enrich the place more accurately. For the full list of supported fields and guidance, see [Input Place Schema](/schemas/schemas#input-place-schema).
***
## 3. Understanding the Response
The API will return enriched data about the place, including your `place_id` for easy joining:
```json theme={null}
{
"place_id": "my_place_123",
"status": "completed",
"inputs": {
"name": "Joe's Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
},
"outputs": {
"websites": ["https://www.joespizzanyc.com"],
"phoneNumbers": ["+12122555803"],
"openingHours": {
"monday": "10:00-2:00",
"tuesday": "10:00-2:00"
},
"closed_permanently": false
},
"job_metadata": {
"last_enriched": "2024-03-15T10:35:00Z",
"attribute_status": {
"websites": "RUN",
"phoneNumbers": "RUN",
"openingHours": "RUN",
"closed_permanently": "RUN"
}
}
}
```
## 4. Available Attributes
Specify exactly which attributes you want to enrich using the `attributes` array. Common attributes include:
| Attribute | Description |
| -------------------- | ------------------------------------------------ |
| `websites` | Business website URLs |
| `phoneNumbers` | Phone numbers |
| `socialHandles` | Social media handles (Instagram, Facebook, etc.) |
| `closed_permanently` | Whether the business is permanently closed |
| `price_tier` | Price range (e.g., \$, \$\$, \$\$\$) |
| `categories` | Business categories |
| `openingHours` | Opening hours |
| `names` | Alternative names for the business |
| `address` | Address |
You can see the entire list of attributes by calling the [Enrichment Attributes](/api-reference/attributes/get-enrichment-attributes) endpoint.
***
## 5. Batch Processing
For multiple places, use batch processing for asynchronous enrichment:
```json theme={null}
{
"batch_name": "NYC Restaurants Batch",
"attributes": ["websites", "phoneNumbers", "openingHours", "closed_permanently"],
"jobs": [
{
"place_id": "my_db_id_456",
"inputs": {
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014"
}
},
{
"place_id": "my_db_id_789",
"inputs": {
"name": "Tony's Deli",
"latitude": 40.7505,
"longitude": -73.9934,
"full_address": "123 Main St, New York, NY 10001"
}
}
]
}
```
Submit this to the `/place_enrichment/batches` endpoint, then track progress and retrieve results using the returned batch ID. Each result will include the `place_id` you provided for easy matching back to your database.
Learn more in our [Batch Processing Guide](/guides/batch-processing).
***
## 6. Next Steps
Now that you've made your first API call, explore more:
* **[API Reference](/api-reference)** - Complete endpoint documentation
* **[Batch Processing](/guides/batch-processing)** - Process multiple places efficiently
# Search and Ask
Source: https://docs.repromptai.com/guides/search-and-ask
Retrieve normalized web results or get a fast, source-backed answer.
## Overview
Reprompt offers two small, complementary web endpoints:
* **Search** retrieves normalized web search results for a query. Use it when your application or agent needs the results themselves.
* **Ask** retrieves search results and produces a fast, single-hop narrative answer grounded in those results. Use it when your user needs a concise answer with sources.
Both endpoints accept the same minimal body. There are no filters, modes, or structured search inputs at launch.
`Ask` is a fast grounded-answer endpoint, not a deep-research workflow. It does not perform multi-step research or replace source review for high-stakes decisions.
## Authentication and base URL
Create an API key in [Organization Settings → API Keys](https://app.repromptai.com/organization), then send it as a bearer token. Reprompt resolves the organization from the authenticated API key, so no organization identifier is required in the URL.
```bash theme={null}
https://api.repromptai.com/v1
```
## Search
Send a natural-language query to `POST /search`. The response is a stable, normalized result list; it intentionally does not expose the underlying search-provider response.
```bash cURL theme={null}
curl --request POST \
--url 'https://api.repromptai.com/v1/search' \
--header 'Authorization: Bearer {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"query": "What is the difference between a web search API and a research agent?"
}'
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.repromptai.com/v1/search",
headers={
"Authorization": "Bearer {YOUR_API_KEY}",
"Content-Type": "application/json",
},
json={
"query": "What is the difference between a web search API and a research agent?"
},
)
response.raise_for_status()
print(response.json())
```
```javascript JavaScript theme={null}
const response = await fetch(
'https://api.repromptai.com/v1/search',
{
method: 'POST',
headers: {
Authorization: 'Bearer {YOUR_API_KEY}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'What is the difference between a web search API and a research agent?'
})
}
);
if (!response.ok) throw new Error(`Search failed: ${response.status}`);
console.log(await response.json());
```
### Search response
```json theme={null}
{
"query": "What is the difference between a web search API and a research agent?",
"answer_box": {
"answer": "A web search API retrieves ranked web results.",
"url": "https://example.com/search-apis"
},
"results": [
{
"title": "Example result title",
"url": "https://example.com/search-vs-research",
"snippet": "A short excerpt describing the result.",
"position": 1,
"date": "2026-07-25"
}
]
}
```
Each item in `results` has a stable normalized shape:
| Field | Type | Description |
| ---------- | ---------------- | -------------------------------------------- |
| `title` | string | Result title. |
| `url` | string | Canonical result URL. |
| `snippet` | string, optional | Search-result excerpt. |
| `position` | integer | One-based rank in the returned result set. |
| `date` | string, optional | Date supplied by the result, when available. |
The `results` array can be empty when no results match the query.
When the search provider supplies them, the response can also include:
* `answer_box` — a direct answer or featured snippet with its source URL.
* `knowledge_graph` — entity information such as a title, type, description, website, and scalar facts.
These objects are optional. Build agent logic around `results` unless it explicitly benefits from enriched search features.
## Ask
Send the same query to `POST /ask` to receive a concise narrative answer plus the source objects used to ground it. Reprompt uses DeepSeek V4 Flash through OpenRouter for this endpoint.
```bash cURL theme={null}
curl --request POST \
--url 'https://api.repromptai.com/v1/ask' \
--header 'Authorization: Bearer {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"query": "What is the difference between a web search API and a research agent?"
}'
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.repromptai.com/v1/ask",
headers={
"Authorization": "Bearer {YOUR_API_KEY}",
"Content-Type": "application/json",
},
json={
"query": "What is the difference between a web search API and a research agent?"
},
)
response.raise_for_status()
answer = response.json()
print(answer["answer"])
for source in answer["sources"]:
print(source["title"], source["url"])
```
```javascript JavaScript theme={null}
const response = await fetch(
'https://api.repromptai.com/v1/ask',
{
method: 'POST',
headers: {
Authorization: 'Bearer {YOUR_API_KEY}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'What is the difference between a web search API and a research agent?'
})
}
);
if (!response.ok) throw new Error(`Ask failed: ${response.status}`);
const { answer, sources } = await response.json();
console.log(answer, sources);
```
### Ask response
```json theme={null}
{
"query": "What is the difference between a web search API and a research agent?",
"answer": "A web search API returns relevant documents for a query. A research agent typically uses search as one step in a larger, multi-step process that evaluates sources and synthesizes a response. [1]",
"sources": [
{
"title": "Example result title",
"url": "https://example.com/search-vs-research",
"snippet": "A short excerpt describing the result.",
"position": 1,
"date": "2026-07-25"
}
]
}
```
`sources` uses the same normalized source-object shape as `Search` results. Render the source URLs alongside the answer so people can inspect the evidence themselves.
## Errors and retries
Both endpoints return JSON errors. Handle these status codes:
| Status | Meaning | What to do |
| ------ | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `401` | The API key is missing, invalid, or revoked. | Create or use an active API key. |
| `403` | The authenticated account cannot access the endpoint. | Verify the feature is enabled for the account. |
| `422` | The request is invalid, including a missing, blank, or extra input field; `Ask` also uses this when no web results are available. | Correct the request; do not retry unchanged input. |
| `429` | The account has exceeded a rate or usage limit. | Retry with exponential backoff and respect `Retry-After` when present. |
| `502` | `Ask` could not produce a citation-backed answer from the retrieved sources. | Retry once or reformulate the query. |
| `503` | A search or answer provider is temporarily unavailable. | Retry idempotently with exponential backoff and respect `Retry-After`. |
For authentication help, see [Troubleshooting Authentication & 40x Errors](/guides/troubleshooting-40x).
# Troubleshooting Authentication & 40x Errors
Source: https://docs.repromptai.com/guides/troubleshooting-40x
How to diagnose and fix 401, 403, and 404 errors in your API requests
## Overview
This guide helps you troubleshoot common authentication and request errors when using the Reprompt API. Most 40x errors are related to API keys, organization slugs, or request formatting.
## 401 Unauthorized
A `401` error means your API key is invalid, missing, or revoked.
### Common Causes
1. **Missing or malformed Authorization header**
2. **Revoked API key**
3. **Expired API key**
4. **Copy-paste errors** (extra spaces, truncated key)
### How to Fix
Ensure you're including the header in the correct format:
```bash theme={null}
Authorization: Bearer YOUR_API_KEY_HERE
```
**Common mistakes:**
* Missing the word `Bearer`
* Extra spaces before/after the key
* Using single quotes instead of the actual key value
Check if your key has been revoked:
1. Go to [Organization Settings → API Keys](https://app.repromptai.com/organization)
2. Click **"Show revoked keys"** to see if your key was disabled
3. If revoked, generate a new API key
If your key is revoked or you suspect it's compromised:
1. Navigate to [Organization Settings](https://app.repromptai.com/organization)
2. Go to the **API Keys** section
3. Click **"Create new API key"**
4. Copy the new key immediately (it won't be shown again)
5. Update your application with the new key
***
## 403 Forbidden
A `403` error means your API key is valid, but you don't have permission to access the requested resource.
### Common Causes
1. **Accessing another organization's resources** - Using an org slug that doesn't match your API key
2. **Insufficient permissions** - Your API key doesn't have access to the specific resource or endpoint
### How to Fix
Ensure you're using the correct org slug for your API key:
Check that the `{org_slug}` in your URL matches your organization
***
## 404 Not Found
A `404` error means the API endpoint doesn't exist, usually due to an incorrect URL or org slug.
### Common Causes
1. **Incorrect organization slug** in the URL
2. **Typo in the endpoint path**
3. **Wrong API version** (using V1 endpoint format with V2 base URL or vice versa)
4. **Invalid batch ID or resource ID** in the path
### How to Fix
Double-check your org slug is correct:
```bash theme={null}
# ❌ Wrong
https://api.repromptai.com/v1/wrong-slug/place_enrichment/enrich
# ✅ Correct (replace {org_slug} with your actual org slug)
https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich
```
Find your org slug in the [Dashboard URL](https://app.repromptai.com/organization) when logged in.
Ensure you're using the correct endpoint path. Common endpoints include:
**V1 Endpoints (with org slug):**
* `https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich` - Single place enrichment
* `https://api.repromptai.com/v1/{org_slug}/place_enrichment/batches` - Create/list batches
* `https://api.repromptai.com/v1/{org_slug}/place_enrichment/batches/{batch_id}` - Get batch status
* `https://api.repromptai.com/v1/{org_slug}/place_enrichment/jobs` - Get job results
**V2 Endpoints (no org slug):**
* `https://api.reprompt.io/v2/enrich` - Single place enrichment
* `https://api.reprompt.io/v2/attributes` - List available attributes
Cross-reference your request with the [API Reference](https://docs.repromptai.com/):
1. Check the correct HTTP method (GET, POST, etc.)
2. Verify the endpoint path matches the documentation
3. Ensure required path parameters (like `{batch_id}`) are valid
4. Confirm you're using the right API version
Try the basic example from the [Quickstart guide](/guides/quickstart) to verify your configuration:
```bash theme={null}
curl -X POST \
'https://api.repromptai.com/v1/{org_slug}/place_enrichment/enrich' \
-H 'Authorization: Bearer {YOUR_API_KEY}' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {
"name": "Joe'\''s Pizza",
"latitude": 40.7359,
"longitude": -73.9911
},
"attributes": ["websites"]
}'
```
***
## Quick Reference Table
| Error Code | Meaning | Primary Cause | Quick Fix |
| ---------- | ------------ | -------------------------------- | ----------------------------------------------------------------- |
| **401** | Unauthorized | Invalid/revoked API key | [Check API key status →](https://app.repromptai.com/organization) |
| **403** | Forbidden | Accessing unauthorized resources | Verify org slug matches API key |
| **404** | Not Found | Wrong URL or org slug | Verify org slug and endpoint path |
***
## Related Guides
* [Quickstart](/guides/quickstart) - Basic API usage
* [Batch Processing](/guides/batch-processing) - Batch endpoint details
* [Agents in API](/guides/agents-in-api) - Using custom agents via API
# Schemas
Source: https://docs.repromptai.com/schemas/schemas
Data structures and enums used in the Reprompt API
## Input Place Schema
```python theme={null}
{
# Required
"name": str, # Business name in local language
"latitude": float, # -90 to 90
"longitude": float, # -180 to 180
# OR
"full_address": str, # Complete address including city/country/postal code
# Tracking (optional but encouraged)
place_id: str, # Your internal stable identifier for the place to be used to join on later
# Optional but increase accuracy
"type": str, # Primary category of the place
# Address subparts
"street": str,
"house": str, # Building number
"city": str,
"state": str,
"postalCode": str,
# Location metadata
"wkt_geometry": str, # Alternative to lat/lon, uses (lon, lat) order
"country": str,
"country_code": str, # ISO 3166-1 alpha-2 (e.g., "US", "GB")
# Enrichment hints
"website": str, # Will be validated/corrected. Better to provide even if wrong
"phone": str, # International format preferred
"type": str, # Primary category (helps disambiguation)
"opening_hours": dict,
}
```
## Provide a stable identifier with place\_id
We encourage you to provide a stable identifier for the place with the `place_id` field. A place\_id is returned with every API call as the place's primary key.
If you don't provide a `place_id`, we will automatically generate a UUID for you.
## Field Priority
**Critical for accuracy:**
1. `name` (required)
2. `latitude` + `longitude` OR `full_address`
3. `full_address` (when combined with coordinates)
**Helpful for disambiguation:**
* `type` - Essential for places like "Hotel Bar" vs "Hotel"
* `website` - Preferred source even if incorrect
* `country_code` - Inferred from coordinates if not provided
## Examples
### Minimal (Name + Coordinates)
```json theme={null}
{
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911
}
```
### Minimal (Name + Address)
```json theme={null}
{
"name": "Joes Pizza",
"full_address": "7 Carmine St, New York, NY 10014"
}
```
### Recommended (All key fields)
```json theme={null}
{
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014",
"type": "restaurant",
"country_code": "US"
}
```
### Complete (Maximum accuracy)
```json theme={null}
{
"id": "place_123",
"name": "Joes Pizza",
"latitude": 40.7359,
"longitude": -73.9911,
"full_address": "7 Carmine St, New York, NY 10014",
"street": "Carmine St",
"house": "7",
"city": "New York",
"state": "NY",
"postalCode": "10014",
"country": "United States",
"country_code": "US",
"type": "restaurant",
"website": "http://www.joespizzanyc.com",
"phone": "+12122555803"
}
```
***
## Confidence Scores
Confidence scores indicate how reliable an enrichment result is based on the quality and quantity of sources found.
```python theme={null}
class ConfidenceScore(str, Enum):
VERY_HIGH = "VERY_HIGH"
HIGH = "HIGH"
MEDIUM = "MEDIUM"
LOW = "LOW"
NONE = "NONE"
```
### Confidence Levels
| Level | Description | When Used |
| ----------- | ------------------- | ---------------------------------------------------------------- |
| `VERY_HIGH` | Extremely reliable | Multiple authoritative sources, recent data, high source quality |
| `HIGH` | Very reliable | Strong evidence from credible sources, good recency |
| `MEDIUM` | Moderately reliable | Reasonable evidence with some uncertainty or older sources |
| `LOW` | Less reliable | Ambiguous, conflicting, or weak signals |
| `NONE` | No confidence | No reliable sources found or unable to determine |
### Best Practices
* **VERY\_HIGH/HIGH**: Safe to use directly in production
* **MEDIUM**: Generally reliable, consider validation for critical use cases
* **LOW**: Use with caution, may require manual review
* **NONE**: No reliable data found, consider alternative sources
***
## Open/Closed Status
```python theme={null}
class OpenClosedStatus(str, Enum):
NO_INTERNET_PRESENCE = "No Internet Presence"
OPEN = "Open"
CLOSED = "Closed"
TEMPORARILY_CLOSED = "Temporarily Closed"
```
### Status Definitions
* **Open**: Recent, credible evidence the business is operating
* **Closed**: Explicit closure signals from credible sources
* **Temporarily Closed**: Business appears temporarily closed but may reopen
* **No Internet Presence**: No credible reference for the exact name with plausible location context