2026-06-17 14:30:00 +02:00
---
title : FlareSolverr Compat
description : POST /v1 — the drop-in FlareSolverr v2 endpoint.
---
# `POST /v1` — FlareSolverr Compatible
This endpoint implements the FlareSolverr v2 API contract. Any client that works with FlareSolverr works with TRAWL without code changes.
**No authentication required.**
## Request
```typescript
interface FlareSolverrRequest {
2026-06-26 22:05:47 +02:00
cmd ?: 'request.get' | 'request.post' // default: 'request.get'
2026-06-17 14:30:00 +02:00
url : string
maxTimeout? : number // milliseconds, default 60000
postData? : string // body for request.post
headers? : Record < string , string >
2026-07-05 16:41:01 +02:00
proxy? : string // TRAWL extension — not part of the real FlareSolverr contract
2026-06-17 14:30:00 +02:00
}
```
### Fields
2026-07-11 17:00:29 +02:00
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cmd` | string | No | `"request.get"` or `"request.post"` (default `"request.get"` ) |
| `url` | string | Yes | The URL to scrape |
| `maxTimeout` | number | No | Max wait in ms (default 60000) |
| `postData` | string | No | POST body (only for `request.post` ). On TRAWL's native `/scrape` endpoint this field is named `body` ; the `/v1` adapter maps `postData` → `body` internally so the FlareSolverr wire contract stays unchanged for existing callers. |
2026-08-09 05:15:49 +02:00
| `headers` | object | No | Custom headers forwarded to the target across all tiers — see [Custom Headers ](/api-reference/custom-headers ). For Prowlarr compatibility, `contentType` is accepted as `Content-Type` ; serialized `contentLength` is ignored and recalculated by the HTTP client. An explicit standard `Content-Type` takes precedence. |
2026-07-11 17:00:29 +02:00
| `proxy` | string | No | **TRAWL-specific extension** (not in the real FlareSolverr v2 contract) — per-request proxy override for Tier 3/4, see [Configuration § Proxies ](/getting-started/configuration#proxies ) |
2026-06-17 14:30:00 +02:00
## Response
```typescript
interface FlareSolverrResponse {
status : 'ok' | 'error'
message : string
startTimestamp : number // unix ms
endTimestamp : number // unix ms
version : '2.0.0'
solution : {
url : string // final URL after redirects
status : number // HTTP status code
headers : Record < string , string >
response : string // raw HTML body
cookies : Cookie []
userAgent : string
}
}
interface Cookie {
name : string
value : string
domain : string
path : string
expires : number
httpOnly : boolean
secure : boolean
sameSite? : string
}
```
## Examples
### GET request (curl)
```bash
curl -s -X POST http://localhost:8191/v1 \
-H "Content-Type: application/json" \
-d '{
"cmd": "request.get",
"url": "https://nowsecure.nl",
"maxTimeout": 60000
}'
```
### GET request (JavaScript)
```javascript
const res = await fetch ( 'http://localhost:8191/v1' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON . stringify ({
cmd : 'request.get' ,
url : 'https://nowsecure.nl' ,
maxTimeout : 60000 ,
}),
})
const data = await res . json ()
// data.status === 'ok'
// data.solution.response → HTML string
// data.solution.cookies → Cookie[]
// data.solution.userAgent → browser UA
```
### GET request (Python)
```python
import requests
res = requests . post ( 'http://localhost:8191/v1' , json = {
'cmd' : 'request.get' ,
'url' : 'https://nowsecure.nl' ,
'maxTimeout' : 60000 ,
}, timeout = 65 )
data = res . json ()
assert data [ 'status' ] == 'ok'
html = data [ 'solution' ][ 'response' ]
cookies = data [ 'solution' ][ 'cookies' ]
```
### POST request
2026-08-09 05:15:49 +02:00
POST requests with `postData` must supply a content type. TRAWL accepts either a standard
`Content-Type` header or Prowlarr's serialized `headers.contentType` representation at this
compatibility endpoint. Native `/scrape` requests continue to require the standard header.
2026-06-17 14:30:00 +02:00
```bash
curl -s -X POST http://localhost:8191/v1 \
-H "Content-Type: application/json" \
-d '{
"cmd": "request.post",
"url": "https://example.com/api/login",
"postData": "username=user&password=pass",
2026-08-09 05:15:49 +02:00
"headers": { "Content-Type": "application/x-www-form-urlencoded" },
2026-06-17 14:30:00 +02:00
"maxTimeout": 30000
}'
```
## Error response
2026-06-30 00:22:57 +02:00
When the request fails, the response is still a FlareSolverr v2 envelope with `status: "error"` and an empty `solution` . The HTTP status code carries the failure class:
2026-07-11 17:00:29 +02:00
| Code | Meaning |
| ---- | -------------------------------------------------------------------- |
| 200 | `status: "ok"` (request succeeded) |
| 400 | Malformed request body |
| 429 | Pool exhausted — all browsers busy past `BROWSER_ACQUIRE_TIMEOUT_MS` |
| 500 | Internal error |
2026-06-30 00:22:57 +02:00
Example — pool exhausted (HTTP 429):
2026-06-17 14:30:00 +02:00
```json
{
"status" : "error" ,
2026-06-30 00:22:57 +02:00
"message" : "Browser pool saturated, retry shortly" ,
2026-06-17 14:30:00 +02:00
"startTimestamp" : 1700000000000 ,
2026-06-30 00:22:57 +02:00
"endTimestamp" : 1700000015000 ,
2026-06-17 14:30:00 +02:00
"version" : "2.0.0" ,
"solution" : {
"url" : "https://nowsecure.nl" ,
"status" : 0 ,
"headers" : {},
"response" : "" ,
"cookies" : [],
"userAgent" : ""
}
}
```