Skip to main content

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/apify
Point any Apify client at that base URL and pass your Fetchin API key as the token. That’s the whole change.
The 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 the username/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. Increment page_number to walk the feed:
Reaction items additionally carry a 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:
Comment items carry no 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 ends FAILED, 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:
When a profile genuinely has no activity of that kind, the run ends 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.statusMessage explains the result ("Confirmed empty: …", "Confirmed end of feed: 12 item(s) available, 100 requested.").
  • run.stats.creditsCharged is 0 — nothing billable was produced.
  • Reading the dataset directly, the response carries x-fetchin-run-status and x-fetchin-run-status-message headers, so a consumer that only fetches items still sees the outcome without a second request.
In a multi-profile run, one profile failing does not sink the others: it yields a non-billed { "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: true costs 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 timeout input (seconds) bounds a run. If it elapses, the run ends TIMED-OUT and 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 429 with Retry-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:
You are not charged for a failed URL. Filter results with 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 by page_number (this matches Apify’s actor).
  • Reaching a deep page_number costs one source request per skipped page, so page sequentially rather than jumping to a high page number.

apimaestro/linkedin-profile-reactions (reactions)