Skip to main content
Watch for real-time updates to a specific published content item.

Subscription

subscription WatchContent($id: ID!) {
  contentUpdated(id: $id) {
    contentId
    action
    timestamp
    content {
      id
      name
      compiled
    }
    resolvedRef {
      package
      dependencies
    }
  }
}

Parameters

ParameterTypeRequiredDescription
idID!YesContent item ID to watch

Response: ContentUpdate

FieldTypeDescription
contentIdID!ID of the updated content
contentContentFull content object (null if payload exceeds 128KB)
resolvedRefResolvedPackageRef!Package IDs for caching
actionString!“update” or “delete”
timestampDateTime!When the update occurred

Example

Variables

{
  "id": "cont123"
}

Update Payload

{
  "data": {
    "contentUpdated": {
      "contentId": "cont123",
      "action": "update",
      "timestamp": "2024-01-15T10:30:00Z",
      "content": {
        "id": "cont123",
        "name": "Getting Started",
        "compiled": "const body = () => { ... }"
      },
      "resolvedRef": {
        "package": "abc123def456...",
        "dependencies": ["xyz789ghi012..."]
      }
    }
  }
}

Delete Payload

{
  "data": {
    "contentUpdated": {
      "contentId": "cont123",
      "action": "delete",
      "timestamp": "2024-01-15T11:00:00Z",
      "content": null,
      "resolvedRef": {
        "package": "abc123def456...",
        "dependencies": []
      }
    }
  }
}

Client Implementation

import { createClient } from 'graphql-ws';

const client = createClient({
  url: 'wss://api.metabind.ai/graphql',
  connectionParams: {
    headers: {
      'x-api-key': 'YOUR_API_KEY'
    }
  }
});

const unsubscribe = client.subscribe({
  query: `
    subscription WatchContent($id: ID!) {
      contentUpdated(id: $id) {
        contentId
        action
        timestamp
        content {
          id
          name
          compiled
        }
        resolvedRef {
          package
          dependencies
        }
      }
    }
  `,
  variables: { id: 'cont123' }
}, {
  next: (data) => {
    const update = data.data.contentUpdated;
    console.log('Content updated:', update.action, update.timestamp);

    if (update.action === 'delete') {
      removeContent(update.contentId);
      return;
    }

    // Handle large payloads - content may be null
    if (!update.content) {
      fetchContent(update.contentId).then(content => {
        refreshContent(content, update.resolvedRef);
      });
    } else {
      refreshContent(update.content, update.resolvedRef);
    }

    // Fetch any missing package data
    fetchMissingPackages([
      update.resolvedRef.package,
      ...update.resolvedRef.dependencies
    ]);
  },
  error: (err) => console.error('Subscription error:', err),
  complete: () => console.log('Subscription complete')
});

// Later, to unsubscribe
unsubscribe();

Handling Large Payloads

When content exceeds 128KB, the content field will be null:
if (!update.content) {
  // Content exceeded 128KB - fetch separately
  const content = await fetchContent(update.contentId);
  refreshContent(content, update.resolvedRef);
} else {
  // Content included in payload
  refreshContent(update.content, update.resolvedRef);
}