Skip to content

TypeScript SDK

@picora/sdk is the official TypeScript client for Picora. It runs on Node.js ≥ 18, Bun, Cloudflare Workers, and modern browsers.

Install

Terminal window
npm install @picora/sdk

Create 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 user
await picora.auth.me() // → User
await picora.auth.subscription() // → Subscription (plan + features + limits)
// Image management
await picora.images.list({ pageSize: 20 }) // → PaginatedResponse<Image>
await picora.images.get('abc123def45') // → Image
await picora.images.delete('abc123def45') // → void
// First-party SSO authorized apps (v0.30+)
await picora.apps.list() // → AuthorizedApp[]
await picora.apps.revoke('mw_picora') // → void

videos, 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
}
}
HTTPSDK classAuto-retry
200/201/204(success)
400/401/403/404/422PicoraApiErrorNo
429PicoraRateLimitErrorYes, up to 3× (1 s / 2 s / 4 s exponential)
500–504PicoraApiErrorYes, up to 2× (500 ms / 1500 ms)
Network failurePicoraNetworkErrorYes, up to 2× (network errors only)
TimeoutPicoraNetworkErrorNo (AbortError, treat as user-cancelled)

PicoraApiError exposes:

  • status — HTTP status code
  • code — Picora machine-readable error code (UNAUTHORIZED, QUOTA_EXCEEDED, RATE_LIMITED, …)
  • message — human-readable, localized to the user’s Accept-Language
  • meta — extra context (e.g. { retryAfterSec: 30 } on rate limit, { kbId: '…' } on KB-specific failures)
  • requestId — value of the X-Request-Id response 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.fetch once you inject one).
  • Wrap fetch for SSR runtimes that need extra cookies / observability hooks.
  • Run on Node < 18 by passing a node-fetch polyfill.

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 before 1.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.