Skip to main content

Protocol overview

The WebSocket relay at wss://scraping-api.55-tech.com/ws provides a bidirectional proxy. You connect to the gateway, send a JSON connect message, and the gateway relays all frames between you and the target through a geo-distributed agent.
Client ←→ Gateway (wss://.../ws) ←→ Agent ←→ Target WebSocket

Interactive playground

The /ws/docs endpoint returns the protocol schema:
curl https://scraping-api.55-tech.com/ws/docs
{
  "type": "connected",
  "status": 101,
  "node_id": "scraping-de1",
  "message": "This is a documentation endpoint. Connect via WebSocket at wss://scraping-api.55-tech.com/ws"
}
For interactive WebSocket testing, use wscat:
npm install -g wscat
wscat -c wss://scraping-api.55-tech.com/ws
Then paste:
{"apiKey":"YOUR_API_KEY","url":"wss://echo.websocket.events"}

Connect message (client → gateway)

Must be sent as JSON text within 10 seconds of connecting.
{
  "apiKey": "YOUR_API_KEY",
  "url": "wss://target.example.com/stream",
  "headers": {
    "Authorization": "Bearer token",
    "Origin": "https://target.example.com"
  },
  "cookies": {
    "session": "abc123"
  },
  "geo": "US,DE",
  "agent": "de1",
  "idle_timeout": 0
}

Fields

FieldTypeRequiredDefaultDescription
apiKeystringYesAPI key for authentication. key is also accepted.
urlstringYesTarget WebSocket URL (wss://... or ws://...)
headersobjectNo{}Custom headers sent with the WS upgrade request to the target. Useful for Authorization, Origin, Cookie headers that the target expects.
cookiesobjectNo{}Cookies sent with the WS upgrade request. Merged into the Cookie header.
geostringNoRestrict agent selection to specific countries. Comma-separated ISO codes (e.g. US,DE,AT).
agentstringNoPin to specific agent(s) by slug (e.g. de1) or comma-separated for random pick (de1,at5,us3).
idle_timeoutfloatNo0If > 0, disconnect after this many seconds without receiving a message from the target. 0 = no idle timeout.

Response messages (gateway → client)

Connected

Sent once after the agent successfully connects to the target WebSocket.
{
  "type": "connected",
  "status": 101,
  "node_id": "scraping-de1"
}
FieldTypeDescription
typestringAlways "connected"
statusintHTTP status code of the WS upgrade. 101 = success.
node_idstringProxy node handling the relay (e.g. scraping-de1)

Error

Sent when connection fails or an error occurs. The WebSocket is closed after this message.
{
  "type": "error",
  "message": "Invalid or missing API key"
}
FieldTypeDescription
typestringAlways "error"
messagestringHuman-readable error description

Relayed frames

After the connected message, all subsequent frames are raw relay — no JSON wrapping. Text frames stay text, binary frames stay binary.

Close codes

CodeMeaning
1000Normal closure (you or target closed)
1008Policy violation — invalid API key, rate limited, or connect timeout
1011Internal error — agent failure or target unreachable

Error scenarios

ScenarioWhat happens
No connect message within 10sGateway closes with code 1008
Invalid API keyGateway sends error JSON, closes with 1008
Rate limit exceededGateway sends error JSON, closes with 1008
Target connection refusedGateway sends error JSON, closes with 1011
No agent availableGateway sends error JSON, closes with 1011
Target closes connectionGateway forwards the close frame with target’s code and reason
Client closes connectionGateway forwards close to target, cleans up
Agent crashes mid-relayGateway closes with 1011

Frame flow diagram

Rate limiting

WebSocket connections consume 1 token from your rate limit bucket on connect (when the connect message is validated). Subsequent frames do not consume tokens. If your bucket is empty, the gateway sends an error and closes with 1008.

Testing with wscat

# Install
npm install -g wscat

# Connect
wscat -c wss://scraping-api.55-tech.com/ws

# Paste connect message:
{"apiKey":"YOUR_KEY","url":"wss://echo.websocket.events"}

# After "connected" response, type messages to relay:
hello world

# The echo server will send back your message

Testing with Python

import asyncio
import json
import websockets

async def test():
    async with websockets.connect("wss://scraping-api.55-tech.com/ws") as ws:
        await ws.send(json.dumps({
            "apiKey": "YOUR_API_KEY",
            "url": "wss://echo.websocket.events",
        }))

        resp = json.loads(await ws.recv())
        print(f"Status: {resp}")

        if resp["type"] == "connected":
            await ws.send("test message")
            reply = await ws.recv()
            print(f"Echo: {reply}")

asyncio.run(test())