{
  "slug": "sdk/parity",
  "title": "SDK Parity & Divergence",
  "description": "Intentional API differences across the four Cuitty SDKs.",
  "url": "https://cuitty.com/docs/sdk/parity",
  "markdown_url": "https://cuitty.com/docs/sdk/parity.md",
  "json_url": "https://cuitty.com/docs/sdk/parity.json",
  "frontmatter": {
    "title": "SDK Parity & Divergence",
    "description": "Intentional API differences across the four Cuitty SDKs.",
    "order": 5,
    "section": "SDK",
    "updatedAt": "2026-04-28"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "sdk-parity--divergence",
      "text": "SDK Parity & Divergence"
    },
    {
      "depth": 2,
      "slug": "capability-matrix",
      "text": "Capability matrix"
    },
    {
      "depth": 2,
      "slug": "things-that-are-the-same-across-all-four-sdks",
      "text": "Things that ARE the same across all four SDKs"
    },
    {
      "depth": 2,
      "slug": "where-to-find-authoritative-behavior",
      "text": "Where to find authoritative behavior"
    }
  ],
  "body_markdown": "# SDK Parity & Divergence\n\nThe Cuitty SDKs share a wire protocol but each takes the idiomatic shape of its language. This page documents the intentional differences.\n\n## Capability matrix\n\n| Feature | TypeScript | Python | Go | Rust |\n| --- | --- | --- | --- | --- |\n| Async-first | Implicit (Promise) | Sync (async on roadmap) | Sync, ctx-aware | Async (Tokio) |\n| Plugin model | `client.use(plugin)` | `client.audit`, `client.logs` | `client.Audit`, `client.Logs` | `client.audit()`, `client.logs()` |\n| Path B retry | Yes (5xx + 429) | Yes (5xx + 429) | Yes (5xx + 429) | Yes (5xx + 429) |\n| Idempotency keys | Yes (UUID v4) | Yes | Yes | Yes |\n| Hono adapter | Yes | n/a | n/a | n/a |\n| Pino bridge | Yes | n/a (stdlib logging adapter on roadmap) | n/a (slog) | n/a (tracing) |\n| Concurrency-safe | Yes | Yes | Yes | Yes (Arc-cloned client) |\n\n## Things that ARE the same across all four SDKs\n\n- Wire format: identical JSON bodies for the same logical event\n- Idempotency: UUID v4 in `X-Idempotency-Key` header on every Path B batch\n- Retry: 3 attempts, exponential backoff (250 ms → 1 s → 4 s)\n- 4xx behavior: drop with warn log, no retry\n- 429 behavior: honor `Retry-After`\n- Auth: `Authorization: Bearer <api_key>` plus `X-Project-Id`\n- Batch triggers: ≥1000 events or ≥1 MiB or ≥250 ms idle\n- Close semantics: `close()` flushes pending events synchronously\n\nIf your code depends on something that's the same across SDKs but isn't on this list, it might still be safe — but it's not promised. Open an issue and we'll add it (or document why it's not promised).\n\n## Where to find authoritative behavior\n\nThe wire protocol is documented in [`packages/wire-protocol/openapi.yaml`](https://gitlab.com/cuitty/wire-protocol/openapi.yaml). The SDK-specific READMEs document divergences from that protocol in their \"Spec Drift\" sections.\n\nLive SDK-by-SDK benchmarks: [https://benchmarks.cuitty.com/sdks](https://benchmarks.cuitty.com/sdks).",
  "body_html": "<h1 id=\"sdk-parity--divergence\">SDK Parity &#x26; Divergence</h1>\n<p>The Cuitty SDKs share a wire protocol but each takes the idiomatic shape of its language. This page documents the intentional differences.</p>\n<h2 id=\"capability-matrix\">Capability matrix</h2>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Feature</th><th>TypeScript</th><th>Python</th><th>Go</th><th>Rust</th></tr></thead><tbody><tr><td>Async-first</td><td>Implicit (Promise)</td><td>Sync (async on roadmap)</td><td>Sync, ctx-aware</td><td>Async (Tokio)</td></tr><tr><td>Plugin model</td><td><code>client.use(plugin)</code></td><td><code>client.audit</code>, <code>client.logs</code></td><td><code>client.Audit</code>, <code>client.Logs</code></td><td><code>client.audit()</code>, <code>client.logs()</code></td></tr><tr><td>Path B retry</td><td>Yes (5xx + 429)</td><td>Yes (5xx + 429)</td><td>Yes (5xx + 429)</td><td>Yes (5xx + 429)</td></tr><tr><td>Idempotency keys</td><td>Yes (UUID v4)</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Hono adapter</td><td>Yes</td><td>n/a</td><td>n/a</td><td>n/a</td></tr><tr><td>Pino bridge</td><td>Yes</td><td>n/a (stdlib logging adapter on roadmap)</td><td>n/a (slog)</td><td>n/a (tracing)</td></tr><tr><td>Concurrency-safe</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes (Arc-cloned client)</td></tr></tbody></table>\n<h2 id=\"things-that-are-the-same-across-all-four-sdks\">Things that ARE the same across all four SDKs</h2>\n<ul>\n<li>Wire format: identical JSON bodies for the same logical event</li>\n<li>Idempotency: UUID v4 in <code>X-Idempotency-Key</code> header on every Path B batch</li>\n<li>Retry: 3 attempts, exponential backoff (250 ms → 1 s → 4 s)</li>\n<li>4xx behavior: drop with warn log, no retry</li>\n<li>429 behavior: honor <code>Retry-After</code></li>\n<li>Auth: <code>Authorization: Bearer &#x3C;api_key></code> plus <code>X-Project-Id</code></li>\n<li>Batch triggers: ≥1000 events or ≥1 MiB or ≥250 ms idle</li>\n<li>Close semantics: <code>close()</code> flushes pending events synchronously</li>\n</ul>\n<p>If your code depends on something that’s the same across SDKs but isn’t on this list, it might still be safe — but it’s not promised. Open an issue and we’ll add it (or document why it’s not promised).</p>\n<h2 id=\"where-to-find-authoritative-behavior\">Where to find authoritative behavior</h2>\n<p>The wire protocol is documented in <a href=\"https://gitlab.com/cuitty/wire-protocol/openapi.yaml\"><code>packages/wire-protocol/openapi.yaml</code></a>. The SDK-specific READMEs document divergences from that protocol in their “Spec Drift” sections.</p>\n<p>Live SDK-by-SDK benchmarks: <a href=\"https://benchmarks.cuitty.com/sdks\">https://benchmarks.cuitty.com/sdks</a>.</p>",
  "links_out": [
    "https://gitlab.com/cuitty/wire-protocol/openapi.yaml",
    "https://benchmarks.cuitty.com/sdks"
  ]
}