Quickstart
Get a key, make a call, page through a list.
1. Get a key
Create one in the dashboard. The plaintext is shown once at creation and never again — we store a hash, so a lost key means a new key.
New accounts start with free balance, so you can run through this page before paying anything.
2. Make a call
curl https://api.herascrape.com/users/username/instagram \
-H "X-Api-Key: $HERASCRAPE_KEY"You get Instagram's profile object back, in full. Take pk from it — that
numeric id addresses every sub-resource:
curl https://api.herascrape.com/users/25025320/followers \
-H "X-Api-Key: $HERASCRAPE_KEY"Looking up by username costs two Instagram requests (a resolve, then the profile), so it is billed at double. Cache the numeric id and the second call onward is single-price. See Pricing.
3. Page through a list
One call returns one Instagram page. Loop on next_cursor until has_more
goes false:
import httpx
BASE = "https://api.herascrape.com"
headers = {"X-Api-Key": KEY}
def paginate(path: str, **params):
cursor = None
with httpx.Client(base_url=BASE, headers=headers, timeout=60) as http:
while True:
if cursor:
params["cursor"] = cursor
page = http.get(path, params=params).raise_for_status().json()
yield from page["items"]
if not page["has_more"]:
return
cursor = page["next_cursor"]
for follower in paginate("/users/25025320/followers"):
print(follower["username"])const BASE = 'https://api.herascrape.com'
async function* paginate(path, params = {}) {
let cursor = null
for (;;) {
const query = new URLSearchParams({ ...params, ...(cursor ? { cursor } : {}) })
const response = await fetch(`${BASE}${path}?${query}`, {
headers: { 'X-Api-Key': process.env.HERASCRAPE_KEY },
})
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`)
const page = await response.json()
yield* page.items
if (!page.has_more) return
cursor = page.next_cursor
}
}Treat cursor as opaque. It encodes whichever token the underlying Instagram
endpoint uses, and that differs per endpoint — parsing or constructing one
will break.
4. Handle the errors that matter
Three you should branch on, and one you should retry:
response = http.get(f"/users/{user_id}")
if response.status_code == 404:
... # gone, deleted, or never existed
elif response.status_code == 403:
... # private account
elif response.status_code == 429:
... # your rate limit; back off
elif response.status_code in (502, 503):
... # transient on our side; retryNon-2xx responses are never billed. Full list in Errors.
Where to go next
- Authentication — key handling and headers.
- Resolving ids — usernames, shortcodes, share links.
- Migrating from HikerAPI — if you are coming from there, start at the translation table.