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

# Suki SDKs Overview

> Compare Suki SDKs for Ambient, Form filling, Dictation, and Patient Summary workflows, then jump to quickstarts, changelogs, and integration guides

export const SOV = {
  supportEmail: "support@suki.ai",
  calloutTag: "Note",
  decide: {
    title: "Not sure which SDK fits?",
    body: "Compare hosted UI, headless, and native paths side by side before you build."
  },
  pillIcons: {
    JavaScript: "js",
    React: "react",
    Swift: "swift",
    iOS: "apple"
  },
  pillTones: {
    GA: "ga",
    BETA: "beta"
  },
  tileTones: {
    workflows: "yellow",
    quickstart: "yellow",
    auth: "yellow",
    "patient-summary": "yellow",
    web: "blue",
    headless: "blue",
    dictation: "blue",
    api: "blue",
    websocket: "blue",
    mobile: "cream",
    webhook: "cream",
    "form-filling": "cream",
    guidelines: "cream"
  },
  paths: {
    all: "M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z",
    ambient: "M3 12h3.5l2.5-6 4 12 2.5-6H21",
    dictation: "M9 6a3 3 0 0 1 6 0v6a3 3 0 0 1-6 0zM5.5 11.5a6.5 6.5 0 0 0 13 0M12 18v3",
    form: "M8 4h8v3H8zM6 5.5H5v15h14v-15h-1M8.5 12h7M8.5 16h5",
    summary: "M5 4h14v16H5zM8.5 9h7M8.5 12.5h7M8.5 16h4",
    grid: "M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z",
    code: "M8 7l-5 5 5 5M16 7l5 5-5 5",
    phone: "M7.5 3h9v18h-9zM11 18h2",
    headless: "M4 5h16v14H4zM8 10l2.5 2L8 14M12.5 14H16",
    rocket: "M5 16.5c-1.5 1.3-2 5-2 5s3.7-.5 5-2c.7-.8.7-2.1-.1-2.9a2.2 2.2 0 0 0-2.9-.1zM12 15l-3-3a22 22 0 0 1 2-4A12.9 12.9 0 0 1 22 2c0 2.7-.8 7.5-6 11a22.4 22.4 0 0 1-4 2zM9 12H4s.5-3 2-4c1.6-1.1 5 0 5 0M12 15v5s3-.5 4-2c1.1-1.6 0-5 0-5",
    key: "M7.5 8.5a3.5 3.5 0 1 0 0 7a3.5 3.5 0 1 0 0-7M11 12h9.5M17.5 12v3M20.5 12v2",
    braces: "M9 4H7.5A2.5 2.5 0 0 0 5 6.5v3A2.5 2.5 0 0 1 2.5 12 2.5 2.5 0 0 1 5 14.5v3A2.5 2.5 0 0 0 7.5 20H9M15 4h1.5A2.5 2.5 0 0 1 19 6.5v3a2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0-2.5 2.5v3a2.5 2.5 0 0 1-2.5 2.5H15",
    bell: "M6 10a6 6 0 0 1 12 0v4l2 3H4l2-3zM10 20a2 2 0 0 0 4 0",
    bars: "M4 14h4v6H4zM10 10h4v10h-4zM16 6h4v14h-4z",
    file: "M6 3h8l4 4v14H6zM14 3v4h4",
    download: "M12 4v11M7 10l5 5 5-5M5 20h14",
    check: "M5 12.5l4.5 4.5L19 7",
    arrow: "M4 12h16M14 6l6 6-6 6",
    book: "M4 4.5h6a2 2 0 0 1 2 2v13a2 2 0 0 0-2-2H4zM20 4.5h-6a2 2 0 0 0-2 2v13a2 2 0 0 1 2-2h6z"
  },
  art: {
    ink: "#1B1B1B",
    paper: "#FFFDF7",
    skel: "#DCD7C9",
    yellow: "#FDF49D",
    yellowEdge: "#E9D25A",
    blueBar: "#9CCBF2"
  }
};

export const sovUtil = {
  safe: (fn, fallback) => {
    try {
      return fn();
    } catch (e) {
      return fallback;
    }
  },
  flat: n => Array.isArray(n) ? n.flatMap(sovUtil.flat) : n == null || typeof n === "boolean" ? [] : [n],
  isEl: n => !!(n && typeof n === "object" && n.props),
  isBoundary: n => {
    const p = n.props;
    return typeof p.name === "string" && sovUtil.isEl(p.children) && Object.keys(p).every(k => k === "name" || k === "children");
  },
  unwrap: n => {
    let x = n;
    while (sovUtil.isEl(x) && sovUtil.isBoundary(x)) x = x.props.children;
    return x;
  },
  els: node => sovUtil.flat(node).map(sovUtil.unwrap).filter(sovUtil.isEl),
  findAll: (node, type, out = []) => {
    sovUtil.flat(node).forEach(raw => {
      const n = sovUtil.unwrap(raw);
      if (!sovUtil.isEl(n)) return;
      if (n.type === type) out.push(n); else sovUtil.findAll(n.props.children, type, out);
    });
    return out;
  },
  find: (node, type) => sovUtil.findAll(node, type)[0],
  has: (node, type) => !!sovUtil.find(node, type),
  textOf: n => sovUtil.flat(n).map(x => typeof x === "string" || typeof x === "number" ? String(x) : sovUtil.isEl(x) ? sovUtil.textOf(x.props.children) : "").join(""),
  split: s => String(s || "").split(",").map(x => x.trim()).filter(Boolean)
};

export const SovGlyph = ({k, size = 16, sw = 1.6}) => <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={`sov-ic sov-ic-${k}`}><path d={SOV.paths[k]} /></svg>;

export const SovSlot = ({children}) => <div style={{
  display: "contents"
}}>{children}</div>;

export const SovKeyed = ({list}) => sovUtil.flat(list).map((el, i) => <SovSlot key={i}>{el}</SovSlot>);

export const SovCopyBtn = ({text, label = "Copy"}) => {
  const [done, setDone] = useState(false);
  const go = async () => {
    try {
      await navigator.clipboard.writeText(text);
      setDone(true);
      setTimeout(() => setDone(false), 1500);
    } catch (e) {}
  };
  return <button type="button" className="sov-copy" data-copied={done ? "" : undefined} onClick={go} aria-label={done ? "Copied" : label}>
      <svg viewBox="0 0 18 18" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        {done ? <path d="M2.75 9.5L6.5 13.25L15.25 4.5" /> : <>
            <path d="M14.25 5.25H7.25C6.14543 5.25 5.25 6.14543 5.25 7.25V14.25C5.25 15.3546 6.14543 16.25 7.25 16.25H14.25C15.3546 16.25 16.25 15.3546 16.25 14.25V7.25C16.25 6.14543 15.3546 5.25 14.25 5.25Z" />
            <path d="M2.80103 11.998L1.77203 5.07397C1.61003 3.98097 2.36403 2.96397 3.45603 2.80197L10.38 1.77297C11.313 1.63397 12.19 2.16297 12.528 3.00097" />
          </>}
      </svg>
      <span className="sov-copy-tip" aria-hidden="true">{done ? "Copied" : "Copy"}</span>
    </button>;
};

export const SovArt = ({label, children}) => <svg className="sov-art" width="800" height="200" viewBox="0 0 800 200" role="img" aria-label={label}>{children}</svg>;

export const SovLine = ({x, y, w, c = SOV.art.skel}) => <rect x={x} y={y} width={w} height="6" rx="3" fill={c} />;

export const SovBadge = ({x, y}) => <g>
    <rect x={x} y={y} width="44" height="44" rx="12" fill={SOV.art.ink} />
    {[[9, 8, SOV.art.yellow], [15, 16, "#FFFFFF"], [21, 24, SOV.art.blueBar], [27, 16, "#FFFFFF"], [33, 8, SOV.art.yellow]].map(([dx, h, c], i) => <rect key={i} x={x + dx} y={y + 22 - h / 2} width="2" height={h} rx="1" fill={c} />)}
  </g>;

export const SovBarcode = ({x, y, n, h = 24}) => <g>
    {Array.from({
  length: n
}).map((_, i) => {
  const tall = [1, 0.5, 0.75, 0.5, 1, 0.33, 0.75, 0.5][i % 8];
  const bh = Math.round(h * tall / 2) * 2;
  return <rect key={i} x={x + i * 8} y={y + (h - bh) / 2} width={i % 5 === 3 ? 2 : 1} height={bh} fill={i % 5 === 3 ? SOV.art.yellowEdge : SOV.art.ink} />;
})}
  </g>;

export const SovPill = ({label}) => {
  const name = SOV.pillIcons[label];
  const tone = SOV.pillTones[label];
  const hasIcon = typeof Icon !== "undefined";
  const cls = ["sov-ptag", name && hasIcon ? "sov-ptag-logo" : "", tone ? `sov-ptag-${tone}` : ""].filter(Boolean).join(" ");
  return <span className={cls}>
      {name && hasIcon && <span className="sov-ptag-ic" aria-hidden="true"><Icon icon={name} iconType="brands" size={13} /></span>}
      {label}
    </span>;
};

export const SdkFilterIconAmbient = () => <SovGlyph k="ambient" />;

export const SdkFilterIconDictation = () => <SovGlyph k="dictation" />;

export const SdkFilterIconForms = () => <SovGlyph k="form" />;

export const SdkFilterIconSummary = () => <SovGlyph k="summary" />;

export const SdkStartGlyphGrid = () => <SovGlyph k="grid" size={20} />;

export const SdkStartGlyphReact = () => <SovGlyph k="code" size={20} />;

export const SdkStartGlyphPhone = () => <SovGlyph k="phone" size={20} />;

export const SdkStartGlyphHeadless = () => <SovGlyph k="headless" size={20} />;

export const SdkStartGlyphMic = () => <SovGlyph k="dictation" size={20} />;

export const SdkStartGlyphRocket = () => <SovGlyph k="rocket" size={20} />;

export const SdkStartGlyphAuth = () => <SovGlyph k="key" size={20} />;

export const SdkStartGlyphApi = () => <SovGlyph k="braces" size={20} />;

export const SdkStartGlyphWebhook = () => <SovGlyph k="bell" size={20} />;

export const SdkStartGlyphBars = () => <SovGlyph k="bars" size={20} />;

export const SdkStartGlyphForms = () => <SovGlyph k="form" size={20} />;

export const SdkStartGlyphSummary = () => <SovGlyph k="summary" size={20} />;

export const SdkStartGlyphBook = () => <SovGlyph k="book" size={20} />;

export const OverviewPage = ({className = "", children}) => <div className={["hp-wrap", "api-overview-wrap", className].filter(Boolean).join(" ")}>
    <div className="sov">{children}</div>
  </div>;

export const HpCta = ({href, variant = "primary", className = "", children}) => <a href={href} className={["hp-cta", `hp-cta-${variant}`, "sov-cta", className].filter(Boolean).join(" ")}>{children}</a>;

export const OverviewCtaRow = ({children}) => <div className="sov-ctas">{children}</div>;

export const OverviewInstallRow = () => null;

export const OverviewDownloadList = ({children}) => {
  const rows = sovUtil.findAll(children, OverviewInstallRow).map(r => ({
    label: r.props.label,
    clip: r.props.clipboard,
    text: sovUtil.textOf(r.props.children).trim(),
    aria: r.props.ariaLabel
  }));
  const [i, setI] = useState(0);
  if (!rows.length) return <div className="sov-dls">{children}</div>;
  const r = rows[Math.min(i, rows.length - 1)];
  const isComment = r.text.startsWith("#");
  return <div className="sov-term">
      <div className="sov-term-tabs" role="tablist" aria-label="Install command by SDK">
        {rows.map((x, n) => <button key={x.label} type="button" role="tab" aria-selected={n === i} className="sov-term-tab" onClick={() => setI(n)}>{x.label}</button>)}
      </div>
      <div className="sov-term-body" role="tabpanel">
        <pre><code>{isComment ? <span className="sov-tk-c">{r.text}</span> : <><span className="sov-tk-p">$ </span>{r.text}</>}</code></pre>
        <SovCopyBtn text={r.clip || r.text} label={r.aria || `Copy ${r.label} command`} />
      </div>
    </div>;
};

export const OverviewHeroMain = ({title, lead, children}) => <div className="sov-hero-l">
    <h1 className="sov-title">{title}</h1>
    {lead && <div className="sov-lead">{lead}</div>}
    {children}
  </div>;

export const OverviewHeroSection = ({title, children}) => <section className="sov-sec">
    <h2 className="sov-kicker">{title}</h2>
    <div className="sov-sec-body">{children}</div>
  </section>;

export const OverviewHeroSteps = ({children}) => <ol className="sov-steps-plain">{children}</ol>;

export const OverviewHeroAside = ({ariaLabel, children}) => <aside className="sov-hero-r" aria-label={ariaLabel}>{children}</aside>;

export const OverviewMetaCard = ({title, children}) => <section className="sov-card">
    <h2 className="sov-kicker">{title}</h2>
    {children}
  </section>;

export const OverviewMailRow = ({label = "Support", email = SOV.supportEmail}) => <div className="sov-mail">
    <span className="sov-mail-l">{label}</span>
    <a className="sov-mail-a" href={`mailto:${email}`} data-suki-support-mail="1">{email}</a>
    <SovCopyBtn text={email} label={`Copy ${email}`} />
  </div>;

export const OverviewMetaBestPractices = ({children}) => {
  const tip = sovUtil.els(children)[0];
  return <div className="sov-bp">{tip && tip.props.children ? tip.props.children : children}</div>;
};

export const OverviewHero = ({kicker, children}) => {
  const u = sovUtil;
  const main = u.find(children, OverviewHeroMain);
  const aside = u.find(children, OverviewHeroAside);
  if (!main) return <div className="sov-hero">{children}</div>;
  const sections = u.findAll(main.props.children, OverviewHeroSection);
  const ctas = u.find(main.props.children, OverviewCtaRow);
  const howSec = sections.find(s => u.has(s.props.children, OverviewHeroSteps));
  const introSecs = sections.filter(s => s !== howSec);
  const cards = aside ? u.findAll(aside.props.children, OverviewMetaCard) : [];
  const stepsEl = howSec && u.find(howSec.props.children, OverviewHeroSteps);
  const steps = stepsEl ? u.els(stepsEl.props.children) : [];
  const howIntro = howSec ? u.flat(howSec.props.children).filter(n => u.unwrap(n) !== stepsEl) : [];
  return <div className="sov-hero">
      <div className="sov-row sov-row-a">
        <div className="sov-hero-l">
          {kicker && <div className="sov-kicker">{kicker}</div>}
          <h1 className="sov-title">{main.props.title}</h1>
          {main.props.lead && <div className="sov-lead">{main.props.lead}</div>}
          {ctas}
          {introSecs.map((s, i) => <section key={i} className="sov-sec sov-intro">
              <h2 className="sov-kicker">{s.props.title}</h2>
              <div className="sov-sec-body"><SovKeyed list={s.props.children} /></div>
            </section>)}
        </div>
        {cards.length > 0 && <aside className="sov-hero-r" aria-label={aside.props.ariaLabel}>
            {cards.map((c, i) => {
    const bp = u.find(c.props.children, OverviewMetaBestPractices);
    if (bp) {
      const mail = u.find(c.props.children, OverviewMailRow);
      return <div key={i} className="sov-support">
                    {mail}
                    {bp}
                  </div>;
    }
    const install = u.has(c.props.children, OverviewInstallRow);
    return <section key={i} className={install ? "sov-card sov-card-install" : "sov-card"}>
                  <h2 className="sov-kicker">{c.props.title}</h2>
                  <SovKeyed list={c.props.children} />
                </section>;
  })}
          </aside>}
      </div>

      {howSec && <section className="sov-how" aria-labelledby="sov-how-h">
          <div className="sov-how-head">
            {howSec.props.eyebrow && <div className="sov-kicker">{howSec.props.eyebrow}</div>}
            <h2 className="sov-h2" id="sov-how-h">{howSec.props.title}</h2>
            <div className="sov-how-lead"><SovKeyed list={howIntro} /></div>
          </div>
          <ol className="sov-steps">
            {steps.map((li, i) => <li key={i} className="sov-step">
                <span className="sov-step-n">{String(i + 1).padStart(2, "0")}</span>
                <span className="sov-step-t">{li.props.children}</span>
              </li>)}
          </ol>
        </section>}
    </div>;
};

export const OverviewHeroSections = ({children}) => <div className="sov-secs">{children}</div>;

export const OverviewHeroText = ({callout, children}) => callout ? <div className="sov-note" role="note">
      <span className="sov-tag">{typeof callout === "string" ? callout : SOV.calloutTag}</span>
      <div className="sov-note-t">{children}</div>
    </div> : <div className="sov-text">{children}</div>;

export const OverviewMetaStack = ({children}) => <div className="sov-meta">{children}</div>;

export const OverviewDownloadRow = ({href, name}) => <a className="sov-dl" href={href} target="_blank" rel="noopener noreferrer" aria-label={`Download ${name}`}>
    <SovGlyph k="file" size={16} />
    <span className="sov-dl-n">{name}</span>
    <SovGlyph k="download" size={16} />
  </a>;

export const OverviewKvStack = ({children}) => <div className="sov-kvs">{children}</div>;

export const OverviewKv = ({label, children}) => <div className="sov-kv">
    {label && <span className="sov-kv-l">{label}</span>}
    <div className="sov-kv-v">{children}</div>
  </div>;

export const OverviewKvLine = ({children}) => <div className="sov-kv-line">{children}</div>;

export const OverviewKvLink = ({href, children}) => <a className="sov-link" href={href}>{children}</a>;

export const OverviewInlineLink = ({href, children}) => <a className="sov-link sov-link-go" href={href}>{children}<SovGlyph k="arrow" size={14} /></a>;

export const OverviewInlineCode = ({value, ariaLabel}) => <span className="sov-icode">
    <code>{value}</code>
    <SovCopyBtn text={value} label={ariaLabel || `Copy ${value}`} />
  </span>;

export const OverviewMetaHint = ({children}) => {
  const tip = sovUtil.els(children)[0];
  return <div className="sov-hint">{tip && tip.props.children ? tip.props.children : children}</div>;
};

export const OverviewArtWeb = () => {
  const A = SOV.art;
  return <SovArt label="Browser window with Suki's hosted note and the waveform badge">
      <path d="M64.5 200V60.5a12 12 0 0 1 12-12H800V200z" fill={A.paper} />
      <path d="M64.5 200V60.5a12 12 0 0 1 12-12H800M64.5 72.5H800M136.5 72.5V200" fill="none" stroke={A.ink} />
      {[78, 90, 102].map(x => <rect key={x} x={x + 0.5} y="56.5" width="7" height="7" rx="3.5" fill="none" stroke={A.ink} />)}
      <SovLine x={80} y={88} w={40} /><SovLine x={80} y={104} w={32} /><SovLine x={80} y={120} w={40} />
      <rect x="152.5" y="88.5" width="56" height="17" rx="5" fill={A.yellow} stroke={A.ink} />
      <SovLine x={152} y={120} w={112} /><SovLine x={152} y={136} w={120} /><SovLine x={152} y={152} w={96} /><SovLine x={152} y={168} w={116} />
      <SovBadge x={284} y={84} />
    </SovArt>;
};

export const OverviewArtMobile = () => {
  const A = SOV.art;
  return <SovArt label="Phone running an ambient session that streams audio">
      <path d="M64.5 200V56.5a20 20 0 0 1 20-20h72a20 20 0 0 1 20 20V200" fill={A.paper} stroke={A.ink} />
      <rect x="106" y="46" width="30" height="4" rx="2" fill={A.ink} />
      <rect x="80.5" y="64.5" width="44" height="17" rx="5" fill={A.yellow} stroke={A.ink} />
      <SovLine x={80} y={96} w={80} /><SovLine x={80} y={110} w={64} /><SovLine x={80} y={124} w={72} />
      <SovBadge x={99} y={144} />
      <path d="M176.5 100.5H800" fill="none" stroke={A.ink} />
      <SovBarcode x={200} y={88} n={76} h={24} />
    </SovArt>;
};

export const OverviewArtHeadless = () => {
  const A = SOV.art;
  return <SovArt label="Your own layout, built from Suki hooks">
      <path d="M64.5 200V52.5a12 12 0 0 1 12-12H800" fill="none" stroke={A.ink} strokeDasharray="4 4" />
      <rect x="88.5" y="64.5" width="64" height="56" rx="8" fill={A.paper} stroke={A.ink} />
      <SovBadge x={98} y={70} />
      <path d="M800 64.5H176.5a8 8 0 0 0-8 8v40a8 8 0 0 0 8 8H800z" fill={A.paper} />
      <path d="M800 64.5H176.5a8 8 0 0 0-8 8v40a8 8 0 0 0 8 8H800" fill="none" stroke={A.ink} />
      <SovLine x={184} y={80} w={120} /><SovLine x={184} y={96} w={152} />
      <path d="M800 136.5H96.5a8 8 0 0 0-8 8V200H800z" fill={A.paper} />
      <path d="M800 136.5H96.5a8 8 0 0 0-8 8V200" fill="none" stroke={A.ink} />
      <SovLine x={104} y={152} w={200} /><SovLine x={104} y={166} w={232} /><SovLine x={104} y={180} w={160} />
    </SovArt>;
};

export const OverviewArtMic = () => {
  const A = SOV.art;
  return <SovArt label="Speech captured into a text field as it is spoken">
      <path d="M800 56.5H76.5a12 12 0 0 0-12 12v64a12 12 0 0 0 12 12H800" fill={A.paper} stroke={A.ink} />
      <SovLine x={84} y={76} w={168} /><SovLine x={84} y={92} w={136} />
      <SovLine x={84} y={108} w={96} c={A.ink} />
      <rect x="186" y="104" width="2" height="14" fill={A.ink} />
      <g>
        <rect x="284" y="78" width="44" height="44" rx="12" fill={A.ink} />
        <rect x="301.5" y="88.5" width="9" height="15" rx="4.5" fill="none" stroke={A.yellow} />
        <path d="M298.5 98.5a7.5 7.5 0 0 0 15 0M306 106.5v5M302.5 111.5h7" fill="none" stroke={A.yellow} />
      </g>
      <SovBarcode x={64} y={152} n={30} h={16} />
    </SovArt>;
};

export const OverviewArtForms = () => {
  const A = SOV.art;
  return <SovArt label="Medical form whose fields fill from the visit conversation">
      <path d="M64.5 200V52.5a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12V200" fill={A.paper} stroke={A.ink} />
      <rect x="84" y="58" width="72" height="6" rx="3" fill={A.ink} />
      {[[80, true], [112, true], [144, false]].map(([y, on]) => <g key={y}>
          <rect x="84.5" y={y + 4.5} width="15" height="15" rx="4" fill={on ? A.ink : A.paper} stroke={A.ink} />
          {on && <path d={`M88.5 ${y + 12.5}l3 3 5.5-6.5`} fill="none" stroke={A.yellow} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />}
          <SovLine x={112} y={y + 9} w={32} />
          <rect x="156.5" y={y + 0.5} width="80" height="23" rx="6" fill={on ? A.paper : "none"} stroke={A.ink} strokeDasharray={on ? undefined : "4 4"} />
          {on && <SovLine x={166} y={y + 9} w={y === 80 ? 48 : 32} c={A.ink} />}
        </g>)}
      <path d="M256.5 100.5H284" fill="none" stroke={A.ink} strokeDasharray="4 4" />
      <SovBadge x={284} y={78} />
    </SovArt>;
};

export const OverviewArtWave = () => {
  const A = SOV.art;
  return <SovArt label="A REST request opens the session, then live audio streams over WebSocket">
      <rect x="64.5" y="48.5" width="152" height="104" rx="12" fill={A.paper} stroke={A.ink} />
      <rect x="80.5" y="64.5" width="44" height="17" rx="5" fill={A.yellow} stroke={A.ink} />
      <SovLine x={80} y={96} w={104} /><SovLine x={80} y={110} w={80} /><SovLine x={80} y={124} w={92} />
      <path d="M216.5 100.5H800" fill="none" stroke={A.ink} />
      <SovBadge x={240} y={78} />
      <SovBarcode x={304} y={88} n={62} h={24} />
    </SovArt>;
};

export const OverviewArtSummary = () => {
  const A = SOV.art;
  return <SovArt label="FHIR records combined into one Patient Summary">
      {[56, 92, 128].map(y => <g key={y}>
          <rect x="64.5" y={y + 0.5} width="72" height="27" rx="6" fill={A.paper} stroke={A.ink} />
          <SovLine x={76} y={y + 11} w={40} />
        </g>)}
      <path d="M136.5 70.5h12v72h-12M136.5 106.5H184" fill="none" stroke={A.ink} />
      <SovBadge x={184} y={84} />
      <path d="M228.5 106.5H252" fill="none" stroke={A.ink} strokeDasharray="4 4" />
      <path d="M252.5 200V52.5a12 12 0 0 1 12-12H800V200z" fill={A.paper} />
      <path d="M252.5 200V52.5a12 12 0 0 1 12-12H800" fill="none" stroke={A.ink} />
      <rect x="272" y="58" width="72" height="6" rx="3" fill={A.ink} />
      <rect x="272.5" y="76.5" width="56" height="17" rx="5" fill={A.yellow} stroke={A.ink} />
      <SovLine x={272} y={108} w={160} /><SovLine x={272} y={124} w={200} /><SovLine x={272} y={140} w={176} /><SovLine x={272} y={156} w={120} />
    </SovArt>;
};

export const OverviewWorkflowSection = ({eyebrow, titleId, title, lead, children}) => <section className="sov-wf" aria-labelledby={titleId}>
    {eyebrow && <div className="sov-kicker">{eyebrow}</div>}
    <h2 className="sov-h2" id={titleId}>{title}</h2>
    {lead && <div className="sov-lead">{lead}</div>}
    {children}
  </section>;

export const SdkCardTipPanel = ({what, whenWhy, features = []}) => <div className="sov-tip">
    {what && <div className="sov-what">{what}</div>}
    {whenWhy && <div className="sov-when">{whenWhy}</div>}
    {features.length > 0 && <ul className="sov-feats">
        {features.map(f => <li key={f}><SovGlyph k="check" size={14} sw={2} />{f}</li>)}
      </ul>}
  </div>;

export const OverviewWorkflowCard = ({href, ariaLabel, title, pills = [], workflows, tone, children}) => {
  const u = sovUtil;
  const tip = u.find(children, SdkCardTipPanel);
  const art = u.els(children).filter(n => n.type !== SdkCardTipPanel);
  const tones = new Map([[OverviewArtWeb, "blue"], [OverviewArtMobile, "cream"], [OverviewArtHeadless, "yellow"], [OverviewArtMic, "blue"], [OverviewArtForms, "cream"], [OverviewArtWave, "blue"], [OverviewArtSummary, "yellow"]]);
  const name = title || ariaLabel;
  return <a className="sov-sdk" href={href} data-workflows={workflows} data-tone={tone || art[0] && tones.get(art[0].type) || "blue"}>
      <div className="sov-sdk-art"><SovKeyed list={art} /></div>
      <div className="sov-sdk-body">
        <span className="sov-sdk-title">{name}</span>
        {pills.length > 0 && <span className="sov-sdk-tags">{pills.map(p => <SovPill key={p} label={p} />)}</span>}
        {tip && <SdkCardTipPanel {...tip.props} />}
        <span className="sov-sdk-go">View {name} docs<SovGlyph k="arrow" size={15} sw={1.6} /></span>
      </div>
    </a>;
};

export const OverviewWorkflowCards = ({id, ariaLabel, children}) => {
  const n = sovUtil.findAll(children, OverviewWorkflowCard).length;
  return <div className="sov-sdks" id={id} aria-label={ariaLabel} data-count={n}>{children}</div>;
};

export const SdkWorkflowFilterPill = ({label, children}) => <span className="sov-wf-pill">{children}{label}</span>;

export const SdkWorkflowFilter = ({children}) => {
  const u = sovUtil;
  const pills = u.findAll(children, SdkWorkflowFilterPill);
  const cardsWrap = u.find(children, OverviewWorkflowCards);
  const cards = cardsWrap ? u.findAll(cardsWrap.props.children, OverviewWorkflowCard) : [];
  const start = (pills.find(p => p.props.active) || pills[0] || ({
    props: {
      value: "all"
    }
  })).props.value;
  const [on, setOn] = useState(start);
  useEffect(() => {
    const v = u.safe(() => new URLSearchParams(window.location.search).get("workflow"), null);
    if (v && pills.some(p => p.props.value === v)) setOn(v);
  }, []);
  const pick = v => {
    setOn(v);
    u.safe(() => {
      if (!(/^https?:$/).test(window.location.protocol)) return;
      const sp = new URLSearchParams(window.location.search);
      if (v === "all") sp.delete("workflow"); else sp.set("workflow", v);
      const qs = sp.toString();
      window.history.replaceState(window.history.state, "", window.location.pathname + (qs ? `?${qs}` : "") + window.location.hash);
    });
  };
  const shown = cards.filter(c => on === "all" || u.split(c.props.workflows).includes(on));
  return <div className="sov-filter">
      <div className="sov-pills" role="group" aria-label="Filter by workflow">
        {pills.map(p => {
    const v = p.props.value;
    const n = v === "all" ? cards.length : cards.filter(c => u.split(c.props.workflows).includes(v)).length;
    return <button key={v} type="button" className="sov-pill" aria-pressed={on === v} onClick={() => pick(v)}>
              <span className="sov-pill-l">{v === "all" ? <SovGlyph k="all" /> : p.props.children}{p.props.label}</span>
              <span className="sov-pill-n">{n}</span>
            </button>;
  })}
      </div>
      <div className="sov-sdks" id={cardsWrap && cardsWrap.props.id} aria-label={cardsWrap && cardsWrap.props.ariaLabel} aria-live="polite" data-count={shown.length}>
        {shown.map(c => <SovSlot key={c.props.href}>{c}</SovSlot>)}
      </div>
    </div>;
};

export const SdkWorkflowFilterBar = ({children}) => <div className="sov-pills">{children}</div>;

export const OverviewDecideCta = ({href, ariaLabel, title = SOV.decide.title, body = SOV.decide.body, children}) => <section className="sov-band" aria-label={ariaLabel}>
    <div className="sov-band-t">
      <div className="sov-band-h">{title}</div>
      <div className="sov-band-p">{body}</div>
    </div>
    <a className="hp-cta hp-cta-primary sov-cta" href={href}>{children}</a>
  </section>;

export const OverviewStartSection = ({title, lead, children}) => <section className="sov-start">
    <h2 className="sov-h2">{title}</h2>
    {lead && <div className="sov-lead">{lead}</div>}
    {children}
  </section>;

export const OverviewStartGrid = ({children}) => <div className="sov-tiles">{children}</div>;

export const OverviewStartTile = ({href, variant, title, desc, children}) => <a className="sov-tile" href={href}>
    <span className={`sov-tile-ic sov-tone-${SOV.tileTones[variant] || "yellow"}`}>{children}</span>
    <span className="sov-tile-t"><b>{title}</b>{desc && <span className="sov-tile-d">{desc}</span>}</span>
    <SovGlyph k="arrow" size={16} sw={1.5} />
  </a>;

export const OverviewMintlifyCardgroup = ({children}) => {
  const cards = [];
  const walk = n => sovUtil.els(n).forEach(x => {
    if (typeof x.props.title === "string" && x.props.href) cards.push(x.props); else walk(x.props.children);
  });
  walk(children);
  if (!cards.length) return <div>{children}</div>;
  return <div className="sov-logs">
      {cards.map(c => <a key={c.href} className="sov-log" href={c.href}>
          <b>{c.title}</b>
          <div className="sov-log-d">{c.children}</div>
          <span className="sov-log-go">Read the changelog<SovGlyph k="arrow" size={15} sw={1.6} /></span>
        </a>)}
    </div>;
};

<OverviewPage className="sdk-overview-wrap">
  <OverviewHero kicker="SDKs">
    <OverviewHeroMain title="Suki SDKs" lead="Suki provides npm packages and native client SDKs so you can embed Ambient Clinical Intelligence (ACI) into healthcare applications.">
      <OverviewHeroSections>
        <OverviewHeroSection title="Introduction">
          <OverviewHeroText>
            Suki SDKs help you build clinical AI into healthcare software for providers, nurses, and other care staff. Ambient documentation, Form filling, Dictation, and Patient Summary are the core workflows you can embed in web and mobile apps. Each SDK handles client-side authentication, audio streaming, and session management.
          </OverviewHeroText>

          <OverviewHeroText>
            Choose a hosted clinical UI, or a headless SDK when you want to build your own experience. For server-side session setup, webhooks, or note retrieval, use the Suki REST APIs with the SDK.
          </OverviewHeroText>

          <OverviewHeroText callout="Before upgrading">
            Features and upgrade requirements vary by SDK. Review each product's changelog and migration guide before upgrading.
          </OverviewHeroText>
        </OverviewHeroSection>

        <OverviewHeroSection eyebrow="Integration pattern" title="How it works">
          <OverviewHeroText>
            Each SDK follows the same integration pattern:
          </OverviewHeroText>

          <OverviewHeroSteps>
            <li>Configure authentication</li>
            <li>Initialize the SDK</li>
            <li>Create or resume a clinical session</li>
            <li>Capture audio or user input</li>
            <li>Receive clinical output such as transcripts, notes, completed forms, or a Patient Summary</li>
          </OverviewHeroSteps>
        </OverviewHeroSection>
      </OverviewHeroSections>

      <OverviewCtaRow>
        <HpCta href="/sdk-overview/quickstart">
          Get Started
        </HpCta>

        <HpCta href="/sdk-overview/authentication" variant="secondary">
          Authentication
        </HpCta>
      </OverviewCtaRow>
    </OverviewHeroMain>

    <OverviewHeroAside ariaLabel="SDK installation commands, support contact, and best practices">
      <OverviewMetaStack>
        <OverviewMetaCard title="Installation Commands">
          <OverviewDownloadList>
            <OverviewInstallRow clipboard="npm install @suki-sdk/react @suki-sdk/core" ariaLabel="Copy Web npm install command" label="Web">
              npm install @suki-sdk/react @suki-sdk/core
            </OverviewInstallRow>

            <OverviewInstallRow clipboard="# Mobile SDK (Xcode): download SukiAmbientCore.framework, drag it into the project navigator, set Embed & Sign. See /mobile-sdk/installation." ariaLabel="Copy Mobile Xcode setup reminder" label="Mobile">
              # Xcode: SukiAmbientCore.framework (Embed & Sign). See Mobile SDK installation.
            </OverviewInstallRow>

            <OverviewInstallRow clipboard="npm install @suki-sdk/platform-react" ariaLabel="Copy Headless npm install command" label="Headless">
              npm install @suki-sdk/platform-react
            </OverviewInstallRow>

            <OverviewInstallRow clipboard="npm install @suki-sdk/core @suki-sdk/dictation-react @suki-sdk/dictation" ariaLabel="Copy Dictation npm install command" label="Dictation">
              npm install @suki-sdk/core @suki-sdk/dictation-react @suki-sdk/dictation
            </OverviewInstallRow>

            <OverviewInstallRow clipboard="npm install @suki-sdk/core @suki-sdk/form-filling-react @suki-sdk/form-filling" ariaLabel="Copy Form filling npm install command" label="Form Filling">
              npm install @suki-sdk/core @suki-sdk/form-filling-react @suki-sdk/form-filling
            </OverviewInstallRow>
          </OverviewDownloadList>
        </OverviewMetaCard>

        <OverviewMetaCard title="Support & Best Practices">
          <OverviewKvStack>
            <OverviewMailRow label="SDK support" />
          </OverviewKvStack>

          <OverviewMetaBestPractices>
            <Tip>
              #### Best practices

              * Store **partnerId**, **partnerToken**, and issued tokens securely; rotate credentials per your security policy.
              * Request microphone permission before capture starts; handle denial and prompts clearly in your UI.
              * Send SDK traffic over HTTPS; surface authentication failures and network errors using the patterns in each SDK guide.
              * Test across devices, OS versions, and network conditions before production rollout.
              * Always use the **latest versions of the SDKs** to get the latest features and bug fixes.
            </Tip>
          </OverviewMetaBestPractices>
        </OverviewMetaCard>
      </OverviewMetaStack>
    </OverviewHeroAside>
  </OverviewHero>

  <OverviewWorkflowSection eyebrow="Choose your SDK workflow" titleId="sdk-overview-workflows-title" title="Available SDKs" lead="Pick the SDK for your use case and workflow and start building your integration.">
    <SdkWorkflowFilter>
      <SdkWorkflowFilterBar>
        <SdkWorkflowFilterPill value="all" active label="All" />

        <SdkWorkflowFilterPill value="ambient" label="Ambient">
          <SdkFilterIconAmbient />
        </SdkWorkflowFilterPill>

        <SdkWorkflowFilterPill value="dictation" label="Dictation">
          <SdkFilterIconDictation />
        </SdkWorkflowFilterPill>

        <SdkWorkflowFilterPill value="form-filling" label="Form Filling">
          <SdkFilterIconForms />
        </SdkWorkflowFilterPill>

        <SdkWorkflowFilterPill value="patient-summary" label="Patient Summary">
          <SdkFilterIconSummary />
        </SdkWorkflowFilterPill>
      </SdkWorkflowFilterBar>

      <OverviewWorkflowCards id="sdk-overview-workflow-cards-panel" ariaLabel="SDK cards for selected workflow">
        <OverviewWorkflowCard href="/web-sdk/index" ariaLabel="Web SDK" title="Web SDK" pills={["JavaScript", "React", "Headed"]} workflows="ambient,dictation,form-filling,patient-summary">
          <OverviewArtWeb />

          <SdkCardTipPanel title="Web SDK" what="Pre-built UI and React hooks for ambient clinical notes in the browser." whenWhy="Choose this when you want the fastest web integration with Suki's ready-made interface." features={["Ambient note generation", "Built-in recording UI", "Note management", "Patient Summary", "JavaScript and React packages"]} />
        </OverviewWorkflowCard>

        <OverviewWorkflowCard href="/mobile-sdk/index" ariaLabel="Mobile SDK" title="Mobile SDK" pills={["Swift", "iOS"]} workflows="ambient">
          <OverviewArtMobile />

          <SdkCardTipPanel title="Mobile SDK" what="Native iOS SDK for Ambient documentation in your mobile app." whenWhy="Choose this when you are building an iPhone or iPad app and need on-device ambient sessions." features={["Swift integration", "Ambient sessions", "Audio streaming", "Clinical note retrieval"]} />
        </OverviewWorkflowCard>

        <OverviewWorkflowCard href="/headless-web-sdk/index" ariaLabel="Headless SDK" title="Headless SDK" pills={["React", "Headless"]} workflows="ambient">
          <OverviewArtHeadless />

          <SdkCardTipPanel title="Headless SDK" what="React hooks and core APIs without pre-built UI components." whenWhy="Choose this when you want full control over layout and design while Suki handles sessions and audio." features={["Ambient hooks", "Session management", "Custom UI", "React 18+"]} />
        </OverviewWorkflowCard>

        <OverviewWorkflowCard href="/dictation-sdk/index" ariaLabel="Dictation SDK" title="Dictation SDK" pills={["React", "IFRAME"]} workflows="dictation">
          <OverviewArtMic />

          <SdkCardTipPanel title="Dictation SDK" what="Browser library for speech-to-text with a hosted iframe experience." whenWhy="Choose this when you need Dictation in text fields or a scratchpad without building audio capture yourself." features={["In-field and scratchpad modes", "Hosted iframe", "JavaScript and React", "Transcript callbacks"]} />
        </OverviewWorkflowCard>

        <OverviewWorkflowCard href="/form-filling-sdk/index" ariaLabel="Form filling SDK" title="Form Filling SDK" pills={["JavaScript", "React"]} workflows="form-filling">
          <OverviewArtForms />

          <SdkCardTipPanel title="Form Filling SDK" what="JavaScript and React library with hosted UI for voice-driven medical forms." whenWhy="Choose this when you need structured form output from visit conversation without building the full API workflow." features={["Hosted Form filling UI", "Template-driven output", "SDK callbacks", "Partner webhooks"]} />
        </OverviewWorkflowCard>
      </OverviewWorkflowCards>
    </SdkWorkflowFilter>
  </OverviewWorkflowSection>

  <OverviewDecideCta href="/documentation/get-started/integration-overview" ariaLabel="Decide your SDK path">
    Decide Your SDK Path
  </OverviewDecideCta>

  <OverviewStartSection title="Start building">
    <OverviewStartGrid>
      <OverviewStartTile href="/documentation/get-started/integration-decision-guide" variant="workflows" title="Workflows Overview" desc="Learn more about comparing SDKs and how to choose your integration path.">
        <SdkStartGlyphGrid />
      </OverviewStartTile>

      <OverviewStartTile href="/web-sdk/guides/ambient-implementation" variant="web" title="Web SDK - Create Session" desc="Build your first ambient session, stream audio, and retrieve the note in minutes.">
        <SdkStartGlyphReact />
      </OverviewStartTile>

      <OverviewStartTile href="/mobile-sdk/ambient-guides/create-session" variant="mobile" title="Mobile SDK - Create Session" desc="Build your first ambient session, stream audio, and retrieve the note in minutes.">
        <SdkStartGlyphPhone />
      </OverviewStartTile>

      <OverviewStartTile href="/headless-web-sdk/guides/hooks/ambient-hook" variant="headless" title="Headless Web SDK - Create Session" desc="Build your first ambient session, stream audio, and retrieve the note in minutes.">
        <SdkStartGlyphHeadless />
      </OverviewStartTile>

      <OverviewStartTile href="/dictation-sdk/guides/configuration" variant="dictation" title="Dictation SDK - Configuration" desc="Configure the Dictation SDK with your partner credentials and settings.">
        <SdkStartGlyphMic />
      </OverviewStartTile>

      <OverviewStartTile href="/web-sdk/quickstart" variant="quickstart" title="Web SDK Quickstart" desc="Build your first headed Web SDK flow in minutes.">
        <SdkStartGlyphRocket />
      </OverviewStartTile>

      <OverviewStartTile href="/headless-web-sdk/quickstart" variant="headless" title="Headless Web SDK Quickstart" desc="Build your first headless ambient flow in minutes.">
        <SdkStartGlyphRocket />
      </OverviewStartTile>

      <OverviewStartTile href="/documentation/get-started/partner-onboarding" variant="auth" title="Partner Onboarding" desc="Learn more about partner onboarding to start using Suki SDKs.">
        <SdkStartGlyphAuth />
      </OverviewStartTile>
    </OverviewStartGrid>
  </OverviewStartSection>

  <OverviewStartSection title="Stay updated" lead="Learn about the latest updates for the Web SDK, Mobile SDK, Headless Web SDK, and Dictation SDK.">
    <OverviewMintlifyCardgroup>
      <CardGroup cols={2}>
        <Card title="Web SDK Changelog" icon="bell-ring" href="/web-sdk/product-updates/changelog" arrow={true}>
          Releases and migration notes for the headed Web SDK packages.
        </Card>

        <Card title="Mobile SDK Changelog" icon="bell-ring" href="/mobile-sdk/product-updates/changelog" arrow={true}>
          iOS SDK updates, deprecations, and behavior changes.
        </Card>

        <Card title="Headless Web SDK Changelog" icon="bell-ring" href="/headless-web-sdk/changelog" arrow={true}>
          Platform React package updates for ambient hooks and clients.
        </Card>

        <Card title="Dictation SDK Changelog" icon="bell-ring" href="/dictation-sdk/changelog" arrow={true}>
          Dictation iframe and package updates for JavaScript and React tracks.
        </Card>
      </CardGroup>
    </OverviewMintlifyCardgroup>
  </OverviewStartSection>
</OverviewPage>


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