Impit
Use this skill when work touches Apify Impit: browser-impersonating HTTP requests via TLS + HTTP fingerprints, without running a real browser.
Workflow
- Inspect the local Impit surface before changing code:
- Language binding: Node
impit(npm), Pythonimpit(PyPI/conda), or Rust crate from git. - Package/native binary versions and platform (Node ≥ 20; platform-specific optional deps).
- Client lifetime: shared
Impit/AsyncClient/Impit::<Jar>vs one-shot clients. - Fingerprint choice: generic
chrome/firefoxvs versioned /okhttp/ios18. - Session needs: cookies, proxies, HTTP/3, redirects, default headers, timeouts.
- Language binding: Node
- Refresh docs when the user asks for latest fingerprints, option names, or binding differences. Start from source-map.md.
- For Node/TypeScript install,
ImpitOptions,fetch, responses, and errors, use nodejs.md. - For Python and Rust APIs, patched deps, and builder patterns, use python-rust.md.
- For fingerprints, HTTP/3 vs proxy constraints, cookies, headers precedence, multipart boundaries, and Crawlee
ImpitHttpClient, use fingerprints-ops.md. - Implement in the existing project style:
- Prefer
bun/bunxin command examples for Node work. - Reuse one client instance per impersonated identity (pool + optional cookie jar).
- Do not treat Impit as a headless browser — no page JS, DOM, or automation APIs.
- Prefer
Judgment
- Impit mimics TLS ClientHello and HTTP fingerprints (headers, HTTP/2 settings, pseudo-headers). Plain
fetch/axios/ undici fail TLS JA3-style checks; Impit addresses that layer. - Prefer Impit when bot detection blocks non-browser clients and a full browser is unnecessary. Prefer a real browser (Playwright/Puppeteer) when the site requires executed JavaScript or interactive flows.
- Default clients are stateless for cookies until you pass
cookieJar(JS),cookie_jar/cookies(Python), orwith_cookie_store(Rust). - HTTP/3 and proxies are mutually unsupported in current docs — do not enable both.
- Header precedence (case-insensitive): per-request headers > instance
headers> browser impersonation defaults. Empty-string values remove an impersonated header. - Generic
chrome/firefoxauto-pick a version; use versioned fingerprints when detection tracks outdated signatures. - One
Impitinstance = one user-agent identity sharing config, pool, and jar. Create separate instances for distinct identities. - Response bodies are single-consume (Fetch-compatible). Do not call
text()/json()/arrayBuffer()twice. - Respect site ToS, robots, rate limits, and applicable law. Use impersonation for legitimate integrations, scraping within policy, and testing — not for unauthorized access or abuse.
Verification
Prefer the repo's existing checks. For meaningful Impit work, include the relevant subset:
- Smoke request to a known endpoint; assert status and body parse once.
- Confirm negotiated protocol when
http3: true(response.http_versionin Python; inspect logs/headers where available). - Proxy path: HTTP/HTTPS/SOCKS without HTTP/3; fail closed if both are configured.
- Cookie round-trip when a jar is configured (set on first response, sent on second).
- Platform install: native optional dependency resolves on the target OS/arch (glibc vs musl on Linux).
- Typecheck Node consumers against
ImpitOptions/RequestInit/ error classes. - Crawlee: crawler runs with
ImpitHttpClientand expected fingerprint option.