Load any Apify Actor's results into LlamaIndex

Install llama-index-readers-apify and call ApifyActor(token).load_data(actor_id=..., run_input=..., dataset_mapping_function=...). The mapping function turns each record into a Document, with the record's text and its URL as metadata, ready for an index.

Route: document loader. Install: pip install apify-client llama-index-core llama-index-readers-apify

Working snippets

Each one is run against the current package before the site publishes it (with a stub Apify API, so nothing is billed). Every Actor page has the same snippet for its own Actor and input, under "In an agent framework".

Install: pip install apify-client llama-index-core llama-index-readers-apify

Google Maps

import json
import os

from llama_index.core import Document
from llama_index.readers.apify import ApifyActor

reader = ApifyActor(os.environ["APIFY_TOKEN"])
documents = reader.load_data(
    actor_id="vexaloom-labs/google-maps-business-lead-finder-with-email",
    run_input={
    "mode": "searchPlaces",
    "searchQueries": [
        "coffee shops in Austin TX",
    ],
    "maxPlacesPerSearch": 3,
    "language": "en",
    "extractEmailsFromWebsite": True,
    "maxEmailsPerWebsite": 5,
    "maxContactPagesPerWebsite": 2,
    "onlySaveResults": "allPlaces",
    "websiteFilter": "allPlaces",
    "skipClosedPlaces": False,
},
    dataset_mapping_function=lambda item: Document(text=json.dumps(item), metadata={"url": item.get("sourceUrl")}),
)
print(len(documents), "documents")

Good to know

  • The reader pins its own apify-client version; keep it in its own environment if your project uses the newer client.
  • To read results you already have, use ApifyDataset(token).load_data(dataset_id=..., dataset_mapping_function=...).
  • The snippets map the Actor's long-text field when it publishes one, else the whole record as JSON.

Actors to start with

Other frameworks

Troubleshooting

Why does the workflow or script stop with HTTP 408?

The synchronous endpoint waits at most 300 seconds. After that it answers 408 while the run keeps going in Apify. Lower the result limit, or start the run asynchronously, wait for it to finish and then read its dataset.

Source: Apify API: run Actor synchronously and get dataset items. This fix on its own page

What do 400, 401, 402 and 403 from the Apify API mean?

Read error.type in the response body. 400 is invalid Actor input. 401 (user-or-token-not-found) means a token reached Apify but it is wrong or revoked. 402 with x402-payment-required means no token reached Apify at all: the n8n credential or the Authorization: Bearer header is missing, and Apify is offering its pay-per-run x402 route for agents instead; any other 402 is an exhausted usage limit on the account that pays for the run. 403 is a token without permission for that Actor or storage.

Source: Apify API: authentication; Apify documentation: agentic payments with x402; Apify API: run Actor synchronously and get dataset items. This fix on its own page

Why does starting an Actor through the API return run information instead of scraped results?

The Run Actor endpoint starts the Actor and immediately returns a Run object without waiting for completion. For results stored in the default dataset, pass the response's defaultDatasetId to Get dataset items; to wait and receive output directly, use the synchronous endpoint for dataset items or a key-value store record.

Source: Apify Run Actor API. This fix on its own page

Why are rows and hidden fields missing from my Apify dataset export?

The clean parameter enables both skipEmpty and skipHidden, removing empty items and fields whose names begin with #. This can produce fewer items than the requested limit; to retain those rows and fields, disable clean and ensure skipEmpty and skipHidden are also disabled.

Source: Apify Get dataset items API. This fix on its own page

Sources