# HTTP Request Execution

**Page:** api/curl/execution

[Download Raw Markdown](./api/curl/execution.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



## 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`

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

| 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 |



```bash
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"
```


```typescript
const result = await client.curl.executeCurlRequestGet({
  url: "https://api.example.com/data",
  method: "GET",
  response: "json",
  timeout: 30
});
```


```json
{
  "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
  }
}
```


```json
{
  "job_id": "01HMZ8X9K2QF3N5P7R8T6V4WYD",
  "status": "pending",
  "message": "Request accepted for async execution"
}
```


```json
{
  "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) |


```json
{
  "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`

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 response
- `async`: Returns job ID immediately, executes in background

**Response Modes:**
- `transparent` (default): Returns raw response with original headers
- `json`: 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

The request body uses the `curl_CurlRequest` schema. `url` is the only required field; all other fields are optional. Unknown fields are rejected.



```bash
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
  }'
```


```typescript
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
});
```


```json
{
  "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
  }
}
```


```json
{
  "job_id": "01HMZ8X9K2QF3N5P7R8T6V4WYD",
  "status": "pending",
  "mode": "async",
  "message": "Request accepted for async execution"
}
```


```json
{
  "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 |


```json
{
  "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`

Establish a WebSocket connection that receives job lifecycle events in JSON.

**Messages:**
- `jobstarted` &mdash; payload: `{job_id, name}`
- `jobprogress` &mdash; payload: `{job_id, progress}` (progress is a `0..1` fraction)
- `jobcompleted` &mdash; payload: `{job_id, status}`
- `error` &mdash; payload: `{message}`

**Filtering:**
- Pass the `job_id` query parameter to only receive events for a single job.


Use `getJob` for snapshot state, and the WebSocket for live updates.


#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `job_id` | query | string | No | Optional job ID filter |



```javascript
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;
  }
};
```


```typescript
const stream = await client.curl.events.streamWs({
  job_id: "01HMZ8X9K2QF3N5P7R8T6V4WYD"
});

for await (const event of stream) {
  console.log(event);
}
```


```
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-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.


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid WebSocket upgrade request"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "WebSocket upgrade failed"
}
```