Below is a complete JavaScript example: a session with user context, a message with a streamed answer, and error handling.

const API = 'https://widget-api.prosecaptain.com/api/v2/widget';
const headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer YOUR_TOKEN'
};

// New session
async function startSession(context) {
  const res = await fetch(`${API}/thread`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ widget_id: 'WIDGET_ID', context })
  });
  if (!res.ok) throw new Error(`thread: ${res.status}`);
  return (await res.json()).session_id;
}

// Message without streaming
async function ask(sessionId, message) {
  const res = await fetch(`${API}/message`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ session_id: sessionId, message, widget_id: 'WIDGET_ID' })
  });
  if (res.status === 429) throw new Error('Too many requests, try again shortly');
  if (!res.ok) throw new Error(`message: ${res.status}`);
  return res.json();
}

// Message with streaming (Server-Sent Events)
async function askStream(sessionId, message, onDelta) {
  const res = await fetch(`${API}/message`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ session_id: sessionId, message, widget_id: 'WIDGET_ID', stream: true })
  });
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';
  for (;;) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });
    const events = buffer.split('\n\n');
    buffer = events.pop();
    for (const raw of events) {
      const event = raw.match(/^event: (.*)$/m)?.[1];
      const data = raw.match(/^data: (.*)$/m)?.[1];
      if (event === 'delta' && data) onDelta(JSON.parse(data));
    }
  }
}

const sessionId = await startSession({ current_page: 'Category: Sports' });
const answer = await ask(sessionId, 'Show me available running shoe models');
console.log(answer);

Tip

In production, add retries for network failures and 429 responses. Only send context that helps the assistant answer.