SDK
SDK Parity & Divergence
Intentional API differences across the four Cuitty SDKs.
SDK Parity & Divergence
The Cuitty SDKs share a wire protocol but each takes the idiomatic shape of its language. This page documents the intentional differences.
Capability matrix
| Feature | TypeScript | Python | Go | Rust |
|---|---|---|---|---|
| Async-first | Implicit (Promise) | Sync (async on roadmap) | Sync, ctx-aware | Async (Tokio) |
| Plugin model | client.use(plugin) | client.audit, client.logs | client.Audit, client.Logs | client.audit(), client.logs() |
| Path B retry | Yes (5xx + 429) | Yes (5xx + 429) | Yes (5xx + 429) | Yes (5xx + 429) |
| Idempotency keys | Yes (UUID v4) | Yes | Yes | Yes |
| Hono adapter | Yes | n/a | n/a | n/a |
| Pino bridge | Yes | n/a (stdlib logging adapter on roadmap) | n/a (slog) | n/a (tracing) |
| Concurrency-safe | Yes | Yes | Yes | Yes (Arc-cloned client) |
Things that ARE the same across all four SDKs
- Wire format: identical JSON bodies for the same logical event
- Idempotency: UUID v4 in
X-Idempotency-Keyheader on every Path B batch - Retry: 3 attempts, exponential backoff (250 ms → 1 s → 4 s)
- 4xx behavior: drop with warn log, no retry
- 429 behavior: honor
Retry-After - Auth:
Authorization: Bearer <api_key>plusX-Project-Id - Batch triggers: ≥1000 events or ≥1 MiB or ≥250 ms idle
- Close semantics:
close()flushes pending events synchronously
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).
Where to find authoritative behavior
The wire protocol is documented in packages/wire-protocol/openapi.yaml. The SDK-specific READMEs document divergences from that protocol in their “Spec Drift” sections.
Live SDK-by-SDK benchmarks: https://benchmarks.cuitty.com/sdks.