GuidesAPI Reference
DocumentationLog In

Overview

The websocket feed provides real-time market data updates for orders and trades.

Endpoint: wss://ws-feed.exchange.coinbase.com

Real-time market data updates provide the fastest insight into order flow and trades.
This however means that you are responsible for reading the message stream and using the message relevant for your needs which can include building real-time order books or tracking real-time trades.

The websocket feed is publicly available, but connections to it are rate-limited to 1 per 4 seconds per IP, messages sent by client on each connection are rate-limited to 100 per second per IP.

Protocol

The websocket feed uses a bidirectional protocol, which encodes all messages as JSON objects.
All messages have a type attribute that can be used to handle the message appropriately.

Please note that new message types can be added at any point in time.
Clients are expected to ignore messages they do not support.

Error messages:
Most failure cases will cause an error message (a message with the type "error") to be emitted.
This can be helpful for implementing a client or debugging issues.

{
    "type": "error",
    "message": "error message",
    /* ... */
}

Subscribe

To begin receiving feed messages, you must first send a subscribe message to the server indicating which channels and products to receive. This message is mandatory β€” you will be disconnected if no subscribe has been received within 5 seconds.

// Request
// Subscribe to ETH-USD and ETH-EUR with the level2, heartbeat and ticker channels,
// plus receive the ticker entries for ETH-BTC and ETH-USD
{
    "type": "subscribe",
    "product_ids": [
        "ETH-USD",
        "ETH-EUR"
    ],
    "channels": [
        "level2",
        "heartbeat",
        {
            "name": "ticker",
            "product_ids": [
                "ETH-BTC",
                "ETH-USD"
            ]
        }
    ]
}

There are two ways to specify products ids to listen for within each channel. First, you can specify the product ids for an individual channel. Also, as a shorthand, you can define products ids at the root of the object, which will add them to all the channels you subscribe to.

// Request
{
    "type": "unsubscribe",
    "product_ids": [
        "ETH-USD",
        "ETH-EUR"
    ],
    "channels": ["ticker"]
}

Once a subscribe message is received the server will respond with a subscriptions message that lists all channels you are subscribed to. Subsequent subscribe messages will add to the list of subscriptions.
In case you already subscribed to a channel without being authenticated you will remain in the unauthenticated channel.

// Response
{
    "type": "subscriptions",
    "channels": [
        {
            "name": "level2",
            "product_ids": [
                "ETH-USD",
                "ETH-EUR"
            ],
        },
        {
            "name": "heartbeat",
            "product_ids": [
                "ETH-USD",
                "ETH-EUR"
            ],
        },
        {
            "name": "ticker",
            "product_ids": [
                "ETH-USD",
                "ETH-EUR",
                "ETH-BTC"
            ]
        }
    ]
}

If you want to unsubscribe from channel/product pairs, send an unsubscribe message. The structure is equivalent to subscribe messages. As a shorthand you can also provide no product ids for a channel, which will unsubscribe you from the channel entirely.

// Request
{
    "type": "unsubscribe",
    "channels": ["heartbeat"]
}

As a response to an unsubscribe message you will receive a subscriptions message.

Authentication

It is possible to authenticate yourself when subscribing to the WebSocket Feed.

Authentication will result in a couple of benefits:

  1. Messages where you're one of the parties are expanded and have more useful fields
  2. You will receive private messages, such as lifecycle information about stop orders you placed
// Authenticated feed messages add user_id and
// profile_id for messages related to your user
{
    "type": "open", // "received" | "open" | "done" | "match" | "change" | "activate"
    "user_id": "5844eceecf7e803e259d0365",
    "profile_id": "765d1549-9660-4be2-97d4-fa2d65fa3352",
    /* ... */
}

Here's an example of an authenticated subscribe request:

// Request
{
    "type": "subscribe",
    "product_ids": [
        "BTC-USD"
    ],
    "channels": ["full"],
    "signature": "...",
    "key": "...",
    "passphrase": "...",
    "timestamp": "..."
}

To authenticate, you send a subscribe message as usual, but you also pass in fields just as if you were signing a request to GET /users/self/verify.
To get the necessary parameters, you would go through the same process as you do to make authenticated calls to the API.

πŸ“˜

Authenticated feed messages do not increment the sequence number.

It is currently not possible to detect if an authenticated feed message was dropped.

Sequence Numbers

Most feed messages contain a sequence number. Sequence numbers are increasing integer values for each product with every new message being exactly 1 sequence number greater than the one before it.

If you see a sequence number that is more than one value from the previous, it means a message has been dropped. A sequence number less than one you have seen can be ignored or has arrived out-of-order. In both situations you may need to perform logic to make sure your system is in the correct state.

πŸ“˜

While a websocket connection is over TCP, the websocket servers receive market data in a manner which can result in dropped messages.
Your feed consumer should either be designed to expect and handle sequence gaps and out-of-order messages, or use channels that guarantee delivery of messages.
If you want to keep an order book in sync, consider using the level 2 channel, which provides such guarantees.