HTTP Request — Bulk & Proxied API Calls
Pricing
from $5.00 / 1,000 http request sents
HTTP Request — Bulk & Proxied API Calls
Send HTTP requests (GET, POST, PUT, PATCH, DELETE) to any API with custom headers, params and body. Send a whole batch in one run instead of one run per call, route through Apify proxies by country, and forward each response to a callback URL. Built for Clay, n8n and no-code stacks.
Pricing
from $5.00 / 1,000 http request sents
Rating
0.0
(0)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
19
Total users
13
Monthly active users
6 days ago
Last modified
Categories
Share
Send HTTP requests (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) to any API endpoint with your own headers, query parameters and body — and get the response back as structured data.
Two things make this different from the other HTTP actors on the Store: it sends a whole batch in one run instead of one run per call, and it can route requests through Apify Proxy by country or residential group.
Built for Clay, n8n, Make and any no-code stack that needs real HTTP without an enterprise plan.
Why use this actor
- Batch in one run. Pass an array of requests and they all go out concurrently. Other HTTP actors take a single URL, so 500 calls means 500 runs — 500 start-ups, 500 queue waits. Here it's one run.
- Proxy routing. Send through Apify Proxy in a chosen country to hit geo-restricted endpoints, or spread a burst across residential IPs when an API rate-limits by address. Off by default, because most API calls should go out directly.
- Retries that make sense. Timeouts, connection errors, 408, 429 and 5xx are retried. A 4xx is your request being wrong and will fail identically forever, so it is never retried and never billed twice for nothing.
- Lookup keys. Tag every request with an identifier and get it echoed back on the result row, so you can join responses to the source rows they came from without matching on URL.
- Callback URL. Each row is POSTed to your endpoint the moment it completes — the pattern Clay and n8n use to receive results.
- Honest error rows. A request that dies in transport still returns a row with the error on it. You always learn what happened.
What it does
| You give it | You get back |
|---|---|
| A single URL | One row: status, headers, parsed body, timing |
| An array of requests | One row per request, sent concurrently |
| Headers / query params / JSON body | Applied per-run or overridden per-request |
| A callback URL | Each row POSTed to you as it finishes |
| A proxy config | Every request routed through it |
Supported inputs
| Input | What it does |
|---|---|
| URL | The endpoint to call. All you need for a single request. |
| HTTP method | GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS. |
| Headers | Key/value pairs — Authorization, X-API-Key, anything. Applied to every request; a request can override any single key. |
| Query parameters | Added to whatever the URL already carries — existing query strings are preserved. |
| Request body | For POST/PUT/PATCH. An object is sent as JSON with a matching content-type unless you set your own. |
| Lookup key | Any identifier, echoed back on the row. |
| Requests | The batch: an array of { url, method, headers, params, data, lookupKey }. Each entry inherits the run-level settings. |
| Max concurrency | How many go at once (1–50). Lower it if the target rate-limits you. |
| Response timeout | Per-attempt timeout in seconds. |
| Retry on failure / Max retries | Retry behaviour for transient failures. |
| Parse JSON responses | Parse a JSON body into a json field instead of a raw body string. |
| Max response size | Truncate large bodies, flagged with truncated: true. |
| Treat non-2xx as an error | Also fill the row's error field on a non-2xx. |
| Callback URL | POST each row here as it completes. |
| Proxy configuration | Route through Apify Proxy — pick a country or residential group. |
Use cases
Clay enrichment without the plan upgrade — Clay's HTTP API column sits behind a higher tier. Call this actor instead, pass a lookupKey per row, and join the responses straight back to your table.
Bulk API calls from a no-code tool — n8n, Make and Zapier all throttle or charge per call. Hand the whole list to one run and read the dataset once.
Geo-specific API responses — pricing, availability and search APIs answer differently by country. Set the proxy country and see what a user there sees.
Rate-limit spreading — an API that limits by IP stops being a bottleneck when requests come from a residential pool.
Webhook fan-out — POST the same payload to many endpoints in one run, with per-endpoint headers.
Scheduled health checks — run on a schedule against a list of endpoints and alert on the ok field.
How it works
- You give it a URL, or an array of requests.
- Each request is built from the run-level defaults with its own overrides merged on top — headers and query params merge key-by-key, so a request can change one header without restating the rest.
- Requests go out concurrently, up to your Max concurrency, optionally through Apify Proxy.
- Transient failures are retried; the response is read, optionally JSON-parsed, and truncated to your size cap.
- Each result is pushed to the dataset and POSTed to your callback URL if you set one.
Input examples
A single request:
{"url": "https://api.github.com/repos/apify/crawlee","method": "GET","headers": { "Accept": "application/vnd.github+json" }}
A batch, with a shared auth header and per-row lookup keys:
{"headers": { "Authorization": "Bearer YOUR_TOKEN" },"requests": [{ "url": "https://api.example.com/v1/users/1", "lookupKey": "row-1" },{ "url": "https://api.example.com/v1/users/2", "lookupKey": "row-2" },{ "url": "https://api.example.com/v1/users/3", "lookupKey": "row-3" }],"maxConcurrency": 10,"callbackUrl": "https://hooks.example.com/inbound"}
A POST through a German residential IP:
{"url": "https://api.example.com/v1/search","method": "POST","data": { "query": "coffee", "limit": 25 },"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "DE" }}
Output
One row per request:
{"lookupKey": "row-1","url": "https://api.github.com/repos/apify/crawlee?per_page=1","method": "GET","statusCode": 200,"ok": true,"responseHeaders": { "content-type": "application/json; charset=utf-8" },"json": { "id": 265833387, "name": "crawlee" },"body": null,"truncated": false,"durationMs": 556,"attempts": 1,"error": null}
Key output fields
| Field | Description |
|---|---|
lookupKey | Whatever you passed in, echoed back. null if you didn't set one. |
statusCode | HTTP status. null means no response arrived at all — DNS, TLS, timeout or blocked egress. |
ok | true for a 2xx. The field to filter on. |
responseHeaders | All response headers, lower-cased keys. |
json | Parsed body — present only when Parse JSON is on and the body actually parsed. |
body | Raw response text. null when json was parsed instead. |
truncated | true if the body hit your size cap. JSON parsing is skipped when truncated, since a cut-off document would parse into a silently incomplete object. |
durationMs | Total time across all attempts. |
attempts | Attempts made. 1 means it worked first try. |
error | Why it failed, or null. |
FAQ
Does a 404 or 500 fail the run?
No. That's a real answer from the target API and you get the status back. Only a request that never reached the host is treated as a problem, and it's reported on the run's status message. Turn on Treat non-2xx as an error if you also want the row's error field filled.
How am I billed? Per request sent, plus the actor start. A batch of 100 is billed as 100 requests — the same as 100 single runs, minus 99 start-ups.
Are retries billed twice? No. Billing is per request in your input, not per attempt.
Can I send form-encoded or XML bodies?
Yes. Pass the body as a string and set your own content-type — an explicit content-type is never overridden.
Do I need the proxy? Usually not. Leave it off unless you're hitting geo-restricted endpoints or an API that rate-limits by IP. Proxies add latency and will break IP-allowlisted endpoints.
What happens to very large responses?
They're truncated at your Max response size and flagged with truncated: true.
🤖 For AI Agents & LLM Apps
This actor is a clean tool-call target: one input, one structured row out, no HTML parsing. Point an agent at it to give it authenticated HTTP without handing it network access.
- Set
parseJson: trueso the agent readsjsondirectly instead of parsing a string. - Use
lookupKeyto correlate responses when the agent fans out a batch. okandstatusCodegive the agent an unambiguous success signal.- Cap
maxResponseBytesto keep responses inside the model's context window.
⚠️ Disclaimer
Use this actor only for endpoints you are authorised to call. You are responsible for the terms of service of any API you send requests to, for the credentials you pass in headers, and for the content of the requests you make. This actor sends exactly what you tell it to and does not inspect or modify your payloads beyond the encoding described above.
SEO Keywords
http request actor, send http requests, api request apify, clay http api, clay api enrichment, bulk http requests, rest api caller, webhook sender, post request actor, api proxy requests, no-code api calls, n8n http request, make.com http, geo-targeted api requests, batch api calls


