> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscriptions Overview

> Real-time updates via WebSocket

The GraphQL API supports real-time subscriptions for content updates via WebSocket connections.

## Subscription Schema

```graphql theme={null}
type Subscription {
  # Subscribe to updates for a specific content item
  contentUpdated(id: ID!): ContentUpdate!

  # Preview link updates (token-based auth)
  previewUpdated(token: String!): PreviewUpdate!
}
```

## Available Subscriptions

<CardGroup cols={2}>
  <Card title="contentUpdated" icon="rotate" href="/graphql/subscriptions/content-updated">
    Watch for updates to published content
  </Card>

  <Card title="previewUpdated" icon="eye" href="/graphql/subscriptions/preview-updated">
    Watch for updates to draft previews
  </Card>
</CardGroup>

## WebSocket Client Setup

Subscriptions are served from `wss://ws-api.metabind.ai`, which is a different
host from the one queries and mutations use. `api.metabind.ai` is an HTTP API
and cannot accept a WebSocket upgrade, so pointing a subscription client at it
will never connect.

Note the `?protocol=graphql-transport-ws` query parameter. `graphql-ws` clients
normally negotiate the subprotocol through the `Sec-WebSocket-Protocol` header,
but API Gateway does not forward that header to the backend — the query
parameter is what selects the GraphQL protocol, and the connection is treated
as a plain realtime socket without it.

Use `wss://ws-api-dev.metabind.ai` for the dev environment.

### Using graphql-ws

```javascript theme={null}
import { createClient } from 'graphql-ws';

const client = createClient({
  url: 'wss://ws-api.metabind.ai?protocol=graphql-transport-ws',
  connectionParams: {
    apiKey: 'YOUR_ORG_ID:YOUR_PROJECT_ID:YOUR_API_KEY'
  }
});
```

### For Preview Subscriptions

Use `previewToken` instead of `apiKey`:

```javascript theme={null}
const client = createClient({
  url: 'wss://ws-api.metabind.ai?protocol=graphql-transport-ws',
  connectionParams: {
    previewToken: 'YOUR_PREVIEW_TOKEN'
  }
});
```

## Handling Large Payloads

AWS WebSocket has a 100KB payload limit. When data exceeds this limit:

1. The `content` or `component` field will be `null`
2. The `resolvedRef` field is always included
3. Fetch the full data separately using the ID
4. Use the `resolvedRef` to fetch package data

```javascript theme={null}
if (!update.content) {
  // Content exceeded 100KB - fetch separately
  const content = await fetchContent(update.contentId);
  refreshContent(content, update.resolvedRef);
} else {
  // Content included in payload
  refreshContent(update.content, update.resolvedRef);
}
```

## Related

* [Subscription Types](/graphql/types/subscription-types) - ContentUpdate, PreviewUpdate type definitions
* [Caching](/graphql/caching) - Normalized package caching for subscriptions


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.