@turtini/sdk — typed Public API client for Node, browser, and Deno
@turtini/sdk is the official typed client for the Public API. It wraps fetch with Bearer auth, automatic Idempotency-Key generation per write, exponential-backoff retries on 429/5xx, and typed error classes — so your integration code is six lines, not sixty.
Install:
npm install @turtini/sdk
The package has two import surfaces:
• @turtini/sdk/api — Public API client only (no React deps; safe for Node, browser, Deno, Cloudflare Workers, edge runtimes)
• @turtini/sdk/module — Module SDK only (the existing in-platform module hooks)
• @turtini/sdk — re-exports both for convenience
Quickstart:
import { Turtini } from '@turtini/sdk/api'
const turtini = new Turtini({
apiKey: process.env.TURTINI_API_KEY!,
// baseUrl: 'https://api.turtini.com', // optional override
// timeoutMs: 30000, // optional
})
// Read — pagination iterator
for await (const article of turtini.articles.iter()) {
console.log(article.title)
}
// Write — create a contact (Idempotency-Key auto-generated)
const contact = await turtini.contacts.create({
firstName: 'Ada',
lastName: 'Lovelace',
email: '[email protected]',
})
// Verify the bound org from your code
const me = await turtini.auth.whoami()
console.log('Connected to org:', me.orgName)
Typed resources: turtini.contacts, turtini.articles, turtini.events, turtini.accounts, turtini.opportunities, turtini.auth. Each exposes list / iter / get / create where supported. TypeScript types mirror the wire format exactly.
Error handling:
import { TurtiniError, TurtiniAuthError, TurtiniScopeError, TurtiniRateLimitError } from '@turtini/sdk/api'
try {
await turtini.contacts.create({ ... })
} catch (e) {
if (e instanceof TurtiniScopeError) console.error('Need contacts:write scope')
else if (e instanceof TurtiniAuthError) console.error('Bad API key')
else if (e instanceof TurtiniRateLimitError) console.error('Slow down — retrying after', e.retryAfterMs)
else if (e instanceof TurtiniError) console.error(e.code, e.status, e.message)
else throw e
}
Idempotency: every write call generates a UUID v4 and sends it as Idempotency-Key. You can override it per call by passing { idempotencyKey: '...' } as the second arg, or disable retries entirely with { retries: 0 }.
Browser usage: the SDK works in browsers, but it'll log a warning if you use a write scope from the browser — keys are bearer secrets and shouldn't ship in client bundles. For browser apps, use a server-side proxy instead.
Org context (natural language): turtini.context.query('what shipped this week?') returns a grounded summary of your org's state — modules enabled, top-line counts, recent activity. Useful for AI agents that need org-level context the typed list/read endpoints can't easily express. Required scope: context:read.
Versioning: the SDK is at 0.3.0 today (read + write + context). Pin a major version in your package.json — we'll preserve compatibility within a major.
Source / issues: github.com/turtini/sdk-public — bug reports and PRs welcome.