HTTP Request - Batch API Calls [$4/1K]
Pricing
from $4.00 / 1,000 http requests
HTTP Request - Batch API Calls [$4/1K]
Send GET, POST, PUT, PATCH and DELETE API calls from Apify in batches for Clay, n8n and Make: encrypted secrets, retries, lookup keys, structured results. $4 per 1,000 HTTP responses; blocks, timeouts and retries are never charged.
Pricing
from $4.00 / 1,000 http requests
Rating
0.0
(0)
Developer
Vadim Bezrukov
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
3
Monthly active users
2 days ago
Last modified
Categories
Share
Send a list of API requests and get one result per request, including the HTTP
status and response body. Use lookupKey to match each response back to its
Clay row, n8n item or Make step. Put shared credentials in encrypted secretHeaders.
You pay only for HTTP responses that actually arrived. Security blocks, timeouts, transport failures, retries, redirects and callbacks are never charged, and the bill is predictable before the run: $0.004 × responses plus a $0.00005 start.
Latest update, 13 October 2026: the results table shows the response body next to the HTTP status. Full history is in the changelog.
Try one request
{"requests": [{"lookupKey": "demo-post-1","method": "GET","url": "https://jsonplaceholder.typicode.com/posts/1","headers": { "Accept": "application/json" }}]}
Expected output: one Dataset row with status, httpStatus, parsed JSON body,
durationMs and bytesReceived. Typical first useful result under normal conditions
is under 10 seconds and about $0.004 (one http-request plus the $0.00005 start).
Use from AI agents with MCP
Direct tool URL (authenticated OAuth or API token required to run):
https://mcp.apify.com?tools=automa-flow/http-request-batch
Ask your agent something like: Call GET https://jsonplaceholder.typicode.com/posts/1 with lookupKey demo-post-1 through automa-flow/http-request-batch, keep maxRequests at 10 or lower, set maxTotalChargeUsd to 0.05, then report RUN_SUMMARY status, billedRequests and nextAction before reading the Dataset.
Anonymous discovery (no token) only supports Store search tools:
https://mcp.apify.com?tools=search-actors,fetch-actor-details. Direct Actor
execution always needs the caller's own Apify account.
Estimate the charge before running:
| Size | Input | Total charge (platform usage included) |
|---|---|---|
| Small | 1 request | $0.00405 |
| Small batch | 10 requests | $0.04005 |
| Cap | maxRequests (default 100, hard max 1000) | $0.00005 + N × $0.004 |
Each billable Dataset write and http-request event are atomic. At
maxTotalChargeUsd, the executor stops scheduling new target calls; any in-flight
response refused by the charge limit becomes an uncharged CANCELLED row with no
response payload. Read RUN_SUMMARY.nextAction first.
Related tools for API and file workflows
- Walk every page of one API: Paginated REST API Fetcher follows a configured page, offset, cursor or next-link pattern. Choose it when later requests depend on the previous response; use this HTTP batch Actor for an explicit list of independent calls.
- Store files from response URLs: Parallel Bulk File Downloader takes a list of public file URLs and returns stored files plus a manifest. Extract the permitted URLs from your API results and map them into its input.
- Extract website text: Website Content Crawler turns authorized public HTML into Markdown and optional chunks. Supply website URLs and the required rights declaration; an API response is not a crawl configuration.
Each tool runs separately with its own input and pricing. Your workflow must select successful results, map the next input and start the next run.
Batch example
{"requests": [{"lookupKey": "customer-1","method": "GET","url": "https://api.example.com/customers/1"},{"lookupKey": "customer-2","method": "POST","url": "https://api.example.com/customers","headers": { "Content-Type": "application/json" },"body": { "name": "Ada" }}],"secretHeaders": {"Authorization": "Bearer YOUR_TOKEN"},"maxConcurrency": 20,"maxRetries": 2,"maxRequests": 100}
Clay integration
- Create an Apify account and subscribe to this Actor.
- In Clay, use the Apify integration and select HTTP Request - Batch API Calls [$4/1K].
- Map Clay columns into
requests(or run a single-item batch per row). - Map Dataset fields (
body,httpStatus,lookupKey) back into Clay columns. - Optionally set
callbackUrlto POST each final row to another Clay webhook table.
n8n / Make / API usage
- n8n / Make: call the Apify Actor node / HTTP module with the JSON input above.
- API:
POST https://api.apify.com/v2/acts/automa-flow~http-request-batch/runswith the same input. Read the default Dataset andRUN_SUMMARYwhen the run succeeds; readCALLBACK_REPORTwhen callbacks are enabled.
Schedule recurring batches whenever your automation has a new set of rows/events.
To push results into n8n or Make as soon as a run finishes, add a run webhook
(POST https://api.apify.com/v2/webhooks):
{"eventTypes": ["ACTOR.RUN.SUCCEEDED", "ACTOR.RUN.FAILED"],"condition": { "actorId": "<this Actor's ID>" },"requestUrl": "https://your-n8n-or-make-webhook.example.com/hook","payloadTemplate": "{\"runId\": {{resource.id}}, \"datasetId\": {{resource.defaultDatasetId}}, \"status\": {{resource.status}}}"}
Then read RUN_SUMMARY (status, billedRequests, nextAction) and the Dataset
by datasetId in the receiving workflow.
Auth / secrets
Put credentials in secretHeaders (and callbackSecretHeaders for callbacks).
These fields are marked isSecret: true so Apify encrypts them at rest.
- Secret values are never written to Dataset rows or logs.
- Redirects never forward
secretHeaders, Authorization, cookies or API-key headers to a different origin. Reflected secret values are redacted from body and response-header output. - Prefer headers over query-string secrets (
token,api_key, …). Every query value is redacted in logs, Dataset URLs and callback payload URLs. - Per-request distinct secrets are not supported in this version - use shared
run-level
secretHeaders.
Output example
The results table includes body and bodyText beside the status and HTTP
code. JSON responses are in body. Text responses, and JSON that cannot be
parsed, are in bodyText. Open a row when you need headers or attempt detail.
{"inputIndex": 0,"lookupKey": "demo-post-1","method": "GET","url": "https://jsonplaceholder.typicode.com/posts/1","status": "SUCCESS","httpStatus": 200,"ok": true,"contentType": "application/json; charset=utf-8","responseHeaders": { "content-type": "application/json; charset=utf-8" },"body": { "userId": 1, "id": 1, "title": "…", "body": "…" },"bodyText": null,"truncated": false,"bytesReceived": 292,"attempts": 1,"durationMs": 180,"errorType": null,"errorMessage": null,"retried": false,"billable": true,"callbackStatus": "SKIPPED","callbackError": null,"source": "http-request-batch","scrapedAt": "2026-09-17T00:00:00Z","schemaVersion": 1}
Retries / failure semantics
| Status | Meaning |
|---|---|
SUCCESS | Target returned an HTTP response. ok is true for 2xx. With treatNon2xxAsError=false (default), non-2xx stays SUCCESS with ok=false. |
INVALID_INPUT | This request item was invalid. Other valid items still run. |
HTTP_ERROR | Non-2xx response when treatNon2xxAsError=true. |
TRANSPORT_ERROR | Network/protocol failure - never presented as an empty success. |
TIMEOUT | Attempt timed out. |
RESPONSE_TOO_LARGE | Streaming byte cap hit (default 256 KiB, max 1 MiB). |
SECURITY_BLOCKED | URL failed SSRF checks (private/loopback/metadata/credentials/…). |
CANCELLED | Not sent or unpaid: beyond maxRequests (errorType=MAX_REQUESTS_EXCEEDED), or stopped by maxTotalChargeUsd / billing. Response body is cleared. |
Retries (not billed): connection resets, timeouts, HTTP 408/429/500/502/503/504 -
GET/HEAD/OPTIONS only by default. Set retryNonIdempotent=true to retry
POST/PUT/PATCH/DELETE. Ordinary 4xx such as 400/401/403/404 are never retried.
Redirects are revalidated at every hop (max 5). HTTPS-to-HTTP downgrades and
cross-origin redirects that would preserve a request body are blocked. POST may
become GET on 301/302; 303 becomes GET except for HEAD; same-origin 301/302
methods and 307/308 preserve method and body. Dataset method reports the method
of the final attempt.
One bad request never kills the batch: N inputs → N Dataset rows. A batch
longer than maxRequests sends the first maxRequests items; the rest get
uncharged CANCELLED rows, so you can resend them by inputIndex or
lookupKey.
A run fails only when no request could be answered (every request timed out or hit a network error), the input or budget is invalid, or an unexpected error stops it. For a failure you cannot fix from your input, the run's status message links to this Actor's Issues tab. Paste the message and the run ID there so the failure can be traced.
timeoutSecs covers one complete attempt, including DNS, redirects and body
streaming. Retries each receive a fresh deadline. Retry waits are at most 30
seconds: if Retry-After requests a longer wait, the final response is returned
without retrying early. DNS failures are retryable transport errors, distinct
from private-address security blocks.
Both compressed wire bytes and decoded bytes are capped by maxResponseBytes.
Gzip, deflate and identity are supported. Other encodings, concatenated gzip
members or invalid compressed data return an uncharged
TRANSPORT_ERROR with errorType=RESPONSE_DECODING_ERROR. Invalid JSON,
JSON deeper than 64 levels and unsupported numbers are preserved in bodyText.
Headers must use valid HTTP names and ASCII values without control characters.
Spaces and line breaks around a header value are trimmed. Methods are
case-insensitive (post works like POST).
Unexpected system or storage failures can prevent all rows from being saved.
The failure summary preserves confirmed progress and billing details;
unresolvedRequests identifies unfinished items and progressKnown=false
flags uncertain settlement. Inspect the Dataset and charges before replaying
requests with side effects.
The primary Dataset row is atomically stored and charged before any callback is
sent. Callback retries within a run reuse an Idempotency-Key. A callback-enabled
Dataset row has callbackStatus=PENDING; final per-item delivery status is in
CALLBACK_REPORT. Callback failure keeps the primary result and makes
RUN_SUMMARY.status PARTIAL.
Pricing
Pay-per-event:
| Event | Price |
|---|---|
apify-actor-start | $0.00005 / run (Apify's default synthetic start; one event per GB of run memory) |
http-request | $0.004 / billable HTTP response ($4 / 1,000) |
Billable means the target server produced a real HTTP response (including 4xx/5xx
and RESPONSE_TOO_LARGE). Not billed: SSRF blocks, transport failures, timeouts,
retries, redirects, callbacks, validation. Platform usage (compute, storage,
transfer) is included in the event price; there is no separate usage charge.
Examples (total charge):
- 1 request → $0.00005 + $0.004 = $0.00405
- 100 requests → $0.00005 + $0.40 = $0.40005
- 1,000 requests → $0.00005 + $4.00 = $4.00005
Minimum maxTotalChargeUsd per run: $0.005 (one start plus one response).
Limits
For POST/PUT/PATCH/DELETE use one of body (JSON object), bodyArray (JSON
array), or bodyText (raw text). They are mutually exclusive.
| Limit | Default | Hard max |
|---|---|---|
Requests / run (maxRequests) | 100 | 1,000 |
| Concurrency | 20 | 50 |
| Timeout | 30 s | 120 s |
| Retries | 2 | 5 |
| Response size | 256 KiB | 1 MiB |
Security / SSRF policy
Only http / https URLs. Rejected:
file:,ftp:,data:,javascript:, malformed URLs- embedded credentials in the URL
- loopback, RFC1918 private, link-local, multicast/reserved IPv4
- IPv6 loopback / link-local / unique-local
- cloud metadata (
169.254.169.254, metadata hostnames) - hostnames that resolve to blocked addresses (DNS rebinding)
- redirect hops to blocked destinations
Callback URLs use the same policy. Use only APIs and data you are authorized to
access; do not use this Actor to bypass authentication, paywalls or access
controls. API responses may contain personal, regulated or confidential data and
are retained in the Apify Dataset until you delete them. Minimize requested data,
configure Dataset retention for your obligations, and remember that
callbackUrl discloses the full stored response row to that destination.
Server Set-Cookie values never establish a session for later requests,
redirects or callbacks. An explicit Cookie in secretHeaders is still sent
to each requested target, and is stripped on a cross-origin redirect.
Supported secret header values and Bearer, Basic and cookie credentials are
redacted when reflected verbatim. Encoded or transformed echoes cannot always
be recognized; request only the response data you need.
FAQ
Does this include Apify Proxy?
Not in this version. Plain outbound HTTPS only.
Are retries charged?
No.
What about binary responses?
Metadata is returned; arbitrary binary is not inlined into the Dataset by default.
Can I use distinct secrets per request?
Not in this version - use shared secretHeaders for the run.
Example workflows
- Call a REST API from Clay - single GET +
lookupKey - POST JSON to a webhook/API - demo POST; secrets via
secretHeaders - Send 100 API requests in one batch - concurrency + per-row Dataset identity
