# Instagram Locations Search | $2.25/1K Places + $0.004/Search (`publicsignallabs/instagram-locations-search`) Actor

Find cafés, restaurants, shops and other places by name or GPS coordinates. Build downloadable place lists for local business research and venue discovery, with Instagram location links where available. No Instagram login required.

- **URL**: https://apify.com/publicsignallabs/instagram-locations-search.md
- **Developed by:** [Public Signal Labs](https://apify.com/publicsignallabs) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.25 / 1,000 place candidates

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Locations Search | $2.25/1K Places + $0.004/Search

**Turn place searches into a ready-to-use research list.** Find cafés, restaurants, shops and other venues by name or GPS coordinates, and export the available place details for analysis, prospecting or planning.

Where an Instagram location is available, use its link to explore location-tagged content—or pass it to our Instagram Location Posts Scraper to collect posts. No Instagram login or technical setup required.

### Quick start

Basic place search by name:

```json
{
  "searches": ["Berlin", {"query": "coffee Berlin"}],
  "maxResults": 100,
  "enrichPlaces": false
}
```

Search by GPS coordinates with matching place enrichment:

```json
{
  "searches": [{"latitude": 52.52, "longitude": 13.405}],
  "maxResults": 100,
  "enrichPlaces": true
}
```

`enrichPlaces` is disabled by default and is available to paying users only.

### Input

```json
{
  "searches": ["Berlin", {"query": "coffee Berlin"}, {"latitude": 52.52, "longitude": 13.405}],
  "maxResults": 100,
  "enrichPlaces": false
}
```

| Field | Contract |
| --- | --- |
| `searches` | Required array of 1–50 inputs. Each is a name string, an object containing only `query`, or an object containing only `latitude` and `longitude`. Names contain 1–200 characters. Latitude is −90…90; longitude is −180…180; both must be finite numbers. |
| `maxResults` | Integer 1–1,000, default 100; run-wide unique saved-place cap. |
| `enrichPlaces` | Boolean, default false. Paying users can select matching place lookups for candidates with usable Instagram IDs. |

Equivalent names (normalized whitespace, case-insensitive) and identical coordinate pairs are searched once. All original input indexes remain in provenance. Name and GPS modes may be combined; conflicting properties, unsupported fields and invalid limits are rejected before extraction or FREE admission. There is one search response per unique input, no implicit pagination, alternate-route fallback or automatic paid retry.

### Pricing

| Event | USD price | Charged when |
| --- | ---: | --- |
| `place-candidate` — primary | $0.00225/place ($2.25/1,000) | A unique final place row is confirmed saved. |
| `location-search` | $0.004/search | A valid search completes, including valid empty and duplicate-only results. |
| `place-enrichment` | $0.004/place | Selected matching lookup adds facts that are delivered with a confirmed saved place. Copied facts do not incur this fee. |
| `apify-actor-start` | $0.00005/run at ≤1 GB | Automatic platform start event; never charged manually. |

Unavailable, failed or malformed searches/lookups are not charged as successful work. No additional default-dataset-item event is configured. Actual confirmed event counts and total are recorded in `OUTPUT`; the total includes the platform start allowance for cloud paying runs. A selected enrichment lookup is not a guarantee that any additional facts exist. Search fees can apply even if a delivery cap prevents saving additional candidates.

Example: 100 unique saved places from five completed searches, enrichment off, is **$0.24505** including one start. If 20 saved places receive matching incremental enrichment, the total is **$0.32505**. These are arithmetic examples, not promised yields.

### FREE demo

Eligible nonpaying accounts can use five admitted runs per Actor per UTC month. Each run allows one unique search, at most ten places, no enrichment and one extraction attempt. Requested `maxResults` is capped at ten. Monthly admission uses an atomic account-scoped allowance; a run that aborts or is resurrected cannot acquire another allowance or replay extraction. Missing identity, unavailable quota verification or missing quota configuration fails closed. Paying users bypass the demo allowance, not result, request or spending caps. Store Pricing determines the applicable invoice behavior.

### Dataset and observation quality

Some results—particularly GPS searches—do not have an associated Instagram location. These places remain in your results, but their Instagram ID and link fields are empty. Results reflect the selected searches at extraction time; this is not an exhaustive geographic directory or verified venue database.

The default dataset contains one final row per stable Instagram identity or a namespaced external identity. Equal names alone never deduplicate candidates. A matching external identity can connect an external-only candidate to an observed Instagram identity; conflicting observed Instagram IDs remain separate. First-discovered row order is deterministic. Provenance is merged before append-only persistence.

**Enrichment required?** “No” means the field is available from the search result or calculated locally; optional facts can still be empty. `enrichPlaces=true` can add or update matching place details, but does not guarantee additional data. It cannot create an Instagram ID for an external-only result.

| Fields | Meaning / nullability | Enrichment required? |
| --- | --- | --- |
| `id`, `location_id`, `location_url` | Matching Instagram identity and canonical `/explore/locations/<id>/` link, or null for external-only candidates. `id` is the same as `location_id`. | No. |
| `name` | Required observed place name. | No; `enrichPlaces` may update it. |
| `external_place_id`, `external_place_source` | Distinct external identity and its namespace; nullable. Never substituted for an Instagram ID. | No; `enrichPlaces` may add or update these facts. |
| `latitude`, `longitude`, `coordinate_status` | Supplied numeric coordinates or null. `reported` means search-reported, `query_echo` means the GPS search returned the input coordinates verbatim, and `lookup_reported` means coordinates were returned by a selected matching lookup. None is independent venue verification. | No for search coordinates; `lookup_reported` requires `enrichPlaces`. |
| `address`, `city`, `postal_code` | Nullable supplied facts; a distance-only search label is not represented as a street address. | Optional — `enrichPlaces` can add or update them if the search did not supply them. |
| `category`, `description`, `phone`, `website`, `opening_hours` | Nullable supplied facts. Hours retain the supplied object, array or string shape. Contacts and hours are not guaranteed by enrichment; absent and empty optional facts remain null. | Optional — `enrichPlaces` can add or update them; they may already be in the search result. |
| `is_private`, `is_restricted` | Observed boolean flags or null. Flags alone do not exclude matching rows or selected retrieval. | No; `enrichPlaces` may add or update observed flags. |
| `source_inputs`, `matches` | Original input indexes and normalized search values; each match includes its observed 1-based rank and applicable distance. Only checked searches appear in row provenance. | No; distances may be recalculated using enriched coordinates. |
| `match_rank`, `match_type`, `distance_meters` | First-observed rank/type. Distance is local great-circle distance using supplied coordinates, not driving distance or a relevance guarantee. It is null for absent coordinates, name-only matches and GPS query echoes. | No; `enrichPlaces` may supply coordinates needed to calculate a distance. |
| `fetched_at` | Fixed run observation time in ISO 8601 format. | No. |
| `enrichment_status` | `not_requested`, `succeeded`, `not_available`, or `failed`. Basic facts survive a missing or failed lookup. | No — reports `not_requested` when enrichment is off. |
| `enrichment_incremental`, `enrichment_error` | Optional indication that delivered facts changed, and a sanitized lookup/limit reason. An unchanged matching lookup has `enrichment_incremental=false`. | Yes — describe selected `enrichPlaces` work; absent when not applicable. |

Search results may be geographically surprising, especially GPS results. A reported coordinate or zero/short calculated distance is not proof that a venue is nearby. GPS query echoes have no derived distance. Do not send external-only IDs to the Location Posts Actor or fabricate links from them.

### Limits and outcomes

Normalized final rows are buffered run-wide, bounded by 1,000 places and 16 MiB of serialized normalized data. No raw responses are retained in the final buffer. On result, budget or buffer limits, the confirmed affordable prefix is delivered with only observed provenance; unvisited searches are recorded as `not_checked`. Runtime request limits are finite; no uncertain request is replayed.

Reaching `maxResults` reports `stopReason: "item_limit"` and a partial outcome even when the run contains only one search; a capped prefix is not an exhaustive completion.

`OUTPUT` contains the terminal outcome, delivered count, stop reason, per-search `succeeded`, `empty`, `not_available`, `failed`, `limit_reached` or `not_checked` states, and confirmed billing totals. Each `sources` entry reports `inputIndex`, `sourceInputs` (with `inputIndex` and `matchType` per submitted input), `matchedCount`, an optional sanitized `error`, and a limit `stopReason` for skipped or budget-blocked searches. `AUDIT` contains extraction/deduplication, delivery/billing counts, duration, buffer peak and reconciliation. Valid empty, unavailable and partial/limited extraction outcomes finish successfully and remain distinguishable; a source that could not be checked is never claimed to be empty. Mechanical/internal/configuration failures remain failed runs. Interrupted delivery or charging can require reconciliation rather than a speculative replay.

This Actor does not retrieve location posts, Google ratings/reviews, map filters, durable asset downloads or verified complete contact/opening-hours schedules. Use the separate Location Posts Actor only with observed usable Instagram location IDs.

### API and CLI use

Call the Actor through the standard Apify Actor Runs API. Read place rows from the default dataset and reconciliation metadata from `OUTPUT` and `AUDIT`.

```bash
apify actors call publicsignallabs/instagram-locations-search \
  --input '{"searches":["Berlin"],"maxResults":100,"enrichPlaces":false}' \
  --output-dataset
```

The Actor also works with the Apify JavaScript and Python clients, REST API, schedules, webhooks, and platform integrations.

### Responsible use

Collect and use public data only where you have a lawful purpose. Respect privacy, intellectual-property rights, platform rules, anti-spam requirements, and applicable data-protection law. Minimize retained data, secure exports, honor deletion obligations, and do not use unverified contact fields for unlawful or deceptive outreach.

This Actor is unofficial and is not affiliated with or endorsed by Instagram or Meta.

### Support

Use the **Issues** tab on this Actor's Apify page. Include the run ID, input shape with private values removed, expected result, and observed result. Never include API tokens, cookies, credentials, personal contact values, or other private data.

# Actor input Schema

## `searches` (type: `array`):

Up to 50 inputs: name strings, {query: name}, or {latitude: number, longitude: number}. Equivalent inputs are searched once.

## `maxResults` (type: `integer`):

Run-wide unique place limit. FREE runs are capped at 10.

## `enrichPlaces` (type: `boolean`):

Paying users only. Look up matching usable Instagram IDs. Charge only incremental facts delivered with saved places; contacts and hours may remain null.

## Actor input object example

```json
{
  "searches": [
    "Berlin"
  ],
  "maxResults": 100,
  "enrichPlaces": false
}
```

# Actor output Schema

## `places` (type: `string`):

Unique final place rows from the default dataset, ready for preview or export.

## `summary` (type: `string`):

Run status, stop reason, per-search outcomes, delivered count, and confirmed billing totals.

## `audit` (type: `string`):

Aggregate extraction, deduplication, delivery, billing, duration, and buffer metrics.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searches": [
        "Berlin"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("publicsignallabs/instagram-locations-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searches": ["Berlin"] }

# Run the Actor and wait for it to finish
run = client.actor("publicsignallabs/instagram-locations-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searches": [
    "Berlin"
  ]
}' |
apify call publicsignallabs/instagram-locations-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,publicsignallabs/instagram-locations-search"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ddAKwLQY2iZUeCELV/builds/HjwHVXcwWSlDWS7IR/openapi.json
