Overview
Fetchin exposes an Apify-compatible endpoint. If you already run B2B data actors through Apify, you can keep your existing code and the official Apify client libraries — you only change the base URL to Fetchin and use your Fetchin API key as the token. Everything runs asynchronously, exactly like Apify: you start an actor run, we queue it, and you poll for the result and read the dataset. Batches are buffered and drained at your plan’s RPS.Base URL
https://api.fetchin.io/v1/apifyThe token here is the same key you send as
X-API-Key elsewhere, so
rotating it covers this integration too.
Create the new key, update the token in your Apify clients, and revoke the old
key once it stops being used — both work at once, so nothing breaks in
between. Run history and datasets belong to your account, not to a key.Supported actors
The following Apify actors are supported today. Reference an actor by its raw actor ID or by theusername/actor-name form your existing integration
already uses — both resolve.
We map the output fields to match each actor as closely as possible, so your
downstream code keeps working unchanged.
Need another actor? If you rely on an actor that isn’t in this list,
reach out via the chat on fetchin.io or email us — we
add actors on request.
Usage
JavaScript / Node (apify-client)
Python (apify-client)
HTTP (any language)
Input (comments & reactions)
Both actors accept the published input shape —usernames plus a per-profile
limit — and the singular username form:
limit is a ceiling, not a target: a run returns min(limit, available)
items per profile. Asking for more than a profile has is safe and returns
everything it has — the run’s statusMessage then says Confirmed end of feed.
You never need to know a profile’s true count in advance.
Pagination (comments & reactions)
Each run returns one page per profile. Incrementpage_number to walk the
feed:
pagination_token. Passing it back with the
next page_number jumps straight to that position instead of walking there, so
it is the cheaper and faster way to page that actor:
pagination_token (matching the actor we emulate), so
comments page by page_number alone.
Telling “no data” apart from “it didn’t work”
A run that could not collect its data in full endsFAILED, never
SUCCEEDED with a short or empty dataset. That covers both shapes: a collection
that produced nothing, and one that produced some genuine items but was
truncated before the feed was exhausted — the harder case, because the payload
looks perfectly valid. A truncated run keeps its items in the dataset (they are
real, and yours to use), but its status tells you they are not the whole answer.
So run.status is a sufficient check:
SUCCEEDED
with a single non-billed sentinel item — { "message": "No comment found for this profile" } / { "message": "No reaction found for this profile" },
matching Apify — and these signals confirm it:
run.statusMessageexplains the result ("Confirmed empty: …","Confirmed end of feed: 12 item(s) available, 100 requested.").run.stats.creditsChargedis0— nothing billable was produced.- Reading the dataset directly, the response carries
x-fetchin-run-statusandx-fetchin-run-status-messageheaders, so a consumer that only fetches items still sees the outcome without a second request.
{ "profile_input": "…", "message": "API request failed", "errorDetails": "…" } item, the rest of the batch completes, and the run only
ends FAILED if every profile failed.
Billing, timeouts & retention
- Billing: 1 dataset item = 1 Fetchin credit (the same per-result accounting
as Apify). A batch of 25 profiles = 25 credits. Exception: a post fetched
with
deepScrape: truecosts up to 3 credits per post — 1 for the post plus 1 for each engagement list we return (its comments and its reactions). You are billed only for what we deliver: if an engagement list comes back empty, its credit is not charged (a post whose comments and reactions both come back empty costs 1). A shallow post (deepScrape: false/ omitted) always costs 1 credit. - Timeout: the
timeoutinput (seconds) bounds a run. If it elapses, the run endsTIMED-OUTand the items already produced remain in the dataset. - Retention: run records and datasets are retained for 24 hours. Fetch your results within that window.
- Rate: your account RPS controls how fast we drain your queued items (not
how many runs you can create). Creating runs far faster than your RPS returns
429withRetry-After; the Apify client backs off automatically.
Differences vs Apify
We validate every actor against real Apify output field-by-field. The reactions, comments and post actors reach zero field errors on matched items; the differences below are values that either cannot be reproduced byte-for-byte (live counts, signed URLs, per-request tokens) or that we approximate where the source data isn’t exposed. Everything here is stable and documented so you can decide whether it affects your integration. If a specific field blocks you, contact us and we’ll prioritise it.Applies to all actors
- Live engagement counts (reactions/comments/reposts totals) drift second to second — they reflect the source at fetch time, so two fetches rarely match to the digit. This is identical to Apify.
- Relative timestamps (
"15h","2w") are wall-clock-relative to the moment of the request. Absolute timestamps (timestamp,postedAtISO,formatted) are exact. - Signed media URLs carry an expiring signature (
?e=…&v=…&t=…). The host + path are stable; the signature differs every request. - Pagination tokens are opaque and positional — use them, don’t compare them.
Batch error handling (profile & post)
The batch actors (profile, post) accept many URLs per run. If one URL can’t
be fetched (profile not found, a transient upstream error), the run does not
fail: the rest of the batch still completes, the run ends SUCCEEDED, and the
failed URL yields a single non-billed item:
items.filter((i) => !i.error), and retry the ones carrying an error (a
transient failure usually succeeds on a re-run).
supreme_coder/linkedin-profile-scraper (profile)
supreme_coder/linkedin-post (post)
apimaestro/linkedin-profile-comments (comments)
- Full field parity on matched items. Only the volatile values above (live comment/post reaction counts, relative time) differ.
- Items do not carry a root
pagination_token— this actor pages bypage_number(this matches Apify’s actor). - Reaching a deep
page_numbercosts one source request per skipped page, so page sequentially rather than jumping to a high page number.