Misar IO Docs

AI Research Stream

Stream AI-powered research and outlines for your articles via SSE.

AI Research Stream

POST /ai/research

Streams AI-generated research on any topic as a Server-Sent Events response. Returns sourced insights, key points, and a structured outline you can drop directly into the editor.

Request

curl -X POST https://api.misar.io/blog/v1/ai/research \
  -H "Authorization: Bearer mbk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"topic":"Rust vs Go for backend services in 2026","depth":"detailed"}' \
  --no-buffer

Body Parameters

| Field | Type | Required | Description | |-------|------|----------|-------------| | topic | string | Yes | Research topic or question (max 500 chars) | | depth | string | No | brief (~300 words) | detailed (~800 words) | comprehensive (~1500 words). Default: detailed |

Response

Content-Type: text/event-stream

data: {"chunk": "# Rust vs Go for Backend Services in 2026\n\n"}

data: {"chunk": "## Performance\n\nBoth languages excel at systems-level..."}

data: {"chunk": " performance. Rust achieves near-C speeds through zero-cost abstractions..."}

data: {"chunk": "\n\n## Developer Experience\n\nGo's simplicity..."}

data: [DONE]

The full concatenated stream forms valid Markdown ready to paste into the MisarBlog editor.

TypeScript Example

async function research(topic: string): Promise<string> {
  const res = await fetch("https://api.misar.io/blog/v1/ai/research", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.MISARBLOG_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ topic, depth: "detailed" }),
  });

  const reader = res.body!.getReader();
  const dec = new TextDecoder();
  let out = "";
  let buf = "";

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buf += dec.decode(value, { stream: true });
    const lines = buf.split("\n");
    buf = lines.pop() ?? "";
    for (const line of lines) {
      if (!line.startsWith("data: ")) continue;
      const raw = line.slice(6).trim();
      if (raw === "[DONE]") return out;
      const { chunk, error } = JSON.parse(raw);
      if (error) throw new Error(error);
      out += chunk;
    }
  }
  return out;
}

Depth Guide

| Depth | Words | Use case | |-------|-------|----------| | brief | ~300 | Quick fact-check or intro paragraph | | detailed | ~800 | Full section research with key points | | comprehensive | ~1500 | Deep-dive article with outline + sources |

Errors

| Status | Description | |--------|-------------| | 400 | Missing topic or unrecognised depth | | 401 | Invalid or missing API key | | 429 | Rate limit exceeded |

Streaming errors are also delivered inline:

data: {"error": "Topic content policy violation"}

data: [DONE]