# HTTP Request API — Bulk GET/POST Calls Without a Browser (`fabrikit/http-request-api`) Actor

Send GET, POST, PUT, PATCH, DELETE or HEAD requests in bulk and get one record per request: status, headers, body, parsed JSON, jsonPath/CSS extract, redirects and timing. Retries, concurrency, optional proxy and a Standby HTTP API for agents and n8n. From US$3.50 per 1,000 requests.

- **URL**: https://apify.com/fabrikit/http-request-api.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 http request answereds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## HTTP Request API — Bulk GET/POST Calls Without a Browser

HTTP Request API sends a list of HTTP requests (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) to any public URL or REST API and returns **one JSON record per request**: status code, response headers, body (text or base64), parsed JSON, an optional fragment picked with a `jsonPath` or a CSS `selector`, the redirect chain and timings. Retries with backoff, concurrency, rate limiting and an optional Apify proxy are built in, and the same engine answers synchronously as a **Standby HTTP API** for AI agents, n8n, Make and scripts.

No browser, no crawling: only the URLs you list are fetched. **From US$3.50 per 1,000 answered requests**; requests that never get an answer are free.

### What it is for

- Call a REST API hundreds or thousands of times from one input (IDs, pages, search terms) and get a clean dataset.
- Health-check a list of endpoints: status, latency, redirects, certificate and DNS errors recorded per URL.
- Fetch raw HTML or JSON for a list of pages and pull out just one value (`title`, `a@href`, `data.items[*].id`).
- Give an AI agent or an n8n/Make workflow a single, safe HTTP tool with retries, proxies and size limits instead of raw `fetch`.
- Replay POST/PUT/PATCH/DELETE calls in bulk (webhooks, form submissions, API mutations) with per-request bodies.

### Input

| Field | Description |
|---|---|
| `requests` | List of URL strings or objects `{ url, method, headers, body \| json \| form, label, jsonPath, selector, timeoutSecs }`. Per-request fields override the global ones. |
| `method` | Default method for entries without one (`GET`). |
| `headers` | Headers added to every request (authorization, accept, API keys). |
| `jsonPath`, `selector` | Global extraction: dotted path for JSON answers (`data.items[*].id`, `results[0].name`, `["key.with.dots"]`) or CSS selector for HTML (`h1`, `meta[name=description]@content`). |
| `timeoutSecs`, `maxRetries`, `concurrency`, `minDelayMs` | 30 s per attempt, 2 retries with exponential backoff (Retry-After honoured), 5 requests in flight, optional gap between requests for rate-limited APIs. |
| `followRedirects` | Follow up to 10 redirects and report the chain (`true`), or get the 3xx answer itself. |
| `maxBodyChars`, `includeBody`, `includeResponseHeaders`, `parseJson` | Control the size and content of each record. Bodies are cut at 200,000 characters by default and flagged `truncated`; downloads stop at 10 MB. |
| `browserLikeHeaders` | Realistic browser User-Agent/Accept/TLS fingerprint (default) or a plain `http-request-api/0.1` User-Agent for APIs. Your own headers always win. |
| `proxyConfiguration` | Off by default. Choose Apify datacenter proxy to rotate IPs or residential proxy for sites that block datacenter ranges; the Actor never upgrades to residential on its own. |

#### Example: mixed batch

```json
{
  "requests": [
    { "label": "repo", "url": "https://api.github.com/repos/apify/apify-sdk-js", "jsonPath": "stargazers_count" },
    { "label": "create", "url": "https://httpbin.org/post", "method": "POST", "json": { "name": "demo" }, "jsonPath": "json.name" },
    { "label": "form", "url": "https://httpbin.org/patch", "method": "PATCH", "form": { "a": "1" } },
    { "label": "page", "url": "https://example.com/", "selector": "title" },
    { "label": "ping", "url": "https://example.com/", "method": "HEAD" }
  ],
  "headers": { "accept": "application/json" },
  "concurrency": 5,
  "maxRetries": 2
}
```

#### Example: the same API call for many IDs

```json
{
  "requests": [
    "https://api.example.com/v1/products/101",
    "https://api.example.com/v1/products/102",
    "https://api.example.com/v1/products/103"
  ],
  "headers": { "authorization": "Bearer YOUR_TOKEN" },
  "jsonPath": "data.price",
  "includeBody": false
}
```

### Output

One record per input entry, in input order (also for failed and invalid entries, so nothing is lost):

```json
{
  "index": 0,
  "label": "repo",
  "url": "https://api.github.com/repos/apify/apify-sdk-js",
  "method": "GET",
  "finalUrl": "https://api.github.com/repos/apify/apify-sdk-js",
  "redirected": false,
  "redirectChain": [],
  "ok": true,
  "sent": true,
  "statusCode": 200,
  "statusText": "OK",
  "contentType": "application/json; charset=utf-8",
  "contentLength": 7013,
  "responseHeaders": { "content-type": "application/json; charset=utf-8", "x-ratelimit-remaining": "58", "...": "..." },
  "body": "{\"id\":120862636,\"name\":\"apify-sdk-js\",\"full_name\":\"apify/apify-sdk-js\", ...",
  "bodyEncoding": "text",
  "bodyBytes": 7013,
  "truncated": false,
  "json": { "id": 120862636, "full_name": "apify/apify-sdk-js", "stargazers_count": 124, "...": "..." },
  "extracted": 124,
  "extractError": null,
  "responseTimeMs": 727,
  "totalTimeMs": 742,
  "attempts": 1,
  "proxy": "none",
  "error": null,
  "requestedAt": "2026-10-21T04:18:21.512Z"
}
```

A 404 comes back with `sent: true`, `ok: false`, `error: "HTTP 404 Not Found"` and its body; a timeout or DNS failure with `sent: false`, `statusCode: null` and the reason in `error`. Binary answers (images, PDFs) are stored base64-encoded with `bodyEncoding: "base64"`.

### Standby HTTP API

Once Standby is enabled for the Actor, call it directly and get the record back in the same HTTP response:

```
GET https://fabrikit--http-request-api.apify.actor/?url=https://httpbin.org/get&jsonPath=origin&token=YOUR_APIFY_TOKEN
POST https://fabrikit--http-request-api.apify.actor/?token=YOUR_APIFY_TOKEN
     {"url": "https://httpbin.org/post", "method": "POST", "json": {"a": 1}, "headers": {"x-key": "..."}}
POST ... {"requests": ["https://example.com/", "https://httpbin.org/get"], "selector": "title"}   (up to 20 per call)
```

Add `format=raw` to relay the upstream status, content type and body as they are (a tiny HTTP relay for tools that cannot set headers or follow redirects themselves). Query and JSON fields take the same names as the Actor input.

### Pricing

| Event | Price |
|---|---|
| `request-sent` — a request that reached a server and got an HTTP status (2xx, 3xx, 4xx or 5xx) | US$3.50 per 1,000 |

1,000 answered requests cost US$3.50; 10,000 cost US$35. DNS failures, timeouts, refused connections, blocked private targets and invalid input entries are recorded but **not charged**, and neither are retries: one request is one event however many attempts it took. Platform compute is included; Apify proxy traffic is billed by the platform only if you turn a proxy on.

### Compared with alternatives

- **Other bulk HTTP request Actors on Apify Store** typically list US$5 per 1,000 requests and charge every attempt; this one is US$3.50, charges only answered requests, keeps the dataset in input order and includes jsonPath/CSS extraction, redirect chains and a Standby API.
- **curl / fetch in your own script** is free but gives you no dataset, scheduling, proxy rotation, retries or size caps; this Actor is for lists, workflows and agents, not for one-off calls.
- **Apify's Web Scraper / Cheerio Scraper** render or parse whole pages; here you keep the raw answer and pick one fragment, which is what APIs and health checks need.
- Need the readable text of a web page as Markdown instead of the raw body? Use our [URL to Markdown API](https://apify.com/fabrikit/url-to-markdown-api), which shares the same fetch layer.

### Integrations

Run it from the Apify API or the JavaScript/Python clients, schedule it, or plug it into n8n, Make, Zapier and LangChain through the Apify integrations. In Standby mode the Actor behaves like a plain HTTPS endpoint, so any tool that can make a GET or POST call (an MCP server, a custom GPT action, a cron job) can use it as its HTTP tool with retries, proxies and safety limits handled for it.

### FAQ

**Is this legal?** The Actor is a generic HTTP client. You are responsible for the requests you send: respect the terms of the APIs and sites you call, their rate limits and the law that applies to you. Do not use it to attack, flood or scan hosts.

**Can it reach private or internal hosts?** No. Private, loopback, link-local and cloud-metadata addresses, `localhost`/`.local`/`.internal` names, URLs with embedded credentials and common service ports (SSH, mail, databases) are refused, on every redirect hop too. These entries are recorded with `error: "Blocked target: ..."` and are free.

**Do I need a proxy?** Not for APIs and most sites: by default requests leave from the Actor's own IP. Turn on Apify datacenter proxy to rotate IPs, or residential proxy (extra platform cost) only for sites that block datacenter ranges. The Actor never switches proxies without you.

**How large can a response be?** Up to 10 MB is downloaded per request; the stored `body` is cut at `maxBodyChars` (200,000 by default) and `truncated` tells you when. JSON is parsed from the full download, so `json` and `extracted` are complete even when the stored body is cut.

**What are the limits?** Up to 10,000 requests per run, 20 in flight, 10 redirects per request, 120 s timeout per attempt, 5 retries. Keep `concurrency` and `minDelayMs` within what the target allows.

**Does it run JavaScript?** No. It returns what the server sends. For pages that only render in a browser use a browser-based Actor.

### Changelog

- **0.1** (October 2026) — first release: batch and Standby modes, 7 methods, JSON/form/raw bodies, jsonPath and CSS extraction, retries with backoff, redirect chain, size caps, SSRF protection, optional Apify proxy.

***

### En español

**HTTP Request API** envía en lote peticiones HTTP (GET, POST, PUT, PATCH, DELETE, HEAD) a cualquier URL o API pública y devuelve un registro por petición: código de estado, cabeceras, cuerpo (texto o base64), JSON parseado, un fragmento extraído con `jsonPath` o un selector CSS, la cadena de redirecciones y los tiempos. Incluye reintentos con espera exponencial, concurrencia, límite de tamaño, proxy opcional de Apify y un modo Standby para usarlo como endpoint HTTP desde agentes de IA, n8n o Make. Bloquea direcciones privadas e internas. Desde **US$3,50 por 1.000 peticiones respondidas**; las que no obtienen respuesta no se cobran.

# Actor input Schema

## `requests` (type: `array`):

Requests to send, in order. Each entry is a URL string (sent with the default method) or an object: { "url", "method", "headers", "body" or "json", "form", "label", "jsonPath", "selector", "timeoutSecs" }. Per-request headers are merged over the global ones. https:// is assumed when the scheme is missing. Public hosts only.

## `method` (type: `string`):

Method for entries that do not set their own.

## `headers` (type: `object`):

Headers added to every request, e.g. { "authorization": "Bearer ...", "accept": "application/json" }. Per-request headers override them.

## `jsonPath` (type: `string`):

Dotted path applied to every JSON response to fill the extracted field, e.g. data.items\[\*].id or results\[0].name. Per-request jsonPath overrides it.

## `selector` (type: `string`):

CSS selector applied to every HTML response to fill the extracted field with the matched texts, e.g. h1 or a@href for an attribute. Per-request selector overrides it. Ignored when a jsonPath applies.

## `timeoutSecs` (type: `integer`):

Give up on a request after this many seconds per attempt.

## `maxRetries` (type: `integer`):

Extra attempts after a network error or an HTTP 408, 425, 429 or 5xx answer, with exponential backoff (Retry-After is honoured up to 30 s).

## `concurrency` (type: `integer`):

Requests in flight at the same time.

## `minDelayMs` (type: `integer`):

Minimum gap between two request starts, for rate-limited APIs (0 = none).

## `followRedirects` (type: `boolean`):

Follow up to 10 redirects and report the chain. Turn off to get the 3xx answer itself.

## `maxBodyChars` (type: `integer`):

Cut the body field at this many characters (binary bodies are base64). truncated is set to true when the cut happens. 0 drops the body but keeps json and extracted.

## `includeBody` (type: `boolean`):

Store the response body. Turn off when you only need status, headers, json or the extracted fragment.

## `includeResponseHeaders` (type: `boolean`):

Store the response headers in responseHeaders.

## `parseJson` (type: `boolean`):

Fill the json field with the parsed object when the response is JSON.

## `browserLikeHeaders` (type: `boolean`):

Send a realistic browser User-Agent, Accept and TLS fingerprint (good for websites). Turn off to send a plain User-Agent (good for APIs). Your own headers always win.

## `proxyConfiguration` (type: `object`):

No proxy by default: requests go out from the Actor's own IP. Pick Apify datacenter proxy to rotate IPs, or residential proxy (extra cost) only if the target blocks datacenter IPs. The Actor never switches to residential on its own.

## Actor input object example

```json
{
  "requests": [
    {
      "label": "get",
      "url": "https://httpbin.org/get?demo=1",
      "jsonPath": "args.demo"
    },
    {
      "label": "post",
      "url": "https://httpbin.org/post",
      "method": "POST",
      "json": {
        "hello": "world"
      },
      "jsonPath": "json.hello"
    },
    {
      "label": "github",
      "url": "https://api.github.com/repos/apify/apify-sdk-js",
      "jsonPath": "stargazers_count"
    },
    {
      "label": "html",
      "url": "https://example.com/",
      "selector": "title"
    }
  ],
  "method": "GET",
  "headers": {},
  "timeoutSecs": 30,
  "maxRetries": 2,
  "concurrency": 5,
  "minDelayMs": 0,
  "followRedirects": true,
  "maxBodyChars": 200000,
  "includeBody": true,
  "includeResponseHeaders": true,
  "parseJson": true,
  "browserLikeHeaders": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `responses` (type: `string`):

One item per request sent

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "requests": [
        {
            "label": "get",
            "url": "https://httpbin.org/get?demo=1",
            "jsonPath": "args.demo"
        },
        {
            "label": "post",
            "url": "https://httpbin.org/post",
            "method": "POST",
            "json": {
                "hello": "world"
            },
            "jsonPath": "json.hello"
        },
        {
            "label": "github",
            "url": "https://api.github.com/repos/apify/apify-sdk-js",
            "jsonPath": "stargazers_count"
        },
        {
            "label": "html",
            "url": "https://example.com/",
            "selector": "title"
        }
    ],
    "headers": {},
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/http-request-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "requests": [
        {
            "label": "get",
            "url": "https://httpbin.org/get?demo=1",
            "jsonPath": "args.demo",
        },
        {
            "label": "post",
            "url": "https://httpbin.org/post",
            "method": "POST",
            "json": { "hello": "world" },
            "jsonPath": "json.hello",
        },
        {
            "label": "github",
            "url": "https://api.github.com/repos/apify/apify-sdk-js",
            "jsonPath": "stargazers_count",
        },
        {
            "label": "html",
            "url": "https://example.com/",
            "selector": "title",
        },
    ],
    "headers": {},
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/http-request-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "requests": [
    {
      "label": "get",
      "url": "https://httpbin.org/get?demo=1",
      "jsonPath": "args.demo"
    },
    {
      "label": "post",
      "url": "https://httpbin.org/post",
      "method": "POST",
      "json": {
        "hello": "world"
      },
      "jsonPath": "json.hello"
    },
    {
      "label": "github",
      "url": "https://api.github.com/repos/apify/apify-sdk-js",
      "jsonPath": "stargazers_count"
    },
    {
      "label": "html",
      "url": "https://example.com/",
      "selector": "title"
    }
  ],
  "headers": {},
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call fabrikit/http-request-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/http-request-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/g6PCiy7fd76Jj1eBa/builds/nT4pNDflxkrx3w1pW/openapi.json
