Documentation
Introduction
Relay returns reliable web data through one API. You send a URL; Relay fetches it and returns a clean {status, headers, body}. One endpoint, one key, nothing to operate.
Base URL:
https://cp.167.233.48.91.sslip.io
Quickstart
Grab your API key from the dashboard (API Key tab), then make your first call:
curl -X POST https://cp.167.233.48.91.sslip.io/scrape \ -H "x-api-key: YOUR_API_KEY" \ -H "content-type: application/json" \ -d '{"url": "https://example.com"}'
Authentication
Every request is authenticated with your secret key in the x-api-key header. Keep it server-side; rotate it from the dashboard if exposed.
x-api-key: YOUR_API_KEY/scrapeFetch a URL and return the site's response. The only endpoint you need.
Body parameters
| Field | Type | Description |
|---|---|---|
| url * | string | The page to fetch. |
| method | string | HTTP method, default GET. POST/PUT supported. |
| headers | object | Request headers to forward. |
| body | string | Request body for POST/PUT. |
| timeout | number | Seconds to wait. |
| session_id | string | Pin to a logged-in session (see Sessions). |
Request
curl -X POST https://cp.167.233.48.91.sslip.io/scrape \ -H "x-api-key: YOUR_API_KEY" -H "content-type: application/json" \ -d '{"url":"https://example.com/search","method":"GET"}'
Response
{ "status": 200, "headers": { "content-type": "text/html; charset=utf-8" }, "body": "<!doctype html>…", // the page (or JSON), parse this "finalUrl": "https://example.com/" }
A non-2xx from the target site comes back in status with the body intact; that’s the site’s response, not a Relay error. See Status codes for Relay’s own codes.
Sessions & login
To scrape behind a login, attach a session_id. Relay keeps that session’s state and reuses it across requests, and re-establishes it if it goes stale.
# 1) send the login, marked as this session's login requests.post("https://cp.167.233.48.91.sslip.io/scrape", headers={"x-api-key": "YOUR_API_KEY"}, json={"url": "https://site.com/login", "method": "POST", "body": "user=...&pass=...", "session_id": "job-1", "session_login": True}) # 2) later requests with the same session_id stay authenticated requests.post("https://cp.167.233.48.91.sslip.io/scrape", headers={"x-api-key": "YOUR_API_KEY"}, json={"url": "https://site.com/account", "session_id": "job-1"})
Status codes
| Code | Meaning |
|---|---|
| 200 | Success. The site's response is in the body. |
| 401 | Invalid API key. |
| 403 | Account suspended or disabled. |
| 429 | Rate limit or quota exceeded. |
| 502 | Couldn't complete the fetch. |
| 503 | Capacity busy. Retry shortly. |
| 504 | Upstream timed out. |
Retry 429/502/503/504 with backoff. 401/403 are terminal. Billing: only successful responses count.
Scrapy
Drop-in downloader middleware: matched domains route through Relay; spiders stay normal.
DOWNLOADER_MIDDLEWARES = {"scrapy_replay_proxy.ReplayProxyMiddleware": 1000} REPLAY_PROXY_URL = "https://cp.167.233.48.91.sslip.io" REPLAY_PROXY_API_KEY = "YOUR_API_KEY" REPLAY_PROXY_DOMAINS = ["example.com"] # hosts to route through Relay REPLAY_PROXY_SESSION = "job-1" # optional sticky session RETRY_ENABLED = True RETRY_HTTP_CODES = [429, 502, 503, 504]