A few months ago I published a set of Actors on Apify Store. Today they're all AI-agent ready: any LLM agent (Claude, GPT, Cursor, LangChain, n8n) can discover and call them through the Apify MCP server — no custom integration code needed.
This post is the full playbook: what the tools do, how pay-per-event monetization works (including the pricing trap that made me lose money on every sale), the bugs I hit, and how AI agents actually consume the tools.
The toolbox
| Actor | What it extracts | Price (pay-per-event) |
|---|---|---|
| Google Maps Business Scraper | Names, phones, websites, ratings, reviews, GPS | $1.00 / run + $0.03 / business |
| TikTok Profile & Video Scraper | Followers, likes, bio, per-video stats | $0.01 / profile + $0.002 / video |
| Instagram Profile Scraper | Followers, bio, verified, engagement | $0.01 / profile |
| YouTube Video & Channel Scraper | Views, likes, subscribers, search results | $0.002 / video |
| LinkedIn Profile Scraper | Headlines, companies, skills, experience | $0.02 / profile |
| RAG Web Browser | Clean Markdown from any URL + Google search | $0.003 / page |
| Fuel Prices France API | Real-time prices, 9,800 stations, GPS | $0.20 / run + $0.01 / 1k stations |
| Hotel Rate Monitoring | Competitor rates, parity checks | fractions of a cent per item |
| API Breaking-Change Radar | Diffs OpenAPI specs, classifies changelogs, alerts | $0.50 / run + $0.50 / breaking change |
| Review Radar | New Google reviews for a business, Slack alerts | $0.25 / run + $0.01 / new review |
| Review Pitch Generator | Worst reviews → ready-to-send sales report | $0.25 / run + $0.10 / pitch |
The last three are a different breed: not scrapers but monitors — they keep state between runs and only bill when they find something.
Why "AI-agent ready" changes everything
The old model: a human finds your scraper on the store, reads the docs, clicks buttons.
The new model: an AI agent gets a task ("find me 50 plumbers in Austin with their phone numbers"), searches the Apify Store via MCP, reads the actor's README and input schema, and calls it — end to end, no human.
For that to work, three things must be true:
- Your README is written for an LLM, not just humans. Mine now all start with a "Use this tool when..." section — that's what the agent pattern-matches against the user's request.
- Your input schema has a description on every field. The agent constructs the JSON input from those descriptions. No description = hallucinated parameters = failed runs = no revenue.
- Your output is documented field by field. The agent needs to know what it gets back to reason over it.
Here's the actual flow with the Apify MCP server (https://mcp.apify.com — add it to Claude Desktop or Cursor in 30 seconds):
User: "Get me the follower counts of these 5 TikTok creators"
Agent: → search-actors("tiktok profile")
→ fetch-actor-details (reads README + input schema)
→ call-actor(travelmonitorlab/tiktok-scraper,
{"profiles": [...], "maxVideosPerProfile": 0})
→ returns structured JSON
Or skip MCP entirely — every actor is a single synchronous HTTP call:
curl -X POST "https://api.apify.com/v2/acts/travelmonitorlab~google-maps-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["plumbers Austin TX"], "maxResults": 50}'
Monetization: pay-per-event (and the trap that cost me real money)
Apify offers several pricing models. For new actors, PRICE_PER_DATASET_ITEM is rejected — you must use PAY_PER_EVENT. The model is better anyway: you define events and charge explicitly in code:
await Actor.charge(event_name="business-scraped")
await Actor.push_data(item)
Trap #1 — the vanishing charge: put the charge AFTER crawler.run() and your event loop may already be closed — the charge silently vanishes, you deliver data for free. Charge inside the handler, right before pushing data. Always verify with chargedEventCounts in the run object after a test run.
Trap #2 — pricing below your compute cost (this one actually bit me): on Apify's free plan, the actor owner pays the user's compute. My Google Maps actor was priced at $0.005/business. A customer scraped 16 businesses → I earned $0.08, and paid $1.23 in Playwright + residential proxy costs. Margin: −1436%. Every sale lost money. The structural fix: a flat run-started event that covers fixed costs (browser launch, proxy session) plus a per-result event with real margin:
await Actor.charge(event_name="run-started") # first line of main()
That same 16-business run now bills $1.48 instead of $0.08. If you build browser-based actors, do this from day one.
Setting pricing is pure API — and pricingInfos is append-only: you can't edit a tier in place, you append a new one:
PUT /v2/acts/{actorId}
{"pricingInfos": [existing_tier_verbatim, {
"pricingModel": "PAY_PER_EVENT",
"reasonForChange": "Flat run fee to cover compute",
"pricingPerEvent": {"actorChargeEvents": {
"run-started": {"eventTitle": "Run started", "eventDescription": "...", "eventPriceUsd": 1.0},
"business-scraped": {"eventTitle": "Business scraped", "eventDescription": "...", "eventPriceUsd": 0.03}
}}}]}
Apify takes 20%. Compute is paid by the user (on paid plans); you pocket the event fees.
Trap #3 — self-billing: running your own PPE actor bills your own account. Build a dryRun input flag that wraps every Actor.charge() and skips it — you can then integration-test the full pipeline for free and only flip billing on for real runs.
The QA gauntlet (or: your actor must survive an empty input)
Apify automatically runs every store actor with the schema's prefilled input and expects success within 5 minutes — three failures and your actor gets flagged "Under maintenance", then deprecated. Two lessons learned the hard way:
-
Never raise on empty input. If the user (or the QA bot) provides no target, fall back to a small built-in demo (2 results, dry-run forced) and exit 0. An actor that raises
RuntimeError("no target")is an actor on the deprecation list. - Keep the prefill tiny. The QA run is baked into your build: a heavy prefill (20 Playwright results through residential proxies) blows the 5-minute budget and flags you. Prefill = 2 results max, dry-run on.
Battle scars (so you don't get them)
-
Crawlee 1.8 breaking changes:
purge_on_startandnavigation_timeout_secsare no longer valid kwargs — usepage.set_default_navigation_timeout()in apre_navigation_hook. -
Google Maps never fires
load: analytics keep streaming forever, so navigation always times out. Fix: abort images/fonts/media viapage.route()(the handler must be a coroutine, not a lambda). -
Residential proxies are mandatory for Google Maps, and you must pass
actor_proxy_input=as a named argument toActor.create_proxy_configuration(). -
French number formats will crash your floats:
"4,8"→ replace comma;"1 234"reviews can use\xa0or\u202fas thousand separator. -
A "SUCCEEDED" run can contain zero useful data. Always check
itemCount+ sample the dataset + read the end of the log. - Don't run 7 queries × 25 results in one run. Split into parallel runs of ≤5 queries × 15 results; retry failed ones sequentially (residential proxy tunnels occasionally die).
-
Pin your dependencies.
apify>=3.2,<4+crawlee>=1.7,<2is a proven combo; open ranges break within weeks as PyPI drifts.
The distribution strategy
Publishing on the store is step 0. What actually moves the needle:
- README written for LLMs — agents choose tools whose docs they can parse. Clear "use when", typed inputs, example I/O. The MCP server's own system prompt tells agents to read your README before calling — it's your storefront.
- Niche SEO titles — "Google Maps Scraper" is saturated (the official one has 500k+ users); "Fuel Prices France API" has zero competition on the store.
- Monitors > scrapers — a scraper competes with everyone; a stateful monitor (breaking changes, new reviews) with Slack alerts answers a recurring pain and justifies a per-run flat fee.
- Dogfooding — I use my own Google Maps actor to build lead lists I sell elsewhere. Every sale is also a demo.
Try them
All 11 actors are live on Apify Store. If you build agents, add https://mcp.apify.com to your MCP client and just ask for the data — the agent will find the tools.
Feedback, bugs, feature requests: open an issue on any actor page, I answer fast.
Top comments (8)
Good playbook, the "empty input must exit 0 with a tiny demo" point is the one that quietly gets actors flagged. Curious about the flat run-started fee: have agent callers balked at it compared with per-result only, or does the README cost estimate cover that?
Honest answer: no balking so far — but paying volume is still near zero on my side (first unique store users this month, no paying runs yet), so I wouldn't read much into it either way. The flat event exists because the alternative was measurably worse: per-result-only on a Playwright + residential-proxy actor earned $0.08 on a run that cost me $1.23. Now the Maps actor is $1.00 flat + $0.03/result and the review monitors are $0.25 flat + $0.01/new review — small runs stay cheap, and the flat part roughly covers what launching a browser session + proxy actually costs.
On the README: every actor page lists the full event table with exact prices, and the input schema exposes maxResults, so an agent can compute its worst case before calling (run-started + maxResults × per-result). On the x402 agentic channel the charge scheme is "upto" — the caller only pays for events actually fired, so an aborted or empty run doesn't burn the full estimate.
Curious how you'd split it for browser actors: is a $1 flat ever a dealbreaker for agent buyers, or is predictability what actually matters?
Predictability, I'd guess. An agent mostly needs to compute the worst case before calling, so a flat fee isn't a dealbreaker if the event table and maxResults are visible up front. It hurts when it dominates tiny runs. I don't have buyer data though, you're the one with actors in front of agents.
That's my read too — the flat fee exists so the worst case is computable before the call (run-started + maxResults x per-result), not to extract value from tiny runs. Your "hurts when it dominates tiny runs" point is exactly why the empty-input demo run exits 0 with a near-zero charge, and why the x402 agentic channel uses an "upto" scheme where the caller only pays for events actually fired — an aborted run doesn't burn the estimate.
No buyer data on my side either yet, to be clear: first unique store users this month, zero paying runs so far. So right now it's design intent meeting your educated guess. Once there's real paying volume I'll write the follow-up with actual numbers — whether agents balk at the $1 flat or treat it as rounding error is exactly what I want to measure.
That's the right frame: the flat fee makes the worst case computable before the call. Same picture here: real users, almost no paying runs yet. Looking forward to the follow-up with real numbers.
Thanks! The follow-up with real numbers is definitely planned — I'll publish it once there's meaningful paying volume (honest data or nothing). Good luck on your side too — 'real users, almost no paying runs yet' seems to be exactly where the whole store is right now.
Trap #2 deserves more attention: per-result pricing on browser plus residential-proxy Actors can go negative fast, and the flat run-started event is a clean fix. For agent buyers I'd also put an explicit cost-per-run estimate in the README, so the agent can budget before it calls. Disclosure, since it's related: I work on Bytewells by ThoughtPivot, where renters pay compute from their own prepaid credit and developers can offer 1h/24h/7d passes for agent-style bursts. Pay-per-event isn't supported there at launch, though, so for your monitor-style Actors Apify's PPE is still the better fit.
Fully agreed on the worked example — the event table is already in each README, but a one-line "typical run ≈ $X" (e.g. 50 businesses ≈ $1.00 + 50×$0.03 = $2.50) is exactly what an agent can budget against without doing the multiplication itself. Adding that line to my README template across the store this week.
And thanks for the disclosure — the Bytewells pass model (1h/24h/7d prepaid) looks like a sensible fit for bursty agent workloads where the caller wants a hard spend cap instead of metered events. For always-on monitors firing a handful of events per day, per-event still maps better to the value delivered, which is why I'm staying on PPE for those. Genuinely curious how renters react to pre-funding compute vs post-paid metering — that tradeoff will shape a lot of pricing models this year.