Browse documentation
METAPHRASE / GUIDESREST API v1
Open in AI
Open in ChatGPT Open in Claude
Markdown

Streaming responses

Use Server-Sent Events for paraphrase rewrites, translation and summarization.

Send stream: true in the JSON body. Accept: text/event-stream is optional; the body flag selects streaming. Grammar, detector and citation requests require stream: false. Paraphrase action: alternatives always returns JSON, including when stream: true is sent.

curl --no-buffer --fail-with-body --silent --show-error \
  'https://metaphrase.msalman.com/api/v1/paraphrase' \
  -H "Authorization: Bearer $METAPHRASE_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"text":"Good writing helps people understand an idea.","mode":"standard","stream":true}'

A successful streaming response has HTTP 200 and Content-Type: text/event-stream. Event order:

  1. meta: {"request_id":"<UUID>","tool":"paraphrase"}.
  2. Zero or more delta: {"text_delta":"a piece of output"}. Append only text_delta; do not append the entire event JSON.
  3. Exactly one terminal event: done with the full ordinary JSON response envelope, or error with the same {"error":{"code","message","docs_url"}} object used by JSON errors.

done.result.text is authoritative; replace your accumulated preview with it. A cache hit can send one delta containing the full result, followed by done with zero new usage. Local key-sentence summaries can also stream one complete result. Heartbeats are SSE comment lines beginning with : and must be ignored.

Validation/auth/quota/preflight failures occur before headers and use ordinary non-200 JSON. Once streaming begins, HTTP status cannot change; an error event may arrive after some deltas. If the connection closes without done, the result is incomplete. Preserve it as a partial preview, display the error, and do not cache it as a successful answer.

Use the SDK's streaming helper to handle UTF-8 boundaries and SSE framing:

import { MetaPhrase } from '@metaphrase/sdk';
const client = new MetaPhrase({api_key:process.env.METAPHRASE_API_KEY});
let partial='';
try {
  for await (const event of client.stream('paraphrase',{text:'Good writing makes an idea easier to understand.',mode:'standard'})) {
    if(event.event==='delta'){partial+=event.data.text_delta;process.stdout.write(event.data.text_delta);}
    if(event.event==='done')console.log('\nCompleted:',event.data.result.text,event.data.usage);
  }
} catch(error) {
  console.error('Partial result:',partial);
  console.error(error.code,error.message,error.docs_url);
}

Install the SDK using the SDK guide. The Python helper is client.stream('paraphrase', {'text': '...'}) and yields dictionaries with event and data. Both SDKs throw a MetaPhraseError on an error event or an incomplete stream. Browser EventSource cannot send a POST body or Bearer header; stream through your backend and use fetch streaming in the UI instead.

Abort the fetch/SDK stream when the user selects Stop. Cancellation can still incur upstream tokens; accepted calls still consume quota. Provider fallback happens only before any output is emitted, so two providers' output is never mixed. If you retry, start a separate result and replace the old preview rather than appending to it.