HTTP Request — Bulk API Calls for Clay, n8n & Make avatar

HTTP Request — Bulk API Calls for Clay, n8n & Make

Pricing

from $2.00 / 1,000 request sents

Go to Apify Store
HTTP Request — Bulk API Calls for Clay, n8n & Make

HTTP Request — Bulk API Calls for Clay, n8n & Make

Send HTTP requests to any API (GET, POST, PUT, PATCH, DELETE) from Clay, n8n, Make, Zapier or the Apify API: one call or thousands in a batch, with {{variable}} templating, retries, redirects, JSON field extraction and webhook callbacks. A Clay HTTP API alternative at $2 per 1,000 requests.

Pricing

from $2.00 / 1,000 request sents

Rating

0.0

(0)

Developer

ActorForge

ActorForge

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Features

Limited permissions

Share

Send HTTP requests to any API (GET, POST, PUT, PATCH, DELETE) from Clay, n8n, Make, Zapier or the Apify API: one call or thousands in a batch, with {{variable}} templating, retries, redirects, JSON field extraction and webhook callbacks. A Clay HTTP API alternative at $2 per 1,000 requests.

Call any REST API or webhook from Clay, n8n, Make, Zapier or your own code, with no HTTP plan upgrade and no server to run. Send one request or a batch of thousands (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) with custom headers, query parameters and JSON, form or raw bodies. Get back one clean row per request: status code, response headers, the body (parsed JSON, text, or base64 for binary), extracted fields pulled out of the JSON by path (e.g. data.items[0].email), duration, attempts and the full redirect chain. It works as a Clay HTTP API alternative: Clay only offers its HTTP API integration on higher plans, but any Clay table can run an Apify actor per row. It also does bulk API requests for n8n and Make (one run, many calls, results as items), and you can forward every response to a webhook (a Clay table webhook, n8n or Make) with an optional lookupKey to match rows.

Batch and templating. Put {{field}} placeholders in the URL, headers, query or body and pass a variables list: one request per row, e.g. enrich 5,000 domains with one input. URL values are percent-encoded, JSON bodies are escaped, and a lone "{{count}}" keeps its number type. Reliable by default: retries with exponential backoff on network errors, timeouts, 429 and 5xx (honours Retry-After; POST is never blindly re-sent after a 500), per-host concurrency limits for rate-limited APIs, redirects (credentials are dropped on cross-domain hops), gzip/brotli decoding, and a size cap on bodies.

Secure. Your API keys never appear in the run log, and the secret Authorization header field is stored encrypted. Requests to private networks, localhost and cloud-metadata addresses are blocked at connect time, including after redirects and DNS rebinding.

Drop-in compatible with riceman/send-http-requests inputs: url, method, headers, params, data, responseTimeout, retryOnFailure, maxRetries, callbackUrl, callbackHeaders and lookupKey all work unchanged, and rows keep the data, status, statusText and headers fields, at $2 per 1,000 requests instead of $5.

How to use it from Clay, n8n, Make and Zapier

Your actor ID is actor-forge~http-request-runner. Find your Apify API token in Apify Console → Settings → API & Integrations.

Clay (one API call per table row)

  1. In your Clay table click Add enrichment, search for Apify and choose the action that runs an actor. Connect your Apify account with your API token.
  2. Pick the actor actor-forge/http-request-runner.
  3. In the input, insert Clay columns where values go, e.g. {"url": "https://api.example.com/v1/people?email=<Email column>", "method": "GET", "extract": ["person.title", "company=person.company.name"]}. Put an API key in authorizationHeader (Bearer … or X-Api-Key: …).
  4. Run the column, then map status, extracted.title, extracted.company or data.… to new columns.
  5. Large responses: set callbackUrl to a Clay table webhook and lookupKey to the row ID, and the full row is posted there.

n8n

  1. Add an HTTP Request node: method POST, URL https://api.apify.com/v2/acts/actor-forge~http-request-runner/run-sync-get-dataset-items, header Authorization: Bearer YOUR_APIFY_TOKEN, body type JSON.
  2. Body = the actor input. n8n uses {{ }} for its own expressions, so map values with n8n expressions instead of our placeholders, e.g. {"requests": {{ JSON.stringify($json.urls) }}, "extract": ["id", "name"]}. Each returned item is one response row.
  3. Or use the Apify node (Run actor, wait for finish, then get dataset items).

Make

  1. Add HTTP → Make a request: method POST, URL https://api.apify.com/v2/acts/actor-forge~http-request-runner/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN, body type Raw, content type JSON, and Parse response on.
  2. Request content = the actor input JSON, with Make's mapped values inserted directly (Make also uses {{ }}, so map fields rather than using our placeholders). The output is an array with one bundle per request.
  3. Or use the Apify app: Run an actor (synchronous), then Get dataset items.

Zapier Use the Apify app's Run Actor action with this actor and the input JSON, or Webhooks by Zapier → POST to the run-sync-get-dataset-items URL above.

Any code / curl curl -X POST "https://api.apify.com/v2/acts/actor-forge~http-request-runner/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" -H "Content-Type: application/json" -d '{"url": "https://httpbin.org/get"}' returns the response rows as a JSON array. For a single request, .../run-sync returns the row itself (the run's OUTPUT record). Synchronous calls wait up to 300 seconds; for bigger batches start the run asynchronously and read the dataset, or use callbackUrl.

What data does it return?

Every run outputs clean, schema-validated rows like these:

indexlookupKeyrequest.methodrequest.urlstatusokextracteddurationMserror
0row-17GEThttps://jsonplaceholder.typicode.com/users/1200true{"email":"Sincere@april.biz","company.name":"Romaguera-Crona","address.city":"Gwenborough"}153
1row-18POSThttps://postman-echo.com/post200true{"json.name":"Acme Ltd"}182
2row-19GEThttps://httpbin.org/status/404404false{}97
3row-20GEThttp://169.254.169.254/latest/meta-data/false{}0blocked: internal address 169.254.169.254 is not allowed

How much does it cost?

Transparent pay-per-event pricing — you only pay for what you get, and the actor always respects your run budget: set a maximum total charge and it stops cleanly at the cap instead of overrunning.

EventPriceChargedWorked example
request-sent$0.002per request that got an HTTP response (any status code, after retries and redirects; retries are not charged again)1,000 requests = $2.00; a 10,000-row Clay table = $20
apify-actor-start$0.00005per run per GB of memory (platform start fee)One run at up to 1 GB = $0.00005 (charged as one event)

Input options

FieldTypeRequiredDefaultDescription
urlstringno—URL for a single request (http or https). Supports {{field}} placeholders filled from Variables. Leave empty when you use Requests (batch).
methodstringno—HTTP method. If empty: GET, or POST when a body is given.
headersobjectno—Request headers as a JSON object, e.g. {"Content-Type": "application/json"}. Values support {{field}} placeholders. Header values are never written to the run log. Put API keys in the secret Authorization header field below instead, so they are stored encrypted.
authorizationHeaderstringno—Optional, stored encrypted. A value like "Bearer sk_123" or "Basic dXNlcjpwYXNz" is sent as the Authorization header; "X-Api-Key: abc123" (name: value) sends that header instead. Added to every request and overrides the same header in Headers.
queryParamsobjectno—Query string parameters as a JSON object, URL-encoded and appended to the URL. Arrays repeat the key (tags=a&tags=b). Alias: params.
bodystringno—Raw request body, e.g. a JSON string or form data. A body starting with { or [ is sent as application/json unless you set Content-Type. Placeholders in JSON bodies are JSON-escaped automatically.
dataobjectno—Request body as a JSON object (sent as application/json, or form-encoded when Content-Type is application/x-www-form-urlencoded). A string that is exactly one placeholder, like "{{count}}", keeps the variable's type. Used when Body (raw) is empty.
contentTypestringno—Shortcut for the Content-Type header, e.g. application/json; charset=utf-8.
requestsarrayno—List of requests: URL strings or objects {url, method, headers, queryParams, body, lookupKey}. Each item inherits the top-level settings and can override them.
variablesarrayno—List of objects, e.g. [{"domain": "stripe.com"}, {"domain": "notion.so"}]. Every request is sent once per row with {{domain}} replaced. Dot paths work ({{company.name}}, {{tags[0]}}); {{{field}}} inserts raw. A row's lookupKey field is copied to its result.
lookupKeystringno—Optional identifier copied to the result row and the callback, e.g. the Clay row ID, so you can match responses to rows.
extractarrayno—Paths to pull out of JSON responses into the extracted column, e.g. data.items[0].email, results[*].id or email=data.items[0].email (alias=path names the key). Absent paths give null.
responseFormatstringno"auto"How the response body is returned.
maxResponseBytesintegerno2097152Bodies larger than this are cut off and flagged bodyTruncated. Default 2 MB, maximum 9 MB (the dataset item limit).
includeHeadersbooleannotrueReturn response headers (names lowercased).
includeBodybooleannotrueReturn the response body. Turn off when you only need status and extracted fields (smaller rows).
timeoutSecsintegerno—Maximum time for one attempt (connect, headers and body). Default 30. (alias: responseTimeout in milliseconds)
retriesintegerno—Retries on network errors, timeouts, 429 and 5xx, with exponential backoff and Retry-After. POST and PATCH are only retried when the server certainly did not process them (429, 503, connection refused). Default 2. (alias: retryOnFailure + maxRetries)
followRedirectsbooleannotrueFollow 3xx redirects (up to Max redirects). Off: the 3xx response itself is returned.
maxRedirectsintegerno10Maximum redirect hops per request.
concurrencyintegerno5Requests in flight at once across all hosts.
maxConcurrencyPerHostintegerno5Requests in flight at once to the same host, to stay under API rate limits.
failOnHttpErrorbooleannofalseMark the run as FAILED if any request got a non-2xx status, a network error or was invalid (rows are still saved). Default off: the status is recorded and the run succeeds.
callbackUrlstringno—Optional: each result row is also POSTed as JSON to this URL (e.g. a Clay table webhook, n8n or Make webhook). Supports {{field}} placeholders.
callbackHeadersobjectno—Headers for the callback request, e.g. {"x-clay-webhook-auth": "..."}.

Limits & honest notes

  • You pay only for requests that got a response from the server, whatever the status code (a 404 or 500 is still a response). Network failures, timeouts, invalid URLs, template errors and blocked targets are free.
  • Fast to start: a synchronous single-request call (run-sync-get-dataset-items) typically returns within a few seconds end to end, including the actor start, at 256 MB memory. Batches run up to 20 requests in parallel.
  • Up to 25,000 requests per run (requests × variables rows), 20 in flight at once. Synchronous API calls (run-sync) wait at most 300 seconds, so keep sync batches to a few hundred quick requests or use the dataset/callback for more.
  • Response bodies are capped at 2 MB by default and 9 MB at most (the Apify dataset item limit). Larger bodies are cut off and flagged with bodyTruncated. Truncated JSON is returned as text. The data field (riceman-compatible copy of body) is filled for bodies up to 1 MB.
  • Only public http and https targets. Localhost, private networks (10.x, 172.16-31.x, 192.168.x), link-local and cloud-metadata addresses (169.254.169.254) and .internal/.local hostnames are blocked, and the check is repeated on every redirect and at connect time, so DNS rebinding is blocked too. Host header overrides are rejected, and URLs with user:password@ are refused (send credentials as a header).
  • POST and PATCH are retried only when the server certainly did not process the request (429, 503 or connection refused), to avoid duplicate side effects. GET, PUT, DELETE, HEAD and OPTIONS are also retried on 500, 502 and 504. Retry-After waits are capped at 20 seconds.
  • Requests go out from Apify's shared datacenter IPs without a proxy. Sites that block datacenter traffic or need a browser (JavaScript, CAPTCHAs) are out of scope; this is a tool for APIs and webhooks.
  • Respects your run budget: set a maximum total charge and the run stops cleanly at the cap, with every delivered row charged exactly once.

Changelog

  • 2026-10-19 — Initial release: single and batch HTTP requests, {{variable}} templating, retries with backoff and Retry-After, redirects, per-host concurrency, JSON field extraction, webhook callbacks, secret Authorization header, SSRF protection, riceman/send-http-requests input compatibility.

Built and maintained by ActorForge. Reliability first: every actor in the portfolio is monitored by an automated nightly self-test, and breakages are typically fixed the same day.

⌂ 换网址