HTTP Request Sender: Bulk API Calls for Every CSV Row avatar

HTTP Request Sender: Bulk API Calls for Every CSV Row

Pricing

from $1.20 / 1,000 request sents

Go to Apify Store
HTTP Request Sender: Bulk API Calls for Every CSV Row

HTTP Request Sender: Bulk API Calls for Every CSV Row

Send HTTP requests to any REST API or webhook (GET/POST/PUT/PATCH/DELETE), singly or in bulk: one API call per row of a pasted CSV, JSON list or Apify dataset with {{column}} templates, plus JSON field extraction. Retries, secret auth, rate limits. $2 per 1,000 requests plus a $0.0005 start fee.

Pricing

from $1.20 / 1,000 request sents

Rating

0.0

(0)

Developer

Chris Elder

Chris Elder

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

5

Monthly active users

3 days ago

Last modified

Security

Limited permissions

Share

HTTP Request Sender: Bulk API Calls for Every CSV Row, Dataset or URL List

HTTP Request Sender sends HTTP requests to any REST API, webhook or URL and returns clean, structured results: status code, parsed JSON (or text/base64), response headers, redirect chain and timing. Send one request, perfect for Clay, Make, n8n, Zapier and AI agents that need "call this API" as a step, or thousands in bulk from a URL list, a pasted CSV / Google Sheet, or an Apify dataset. Write the request once with {{column}} placeholders, call the API for every row, and pull the JSON fields you need into clean columns, with rate limiting, retries and per-request labels.

No code, no server, no plan upgrade needed in your no-code tool: it is the missing "HTTP API" block, at $2 per 1,000 requests (from $1.20 on higher Apify plans) plus a $0.0005 start fee per run.

Store page: apify.com/chris_elder/http-request-sender

✅ Pay per result: $2 per 1,000 requests, from $1.20 on higher Apify plans, plus a $0.0005 start fee per run · 🆓 Timeouts, connection errors and blocked requests are never charged · 🔑 Your API key stays encrypted

▶ How to use it · 📄 Real example output · 💲 Pricing · 🔌 API & integrations · ❓ FAQ · 🛟 Support

Features

  • 🔧 All methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • 📦 JSON bodies (Content-Type set automatically), raw bodies (form data, XML), query parameters (arrays → repeated params)
  • 🔐 Secret auth header: put your API key in an encrypted input field; it's never logged, shown as *** in results and never forwarded to another domain on redirects
  • 📚 Bulk mode: a list of requests (URL strings or full objects with their own method, headers, body and label) with common headers/params merged in
  • 🧩 One request per row with {{column}} templates: paste a CSV (Sheets, Excel, Clay, HubSpot export) or a JSON list, write the URL / body / headers once, e.g. https://api.example.com/v1/people?email={{email}}. Values are URL- and JSON-escaped for you; rows with an empty value are skipped and not charged
  • 🎯 Extract JSON fields: {"email": "data.email", "title": "data.jobs[0].title"} turns each response into flat extracted/… columns, and the source row is copied next to it so results join straight back to your sheet
  • 🗂️ From a dataset / CSV: pass datasetId + urlField (optional labelField / methodField) to call an API once per row of another Actor's output or a CSV you uploaded to Apify
  • 🔁 Reliable: retries with exponential back-off on network errors, 429 and 5xx, honours Retry-After; POST/PATCH are not retried unless you allow it (no accidental double orders)
  • 🐢 Rate limiting: parallelism cap plus a per-host delay so you stay within the API's limits
  • 🧾 Smart responses: JSON parsed into objects, text kept as text, binaries (images, PDFs) returned as base64; size cap with a bodyTruncated flag
  • ↪️ Redirect chains reported (or turn following off)
  • 🚦 Optional fail the run on errors: great for automations that must stop when an API call fails
  • 🛡️ Requests to private/internal network addresses are refused for safety

How much does it cost?

$0.002 per request that gets a response (any status code), so $2 per 1,000, plus a $0.0005 Actor start fee per run (charged per GB of run memory). Higher Apify plans get automatic discounts (Silver $0.0016, Gold+ $0.0012).

EventFree / BronzeSilverGold+
Request sent$0.002$0.0016$0.0012
Actor start, × memory GB$0.0005$0.0005$0.0005

Requests that time out, can't connect or are refused for safety are free.

UsagePrice
1 request (e.g. one Clay row)$0.002 + $0.0005 start
1,000 requests$2 + $0.0005 start
50,000 requests$100 (Gold: $60) + $0.0005 start

How to use it

Single request (Clay, Make, n8n, Zapier, agents)

{
"url": "https://api.example.com/v1/companies",
"method": "POST",
"jsonBody": { "domain": "apify.com" },
"secretHeaderName": "Authorization",
"secretHeaderValue": "Bearer sk_live_..."
}

Bulk requests

{
"url": "",
"headers": { "Accept": "application/json" },
"requests": [
"https://api.github.com/repos/apify/crawlee",
{ "url": "https://httpbin.org/post", "method": "POST", "jsonBody": { "hello": "world" }, "label": "echo" },
{ "url": "https://httpbin.org/get", "queryParams": { "q": "apify" } }
],
"maxConcurrency": 5,
"delayBetweenRequestsMs": 200
}

Bulk from an Apify dataset (or CSV export)

Already have URLs in another Actor's dataset, or uploaded a CSV to Apify storage? Point this Actor at that dataset:

{
"url": "",
"datasetId": "YOUR_DATASET_ID",
"urlField": "url",
"labelField": "id",
"maxConcurrency": 5,
"delayBetweenRequestsMs": 200
}
  • datasetId: dataset ID/name, or an actor-run ID (uses that run's default dataset).
  • urlField: column with the URL (default url). Dots reach nested fields; a list of URLs in one cell expands to multiple requests.
  • labelField / methodField: optional columns for result labels and per-row HTTP methods.
  • Rows with a blank URL are skipped and never charged (skippedMissingUrl in RUN_SUMMARY).
  • You can combine requests and datasetId in one run. The Console Try-for-free sample URL is ignored automatically when a dataset is set.

Bulk mode tip: omit url (or set it to "") and put everything in requests. Console "Try for free" still prefills a single httpbin URL so one-click Start works; API callers who send only requests are not charged for that sample.

One request per row from a CSV or sheet ({{column}} templates)

Paste your rows, write the request once, get one result per row:

{
"method": "POST",
"csvText": "id,email,company\n1,ann@example.com,\"Acme, Inc\"\n2,,Globex\n3,bob@example.org,Initech",
"urlTemplate": "https://httpbin.org/anything/{{id}}?company={{company}}",
"bodyTemplate": "{\"email\": \"{{email}}\", \"id\": {{id}}}",
"headersTemplate": { "X-Row-Id": "{{id}}" },
"extractFields": { "sentEmail": "json.email", "companyArg": "args.company" },
"omitBodyWhenExtracting": true
}
  • csvText (or rows as a JSON list, or datasetId for another Actor's output) supplies the rows. Comma, semicolon and tab CSVs work; quoted values with commas are fine.
  • urlTemplate, bodyTemplate, headersTemplate, queryTemplate, labelTemplate, methodTemplate accept {{column}}, nested {{company.id}} and {{items[0].sku}}.
  • URL values are URL-encoded (Acme, Inc → Acme%2C%20Inc); JSON body values are escaped safely.
  • Row 2 has no email, so it is skipped and not charged (result row with errorCode: "TEMPLATE_MISSING_VALUE"). Set allowMissingValues: true to send blanks instead.
  • Each result carries row (your original columns) and extracted (the fields you asked for). In CSV/Excel export they appear as row/email, extracted/sentEmail … columns.

Result (real run, trimmed):

[
{ "label": "1", "method": "POST", "url": "https://httpbin.org/anything/1?company=Acme%2C%20Inc", "row": { "id": "1", "email": "ann@example.com", "company": "Acme, Inc" }, "statusCode": 200, "ok": true, "extracted": { "sentEmail": "ann@example.com", "companyArg": "Acme, Inc" } },
{ "label": "2", "url": "https://httpbin.org/anything/2?company=Globex", "ok": false, "errorCode": "TEMPLATE_MISSING_VALUE", "error": "Row 2: empty or missing value for {{email}} (not sent, not charged)" },
{ "label": "3", "url": "https://httpbin.org/anything/3?company=Initech", "statusCode": 200, "ok": true, "extracted": { "sentEmail": "bob@example.org", "companyArg": "Initech" } }
]

Typical uses: enrich a lead list against your own CRM or enrichment API, push every row of a sheet to a webhook, check hundreds of records against a REST API, or call an internal API for each item another Actor scraped.

Example: 2 requests in → 2 result rows out

RequestResult row
GET https://httpbin.org/get?q=apifystatusCode: 200, ok: true, body.args.q = "apify"
POST https://httpbin.org/post with {"hello":"world"}, label echostatusCode: 200, ok: true, body.json = {"hello":"world"}, label: "echo"

Output example (from a real public run)

Public run data (no login needed): dataset JSON · dataset CSV

Second row (the POST), shortened with ...:

{
"index": 1,
"label": "echo",
"method": "POST",
"url": "https://httpbin.org/post",
"requestHeaders": { "content-type": "application/json" },
"statusCode": 200,
"ok": true,
"finalUrl": "https://httpbin.org/post",
"redirectChain": [],
"contentType": "application/json",
"responseBytes": 630,
"bodyTruncated": false,
"body": { "args": {}, "data": "{\"hello\":\"world\"}", "json": { "hello": "world" }, "url": "https://httpbin.org/post", "...": "..." },
"bodyFormat": "json",
"durationMs": 211,
"responseHeaders": { "content-type": "application/json", "...": "..." }
}

When you use the secret header, its value is shown as *** in requestHeaders.

Failed requests appear with statusCode: null, an error message and an errorCode (e.g. TIMEOUT, ENOTFOUND), and are not charged. A RUN_SUMMARY record counts responses, non-2xx answers and failures.

Using it from Clay

Add an Apify enrichment column, choose HTTP Request Sender, map the row's values into url, queryParams or jsonBody, and read body from the result. Each row costs $0.002, plus a $0.0005 start fee per run.

Integrations (API, AI agents, Make, Zapier, n8n)

curl -X POST "https://api.apify.com/v2/acts/chris_elder~http-request-sender/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://httpbin.org/post","method":"POST","jsonBody":{"hello":"world"}}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("chris_elder/http-request-sender").call(run_input={
"url": "", # only use the bulk list
"requests": [{"url": "https://httpbin.org/get", "queryParams": {"q": "apify"}}],
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["statusCode"], row["body"])

MCP (AI agents): https://mcp.apify.com/?tools=chris_elder/http-request-sender

Make / Zapier / n8n: use the Apify Run Actor module with chris_elder/http-request-sender and read the dataset rows. Works with Apify schedules and webhooks.

Good to know

  • Call only APIs and endpoints you are allowed to use, and respect their terms and rate limits. This Actor is a neutral HTTP client; it does not bypass authentication, CAPTCHAs or bot protection.
  • Maximum response size per request is 8 MB (default 5 MB). For large downloads use a dedicated file downloader.
  • The secret header is added to every request in the run; don't mix endpoints of different providers in one run if they need different keys.

FAQ

Can I send form data? Yes, put a=1&b=2 in Raw body and add the header Content-Type: application/x-www-form-urlencoded.

Does it support GraphQL? Yes, POST {"query": "...", "variables": {...}} as the JSON body.

Is my API key safe? The field is encrypted by Apify, never written to logs or results, and dropped on cross-domain redirects.

Can I call a webhook? Yes, POST your JSON to the webhook URL; the response comes back as a row.

Can I send one request per CSV / dataset row? Yes, paste the CSV into csvText (or set datasetId) and write urlTemplate / bodyTemplate with {{column}} placeholders. Without templates, datasetId + urlField still works as before. Rows with empty values or blank URLs are skipped free.

Can I keep only a few fields from each response? Yes, extractFields maps output names to JSON paths (data.items[0].email); add omitBodyWhenExtracting for slim exports.

Something missing? Open an issue on the Actor page.

Support, reliability and feature requests

  • Requests that time out, can't connect or are refused for safety are free.
  • Every release is tested on real public endpoints; the example input works.
  • Issues answered within 2 business days via the Actor Issues tab.
  • Breaking input or price changes are announced in this README first.

Built by GPT Shop Ltd with AI-assisted development; every release is reviewed and tested.

More tools from GPT Shop Ltd

Bulk File Downloader · Dataset Transformer · Sitemap URL Extractor · Bulk WHOIS Lookup · all tools

Done-for-you

Need this run for you or customised? Done-for-you data from £49: https://tools.gptshopltd.com/done-for-you-scraper/