Run hundreds of HTTP requests
Hand over a list of up to 100 web calls, each with its own address, method, headers and body, and they run side by side with their own retries. Every result comes back together in one delivery. You pay per use, with no subscription.
fan out, collect results
Why a loop of outside calls is worth moving out
Most applications have a loop somewhere that calls outside services a few hundred times in a row: checking a list of addresses for uptime, fetching prices from many suppliers, or sending notices to a list of subscribers. Run inside the same process that serves your users, that loop competes with them for connections and processing time, and one slow service in the list can stall the whole run. Handing the list over as one batch takes that loop out of your application entirely.
How a batch runs and comes back
You send a list of up to 100 calls, each with its own address and, where needed, method, headers and body, and you get a task reference back straight away. Your calls run concurrently in the background, each with its own retry handling. When every one has settled, succeeded, failed or exhausted its retries, all the results arrive together. A pricing engine can refresh a dozen supplier prices at once this way, and an operations dashboard can check dozens of outside services and review them in one place.
What you can do with it
Multi-provider price fetching
A pricing engine calls a dozen supplier APIs at once to refresh product prices, instead of looping through them one at a time inside the application.
Third-party status monitoring
An internal ops dashboard batches status checks against dozens of external services it depends on and reviews the results once a batch completes.
FAQ
What happens if one request in the batch fails?
It's retried automatically up to three times, and if it still fails, the results clearly mark it as failed while the rest of the batch's successful responses are unaffected.
Is this good for scraping or scheduled polling?
It's built for controlled, purposeful fan-out like health checks, price fetching or notification delivery — it isn't a general scraping tool.
How many calls can one batch hold?
Up to 100. Each entry carries its own address and, if needed, its own method, headers and body, so a single batch can mix quite different calls to several services.
When do I get the results?
Once all calls in the batch have settled, whether they succeeded, failed or ran out of retries. You receive the complete picture in one delivery, so there is no need to keep asking for partial results.
Does a batch slow down my own server?
No. Your calls run in the background outside your application, so your own connections and the work serving your users are not touched while they are in flight. One slow service no longer holds up a loop in your code.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
One authenticated POST creates the task; the result comes back by webhook or a signed link. This capability is currently available through the API, not as an interactive Web tool.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/http-batch \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"requests":[{"url":"https://api.example.com/a","method":"GET"}]}'const res = await fetch("https://api.kit.forhosting.com/dev/http-batch", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"requests": [
{
"url": "https://api.example.com/a",
"method": "GET"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/http-batch",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"requests": [
{
"url": "https://api.example.com/a",
"method": "GET"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/http-batch", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"requests":[{"url":"https://api.example.com/a","method":"GET"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"requests":[{"url":"https://api.example.com/a","method":"GET"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/http-batch", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"requests": [
{
"url": "https://api.example.com/a",
"method": "GET"
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.http_batch",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Looping through five hundred API calls from your own server means five hundred open connections, five hundred chances to time out, and a script that has to babysit retries by hand. This endpoint takes the whole list, fires it, and hands back every response in one place once they're all in.
The script that shouldn't live in your app server
Somewhere in most codebases there's a loop that calls an external API a few hundred times in a row — pinging a list of URLs for uptime, fetching prices from a list of product endpoints, notifying a list of subscriber webhooks. Run inside the same process that serves user traffic, that loop competes for connections and CPU with the requests actually paying the bills, and one slow endpoint in the list can stall the whole batch. dev.http_batch pulls that loop out entirely.
What one call actually does
Send POST /dev/http-batch with a list of requests — each with its own URL, method, headers and body as needed — and get a task_id back immediately. The requests run concurrently in the background, each with its own retry handling, and nothing about your own server's connection pool or event loop is touched while they're in flight.
How results come back together
There's no partial-results polling to build; you get the complete picture in a single delivery. Once every request in the batch has settled — succeeded, failed, or exhausted its retries — the full set of results arrives as one payload, matched back to the request that produced each one, delivered by a signed webhook call or held behind a signed link valid for 24 hours.
Retries, failure, and honest pricing
Any individual request in the batch that fails is retried automatically up to three times before it's marked as a clear failure in the results, and a request that never succeeds is never charged — only completed requests count toward the flat $0.002 per-request price. That matters at scale: a batch of five hundred requests where twenty target a flaky third-party endpoint doesn't punish you for someone else's downtime.
Where this replaces a fragile cron job
A nightly script that pings two thousand customer webhook URLs to check they're still reachable, or a job that fetches exchange rates from a dozen providers before reconciling books, is exactly the kind of fan-out this endpoint was built for — submit the list once, let the batch run unattended, and read the results when they land instead of maintaining a bespoke concurrency-limited HTTP client.
Integration use cases
Health-checking customer webhook URLs
A platform that delivers webhooks to hundreds of customers batches a reachability check against every registered URL on a schedule, flagging endpoints that fail.
Bulk notification fan-out
An events platform sends the same update to hundreds of partner-registered callback URLs in one batch instead of queuing individual HTTP calls.
Technical questions
How do I send a batch of HTTP requests with this API?
POST a list of requests — each with its own URL, method, headers and body — to /dev/http-batch, keep the returned task_id, and collect all results by webhook or a signed link valid for 24 hours.
Is the batch HTTP request API free?
No, there is no free tier or trial; it costs a flat $0.002 per completed request within the batch, and failed requests are never charged.
How many requests can one batch contain?
The batch accepts a large list of requests in a single call; very large lists are simply processed concurrently and returned together once every request has settled.
Do I get results as they finish, or all at once?
Results are delivered as one complete payload once the entire batch has settled, matched back to the request that produced each one.
Can each request in the batch use a different method or headers?
Yes, every request in the list is independent, with its own URL, HTTP method, headers and body as needed.
Is this endpoint live?
Yes, /dev/http-batch is live and accepting requests now.