DEV Community

What a browser cannot do, and what that costs — notes from building a small paid lookup tool

I spent a week building a small paid tool. The idea is boring on purpose: you type a
public Instagram handle, and you get the two lists that profile already shows to
anyone — who it follows and who follows it — complete, ordered, exportable.

Nothing about that is secret. Anyone can open the app and scroll. The product is not
access, it is completeness: a few hundred names do not fit in a human head, and the
app gives you no way to search them or keep them.

What I did not expect was how much of the week went into things that have nothing to do
with the feature itself.

The wall I hit on day one

My first instinct was the obvious one: the visitor is already logged into Instagram in
that same browser, so let the page read the data and be done with it.

That does not work, and it cannot work. Session cookies on that domain are HttpOnly,
so no JavaScript can read them, and the Same-Origin Policy stops my domain from sending
authenticated requests to theirs. This is not a gap to be clever about — it is the
boundary the whole web security model is built on.

That leaves three real options:

  1. Ship a browser extension. Extensions get host permissions, so they can do what a page cannot. This works — it is exactly how the popular tools in this niche operate. But then your "website" is an extension, and the install step kills most of your funnel.
  2. Run your own logged-in accounts server-side. I tried. Within a day the account got flagged for automated behaviour. Burning accounts is a business, and it is not the business I wanted.
  3. Buy the data from someone who does option 2 professionally.

I went with the third and used hikerapi.com. One header, one
GET, no session to babysit:

import requests
headers = {"x-access-key": "YOUR_KEY"}
resp = requests.get("https://api.hikerapi.com/v2/user/by/username?username=nasa", headers=headers)
print(resp.json())
Enter fullscreen mode Exit fullscreen mode

You get 100 requests free to check whether the shape of the data fits your product
before paying anything, which is how I confirmed the ordering question below.

Why not instagrapi?

This is the fork in the road for anyone in this space, so let me be concrete rather than
diplomatic.

instagrapi is excellent, and I read its source
while working on this — it is the clearest documentation of Instagram's private API that
exists. If you are doing research, automating your own account, or building something
internal, use it. It is free and it works.

The catch is the same one option 2 above: instagrapi needs an Instagram account, and
that account is yours.
Every request carries your session. The library cannot change
that — it is a client, not a proxy pool. For a personal script that runs a few times a
day, fine. For a public product where strangers trigger scans at unpredictable times, you
are volunteering an account for slaughter, and then a second, and then a third.

The tradeoff is honest and it is not free:

instagrapi Paid API
Cost free per request
Account risk yours theirs
Session handling you own it none
Proxies you arrange them included
Control total whatever the endpoints expose

That last row is real. You give something up: a library gives you every parameter the
private API accepts, while a provider exposes the subset it chose to wrap. I ran into
this — there is a sort-order parameter documented in instagrapi's source that the
provider does not surface. For my use case it did not matter. For yours it might, and
that is worth checking before you build.

So: not "instagrapi is worse". It is "whose account absorbs the risk", and once you are
charging strangers money, that question answers itself.

The three things I wish I had known on day one

Per-request and per-result pricing differ by two orders of magnitude

This was the single biggest number in the whole project, and I nearly missed it.

Some providers bill per result — you pay for every row you pull. Others bill per
request
, and one request returns a page of many rows. For a profile with a few
thousand entries, the same data costs a couple of cents under one model and several
dollars under the other.

Work out your unit cost before you pick anything. Mine came out to roughly:

requests ≈ (followers + following) / page_size + 2
Enter fullscreen mode Exit fullscreen mode

Two extra calls because I read the profile before and after the scan and refuse to save
a snapshot if the counts moved — a half-collected list is worse than no list.

Not all endpoints returning "the same data" are the same

The provider exposes several endpoint families that all return follower lists. They are
not interchangeable. They differ in page size, in what a single call costs you, and —
the part that actually mattered for my product — in the order the rows come back.

I tested them against what the app itself shows before writing a line of product code.
That afternoon of comparing outputs saved me from building the whole thing on the wrong
one and discovering it after launch.

Check the balance endpoint before long jobs

Buried in the API docs is a /sys/balance call that is not billed. It returns how
many requests you have left.

I learned its value the hard way: a scan died a third of the way through because the
balance ran out mid-job. Those requests were spent and produced nothing — the worst
possible outcome. Now nothing long starts without a free balance check first, and if the
remaining budget is smaller than the job needs, the user is told before anything is
charged rather than after.

The honest limitation

There is one thing people ask for constantly and no provider can deliver: the date
someone followed someone.

It does not exist. Not in the private mobile API, not in the web GraphQL, not in Meta's
official Graph API. The lists come back in a meaningful order, and that is all the
information there is. Any product showing you "followed on March 14" invented that date.

I put that in the FAQ instead of quietly hoping nobody notices. It is the kind of thing
that turns into refund requests if you let people assume otherwise.

Was it worth it?

The engineering was two days. The rest of the week went to the offer document, the
privacy policy, the payment provider's requirements, and a legal tax regime detail that
turned out to remove an entire dependency I had budgeted for.

If you are building something small and paid on top of someone else's data: budget for
that half, not for the feature. The feature is the easy part.

What surprised you most in your last "small" project?

Top comments (0)