# Universal Request Runner — Send Any HTTP Request (`vasram/universal-request-runner`) Actor

Send any HTTP request (GET/POST/PUT/PATCH/DELETE) to any URL with custom headers, body & proxies. Supports sticky sessions (same IP across runs) — ideal for start a job then poll its status from one identity. No code needed.

- **URL**: https://apify.com/vasram/universal-request-runner.md
- **Developed by:** [Vasram Sonagara](https://apify.com/vasram) (community)
- **Categories:** Other, Developer tools, Automation
- **Stats:** 1 total users, 1 monthly users, 98.3% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.00005 / actor start

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Universal Request Runner

**Send any HTTP request to any URL — with Apify Proxy and session support built in.**

Universal Request Runner is a lightweight HTTP client Actor for the Apify platform. Send `GET`, `POST`, `PUT`, `PATCH`, or `DELETE` requests to any API or endpoint — with custom headers, a custom body, and Apify's proxy network — directly from the cloud. No code, no server, no Postman required.

***

### What can you do with it?

- **Call any REST API** — send an API key in the headers and JSON in the body, get the parsed response back.
- **Send webhooks and form submissions** — POST data to any endpoint from the cloud, on a schedule.
- **Bypass IP blocks** — route requests through Apify's residential proxy network.
- **Use sessions** — attach a `sessionId` to keep requests on a consistent proxy identity.
- **Automate API calls** — trigger runs via schedule, the Apify API, or integrations like Make, Zapier, and n8n.

***

### Why use this Actor instead of curl or Postman?

| Need | curl / Postman | Universal Request Runner |
| --- | --- | --- |
| Run from the cloud on a schedule | ❌ | ✅ Built-in scheduling |
| Use residential proxy IPs | ❌ Manual setup | ✅ One toggle |
| Consistent identity via sessions | ❌ Hard to manage | ✅ Just set a `sessionId` |
| Auto-save every response | Manual | ✅ Saved to dataset + key-value store |
| Share with non-developers | ❌ | ✅ Just a form, no code |

***

### How to use it

1. Open the Actor on [Apify Store](https://apify.com/vasram/universal-request-runner) and click **Try for free**.
2. Fill in the input form — only **Target URL** and **HTTP Method** are required.
3. *(Optional)* Enable **Proxy Configuration → Apify Proxy** to route through residential IPs.
4. *(Optional)* Add a **Session ID** to keep requests on the same proxy identity.
5. Click **Start**. The response appears under **Output** and **Dataset** within seconds.

You can also run it on a schedule, or trigger it via the Apify API, Zapier, Make, or n8n.

***

### Input

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | ✅ | Target URL, e.g. `https://api.example.com/v1/users` |
| `method` | enum | ✅ | `GET`, `POST` (default), `PUT`, `PATCH`, `DELETE` |
| `headers` | object | ❌ | Custom headers as JSON, e.g. `{"Authorization": "Bearer xyz"}` |
| `body` | string | ❌ | Request body — JSON or plain text. JSON is detected automatically and sent with `Content-Type: application/json`. Ignored for `GET`/`DELETE`. |
| `sessionId` | string | ❌ | Optional session identifier. Requests sharing the same `sessionId` are routed through the same proxy session. Requires a proxy to be enabled. |
| `proxyConfiguration` | object | ❌ | Apify Proxy editor. Enable `useApifyProxy` for residential IPs. |
| `timeoutSecs` | integer | ❌ | Request timeout in seconds (default `30`). |

**Sample input:**

```json
{
    "url": "https://httpbin.org/post",
    "method": "POST",
    "headers": {
        "Authorization": "Bearer my_token_123",
        "X-Custom-Header": "hello"
    },
    "body": "{\"name\": \"Alice\", \"age\": 30}",
    "sessionId": "mysession1",
    "proxyConfiguration": { "useApifyProxy": true }
}
```

***

### Output

Every run writes one record to the default dataset, and stores the latest result under the key `OUTPUT` in the key-value store.

```json
{
    "url": "https://httpbin.org/post",
    "method": "POST",
    "statusCode": 200,
    "statusMessage": "OK",
    "responseHeaders": {
        "content-type": "application/json"
    },
    "responseBody": {
        "json": { "name": "Alice", "age": 30 },
        "origin": "203.0.113.7",
        "url": "https://httpbin.org/post"
    }
}
```

JSON responses are automatically parsed into an object. HTML or plain-text responses are kept as raw strings — nothing is lost.

If a request fails, the record contains `error` and `stack` instead of the response fields, so you can diagnose it from the **Failed Requests** dataset view. Download results as JSON, HTML, CSV, or Excel from the Console.

***

### Pricing

This Actor uses Apify's **Pay-Per-Event (PPE)** model — pay only for what you use.

| Event | When it's charged | Price |
| --- | --- | --- |
| `request-sent` | Once, right before the HTTP request is sent | ~$0.01 per run |

Total cost = the event fee above + Apify's compute cost (billed separately, based on runtime and memory). Since a single request completes in 1–3 seconds, compute cost per run is negligible. No subscriptions, no rental fees — you pay only when a request is actually sent. See exact pricing on the [Actor's Store page](https://apify.com/vasram/universal-request-runner) before running.

***

### Run locally

```bash
## 1. Install the Apify CLI
npm install -g apify-cli

## 2. Authenticate
apify login

## 3. Install dependencies
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

## 4. Run with a test input
apify run --input-file ../test-input.json
```

Results are written to the local `storage/` directory. Local storage isn't pushed to the Apify Console — deploy to see results there. To test with a proxy locally, include `proxyConfiguration` with `useApifyProxy: true` in your input (uses your account's proxy quota).

***

### Deploy to Apify

```bash
apify login
apify push
```

Then open the Actor under **Actors → My Actors**, configure **Proxy Configuration**, and click **Start**.

***

### Tips

- **JSON body:** just paste JSON — `Content-Type: application/json` is set automatically. Override by setting the header yourself if needed.
- **GET / DELETE:** the `body` field is ignored for these methods.
- **Redirects:** not followed by default, so you see the raw `3xx` response.
- **One request per run, by design** — keeps the Actor simple and composable. Chain runs via the Apify API, scheduling, or integrations like Make/n8n, and reuse a `sessionId` where a consistent identity is needed.

***

### FAQ

**Does it work without an Apify account?**
Locally, yes — requests are sent directly. On the platform, you need an Apify account; proxy usage needs proxy quota.

**Can I send multiple requests in one run?**
No, by design. One request per run keeps it simple and composable — chain runs together for multi-step flows.

**Is my API token or Authorization header logged?**
No. The Actor uses Apify's logger, which censors sensitive data. Your headers are sent only to the target URL.

**Why is there a charge per run?**
It covers infrastructure, maintenance, and proxy support — kept as a small markup over Apify's raw compute cost.

***

**Disclaimer:** This Actor is a generic HTTP client. You are responsible for complying with the target service's Terms of Service and applicable law.

# Actor input Schema

## `url` (type: `string`):

The full web address to send the request to. Must start with http:// or https://. Example: https://api.example.com/v1/users

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

What kind of request to send. GET = read data. POST = create/submit. PUT/PATCH = update. DELETE = remove. Most APIs use POST or GET.

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

Extra info sent with the request (like an API key or content type), as a JSON object. Example: {"Authorization": "Bearer my\_token123", "Accept": "application/json"}. Leave empty ({}) if not needed.

## `body` (type: `string`):

Data to send with POST/PUT/PATCH requests. You can paste JSON like {"name": "Alice", "age": 30} OR plain text. If it looks like JSON, we automatically set the right content type for you. Ignored for GET/DELETE.

## `sessionId` (type: `string`):

USE THIS to keep the SAME IP address across multiple Actor runs. Enter any word or number (e.g. mysession1). Every run that uses the SAME session ID goes out from the SAME IP address.

Example use case: Run #1 with session=sess1 starts a video generation from IP A. Run #2 with the same session=sess1 will check its status FROM THE SAME IP A.

Leave empty for a fresh random IP each time. NOTE: Only works when a proxy is enabled below.

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

Route your request through Apify's proxy network (residential IPs from real devices — harder for websites to block). Click the toggle below to enable. When OFF, the request goes out directly from your own IP. REQUIRED for the Session ID above to work. RECOMMENDED for production use.

## `useCurlCffi` (type: `boolean`):

Turn ON to send the request using curl\_cffi instead of httpx. curl\_cffi mimics a real browser's TLS/HTTP2 fingerprint, which helps bypass advanced anti-bot protection (Cloudflare, Akamai, Datadome, PerimeterX). Leave OFF for normal APIs that don't block requests. Requires the 'curl\_cffi' package in the Actor image.

## `impersonate` (type: `string`):

Which browser fingerprint to mimic when 'Use curl\_cffi' is ON. Ignored when OFF. Use 'chrome' (default, latest available) for most sites, or a specific version like 'chrome131', 'safari', 'edge'. If the value is unsupported, the Actor falls back to plain 'chrome'.

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

How long to wait for a response before giving up. Default 30 seconds. Increase for slow APIs.

## Actor input object example

```json
{
  "url": "https://httpbin.org/post",
  "method": "POST",
  "headers": {},
  "body": "",
  "sessionId": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "useCurlCffi": false,
  "impersonate": "chrome",
  "timeoutSecs": 30
}
```

# Actor output Schema

## `dataset` (type: `string`):

Every request's response — status code, headers, and parsed/raw body — appended as a row here. Downloadable as JSON, CSV, HTML, or Excel.

## `latestResult` (type: `string`):

The most recent result saved under the OUTPUT key in the key-value store (JSON). Useful for piping into the next step of a workflow.

## `allRecords` (type: `string`):

Browse all saved records in the default key-value store, including the OUTPUT record.

## `run` (type: `string`):

Details and logs for this specific run.

# 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 = {
    "url": "https://httpbin.org/post",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("vasram/universal-request-runner").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 = {
    "url": "https://httpbin.org/post",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("vasram/universal-request-runner").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "url": "https://httpbin.org/post",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call vasram/universal-request-runner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=vasram/universal-request-runner",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6ogrLTcTheMYd1YTc/builds/2euhiw7w7YGZqEx0U/openapi.json
