HTTP Request Execution
Section titled “HTTP Request Execution”Execute HTTP requests with full libcurl configuration, manage asynchronous background jobs, and subscribe to real-time job lifecycle events over WebSocket. The execution API supports both synchronous (immediate response) and asynchronous (background job) modes, with options for response wrapping, cookie sessions, retries, proxy configuration, and automatic response storage.
GET /api/v1/curl/request
Section titled “GET /api/v1/curl/request”Simplified interface for executing HTTP requests using URL query parameters. Best suited for simple GET requests and quick testing. For advanced features, use the POST variant.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
url | query | string | Yes | Target URL |
method | query | string | No | HTTP method (default: GET) |
response | query | string | No | Response mode: transparent or json (default: json) |
mode | query | string | No | Execution mode: sync or async (default: sync) |
session_id | query | string | No | Session ID for cookie persistence |
follow_redirects | query | boolean | No | Follow redirects (default: true) |
timeout | query | integer | No | Timeout in seconds |
user_agent | query | string | No | User-Agent header |
referer | query | string | No | Referer header |
bearer_token | query | string | No | Bearer token |
save | query | boolean | No | Save to storage |
save_path | query | string | No | Custom save path, relative to downloads/by-job/{job_id} (no absolute paths or ..) |
insecure | query | boolean | No | Allow insecure SSL |
compressed | query | boolean | No | Request compressed |
job_name | query | string | No | Job name for async |
data | query | string | No | Raw request body (curl —data); alias body; presence upgrades default method to POST |
json | query | string | No | JSON request body, sent with Content-Type: application/json (curl —json); upgrades default method to POST |
header | query | string | No | Custom header as Name: Value. Repeatable — supply once per header |
data_base64 | query | string | No | Base64 request body (binary-safe; standard or URL-safe); alias body_base64. Takes precedence over data/json; upgrades default method to POST |
curl -X GET "https://api.hoody.com/api/v1/curl/request?url=https%3A%2F%2Fapi.example.com%2Fdata&method=GET&response=json&timeout=30"const result = await client.curl.executeCurlRequestGet({ url: "https://api.example.com/data", method: "GET", response: "json", timeout: 30});{ "success": true, "status_code": 200, "headers": { "content-type": "application/json", "server": "nginx/1.24.0" }, "body": "{\"items\":[{\"id\":1,\"name\":\"Widget\"}]}", "is_binary": false, "job_id": null, "timing": { "namelookup": 0.012, "connect": 0.043, "pretransfer": 0.045, "starttransfer": 0.128, "redirect": 0.0, "total": 0.135 }, "metadata": { "effective_url": "https://api.example.com/data", "content_type": "application/json", "redirect_count": 0, "size_download": 31, "size_upload": 0, "speed_download": 229.6, "speed_upload": 0 }}{ "job_id": "01HMZ8X9K2QF3N5P7R8T6V4WYD", "status": "pending", "message": "Request accepted for async execution"}{ "statusCode": 400, "error": "Bad Request", "message": "Missing required parameter: url"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_URL | Missing or invalid URL | URL parameter is required and must be valid | Provide url parameter with complete URL including protocol |
INVALID_PARAMETER | Invalid query parameter | One or more query parameters have invalid values | Check parameter values match expected types (e.g., timeout as number) |
{ "statusCode": 500, "error": "Internal Server Error", "message": "Network connection failed"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NETWORK_ERROR | Network request failed | Failed to execute HTTP request via cURL | Verify target URL accessibility and network connectivity |
POST /api/v1/curl/request
Section titled “POST /api/v1/curl/request”Execute an HTTP request using libcurl with comprehensive configuration options. Supports both synchronous (immediate response) and asynchronous (background job) execution modes. Includes advanced features like retry logic, cookie sessions, proxy configuration, and automatic response storage.
Execution Modes:
sync(default): Blocks until completion, returns immediate responseasync: Returns job ID immediately, executes in background
Response Modes:
transparent(default): Returns raw response with original headersjson: Wraps response in JSON with timing metrics and metadata
Example Use Cases:
- API integration with automatic retry
- Large file downloads with progress tracking
- Multi-step authentication flows with session cookies
- Scheduled recurring requests with cron expressions
This endpoint takes no query, path, or header parameters.
Request Body
Section titled “Request Body”The request body uses the curl_CurlRequest schema. url is the only required field; all other fields are optional. Unknown fields are rejected.
curl -X POST "https://api.hoody.com/api/v1/curl/request" \ -H "Content-Type: application/json" \ -d '{ "url": "https://api.example.com/v1/orders", "method": "POST", "mode": "sync", "response": "json", "headers": { "Content-Type": "application/json", "X-Request-ID": "req-7f3a9b" }, "json": { "sku": "WDG-001", "quantity": 2 }, "bearer_token": "eyJhbGciOiJIUzI1NiIs...", "timeout": 30, "retry_count": 3, "retry_delay": 5, "follow_redirects": true }'const result = await client.curl.execute({ url: "https://api.example.com/v1/orders", method: "POST", mode: "sync", response: "json", headers: { "Content-Type": "application/json", "X-Request-ID": "req-7f3a9b" }, json: { sku: "WDG-001", quantity: 2 }, bearer_token: "eyJhbGciOiJIUzI1NiIs...", timeout: 30, retry_count: 3, retry_delay: 5, follow_redirects: true});{ "success": true, "status_code": 201, "headers": { "content-type": "application/json", "location": "/v1/orders/ord_123" }, "body": "{\"id\":\"ord_123\",\"status\":\"created\"}", "is_binary": false, "job_id": null, "timing": { "namelookup": 0.008, "connect": 0.031, "pretransfer": 0.033, "starttransfer": 0.102, "redirect": 0.0, "total": 0.108 }, "metadata": { "effective_url": "https://api.example.com/v1/orders", "content_type": "application/json", "redirect_count": 0, "size_download": 36, "size_upload": 38, "speed_download": 333.3, "speed_upload": 351.8 }}{ "job_id": "01HMZ8X9K2QF3N5P7R8T6V4WYD", "status": "pending", "mode": "async", "message": "Request accepted for async execution"}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid URL format"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_URL | Malformed URL | The provided URL is not in valid format | Provide a complete URL with protocol (e.g., https://example.com) |
INVALID_PARAMETER | Invalid parameter value | One or more parameters contain invalid values | Check parameter types and allowed values in API documentation |
{ "statusCode": 500, "error": "Internal Server Error", "message": "Connection timeout after 30 seconds"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NETWORK_ERROR | Network request failed | cURL could not complete the HTTP request | Check target URL is accessible, verify network connectivity, check timeout settings |
GET /api/v1/curl/ws
Section titled “GET /api/v1/curl/ws”Establish a WebSocket connection that receives job lifecycle events in JSON.
Messages:
jobstarted— payload:{job_id, name}jobprogress— payload:{job_id, progress}(progress is a0..1fraction)jobcompleted— payload:{job_id, status}error— payload:{message}
Filtering:
- Pass the
job_idquery parameter to only receive events for a single job.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
job_id | query | string | No | Optional job ID filter |
const ws = new WebSocket("wss://api.hoody.com/api/v1/curl/ws?job_id=01HMZ8X9K2QF3N5P7R8T6V4WYD");
ws.onmessage = (event) => { const msg = JSON.parse(event.data); switch (msg.event) { case "jobstarted": console.log(`Job ${msg.job_id} started: ${msg.name}`); break; case "jobprogress": console.log(`Job ${msg.job_id} progress: ${(msg.progress * 100).toFixed(1)}%`); break; case "jobcompleted": console.log(`Job ${msg.job_id} finished: ${msg.status}`); break; case "error": console.error(`Error: ${msg.message}`); break; }};const stream = await client.curl.events.streamWs({ job_id: "01HMZ8X9K2QF3N5P7R8T6V4WYD"});
for await (const event of stream) { console.log(event);}HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=The connection is upgraded to a WebSocket. After this point the client should expect JSON event frames rather than HTTP responses.
{ "statusCode": 400, "error": "Bad Request", "message": "Invalid WebSocket upgrade request"}{ "statusCode": 500, "error": "Internal Server Error", "message": "WebSocket upgrade failed"}