TypeScript SDK
@picora/sdk is the official TypeScript client for Picora. It runs on Node.js ≥ 18, Bun, Cloudflare Workers, and modern browsers.
Install
npm install @picora/sdkCreate a client
import { createPicoraClient } from '@picora/sdk'
const picora = createPicoraClient({ apiKey: process.env.PICORA_API_KEY, // sk_live_... // OR (mutually exclusive): // oauthToken: process.env.PICORA_OAUTH_TOKEN,
baseUrl: 'https://api.picora.me', // default; switch to https://api.picora.cn for the China deployment timeout: 30_000, // ms; default 30s retryOnRateLimit: true, // default; auto-retry 429 up to 3× with exponential backoff retryOnServerError: true, // default; auto-retry 5xx and network errors up to 2× userAgent: 'MyApp/1.2', // SDK appends '@picora/sdk/<version>' debug: false,})Namespaces (v0.1.0)
// Authentication / current userawait picora.auth.me() // → Userawait picora.auth.subscription() // → Subscription (plan + features + limits)
// Image managementawait picora.images.list({ pageSize: 20 }) // → PaginatedResponse<Image>await picora.images.get('abc123def45') // → Imageawait picora.images.delete('abc123def45') // → void
// First-party SSO authorized apps (v0.30+)await picora.apps.list() // → AuthorizedApp[]await picora.apps.revoke('mw_picora') // → voidvideos, audio, docs, kbs, and mcp namespaces are scheduled for @picora/sdk@0.2.0 together with full OpenAPI codegen — the underlying HTTP endpoints are already public, so until v0.2 ships you can keep using fetch() for those resources.
Error model
import { PicoraApiError, PicoraRateLimitError, PicoraNetworkError,} from '@picora/sdk'
try { await picora.images.delete(id)} catch (err) { if (err instanceof PicoraRateLimitError) { console.warn(`Rate limited; retry in ${err.retryAfterSec}s`) } else if (err instanceof PicoraApiError && err.status === 404) { console.log('Image already deleted') } else if (err instanceof PicoraNetworkError) { console.error('Network blip:', err.cause?.message) } else { throw err }}| HTTP | SDK class | Auto-retry |
|---|---|---|
| 200/201/204 | (success) | — |
| 400/401/403/404/422 | PicoraApiError | No |
| 429 | PicoraRateLimitError | Yes, up to 3× (1 s / 2 s / 4 s exponential) |
| 500–504 | PicoraApiError | Yes, up to 2× (500 ms / 1500 ms) |
| Network failure | PicoraNetworkError | Yes, up to 2× (network errors only) |
| Timeout | PicoraNetworkError | No (AbortError, treat as user-cancelled) |
PicoraApiError exposes:
status— HTTP status codecode— Picora machine-readable error code (UNAUTHORIZED,QUOTA_EXCEEDED,RATE_LIMITED, …)message— human-readable, localized to the user’sAccept-Languagemeta— extra context (e.g.{ retryAfterSec: 30 }on rate limit,{ kbId: '…' }on KB-specific failures)requestId— value of theX-Request-Idresponse header for support correlation
SSR & test mocks
createPicoraClient({ fetch: customFetch }) accepts any fetch-compatible implementation. Use it to:
- Mock all HTTP calls in unit tests (the SDK never reaches
globalThis.fetchonce you inject one). - Wrap
fetchfor SSR runtimes that need extra cookies / observability hooks. - Run on Node < 18 by passing a
node-fetchpolyfill.
Versioning
The SDK follows semver:
- Patch (
0.1.x) — bug fixes, new convenience methods, no breaking changes. - Minor (
0.x.0) — new namespaces, new optional client options. - Major (
x.0.0) — breaking type / signature changes (none planned before1.0).
Every release is published to npm with provenance so consumers can verify the artifact came from this repo’s CI.
Provenance & deprecation policy
Once published, an SDK version cannot truly be unpublished. Picora’s policy is to issue a new patch + npm deprecate the bad version, never silent rewrite. If you ever see npm install @picora/sdk print a deprecation notice, upgrade to the suggested version — the deprecation message includes the reason.