@ostuu/sdk
v0.1.0-alpha.0
Published
Ostuu API v1 TypeScript client (alpha)
Readme
@ostuu/sdk (alpha)
Thin typed client for Ostuu API v1.
Status: 0.1.0-alpha.0 — release commit prepared for npm alpha; do not publish until explicitly approved.
The SDK calls Ostuu API v1 only. It never talks to Facebook, LinkedIn, Bluesky, rsi.gl, or Vercel Blob directly, and never needs provider credentials.
CLI and MCP are not available yet.
Install (when published)
npm install @ostuu/[email protected]Requires Node.js ≥ 20. ESM-only. Works in modern browsers that provide fetch, Blob, and FormData.
Authentication
import { Ostuu } from "@ostuu/sdk";
const ostuu = new Ostuu({
apiKey: process.env.OSTUU_API_KEY!,
// baseUrl: "https://www.ostuu.com", // default
});Set OSTUU_API_KEY to a workspace API key from Ostuu Settings (ostuu_live_… / ostuu_test_…).
The client never logs the key, redacts it from toJSON / inspect output, and does not persist it.
Resources
await ostuu.brands.list();
await ostuu.brands.create({ brandName: "Acme" }, { idempotencyKey });
await ostuu.brands.get(id);
await ostuu.brands.update(id, { brandName: "Acme Co" }, { idempotencyKey });
await ostuu.brands.archive(id, { idempotencyKey });
await ostuu.brands.restore(id, { idempotencyKey });
await ostuu.destinations.list();
await ostuu.destinations.get(id);
await ostuu.destinations.setBrand(id, brandId, { idempotencyKey });
await ostuu.posts.list({ status: "DRAFT" });
await ostuu.posts.create({ content: { text: "Hello" } }, { idempotencyKey });
await ostuu.posts.get(id);
await ostuu.posts.update(id, { content: { text: "Hi" } }, { idempotencyKey });
await ostuu.posts.schedule(id, { scheduledAt: iso }, { idempotencyKey });
await ostuu.posts.unschedule(id, { idempotencyKey });
await ostuu.posts.archive(id, { idempotencyKey });
await ostuu.posts.restore(id, { idempotencyKey });
await ostuu.posts.preflight(id, { destinationIds });
await ostuu.posts.publish(id, { idempotencyKey, destinationIds });
await ostuu.posts.listJobs(id);
await ostuu.posts.getJob(id, jobId);
await ostuu.media.list();
await ostuu.media.get(id);
await ostuu.media.uploadImage({ file, fileName: "a.png" }, { idempotencyKey });
await ostuu.media.delete(id, { idempotencyKey });
await ostuu.links.list();
await ostuu.links.create({ url: "https://example.com" }, { idempotencyKey });
await ostuu.links.get(id);Idempotency
All write methods require an explicit idempotencyKey. Prefer:
import { createIdempotencyKey } from "@ostuu/sdk";
const idempotencyKey = createIdempotencyKey();
await ostuu.posts.create({ content: { text: "Hi" } }, { idempotencyKey });
// On network uncertainty, retry with the SAME key — never generate a new one.The SDK does not automatically retry writes. Preflight does not use idempotency keys.
ostuu.lastRequest exposes { status, requestId, idempotencyKey } for the latest call.
Errors
import { OstuuApiError, OstuuConfigError, OstuuNetworkError, OstuuTimeoutError } from "@ostuu/sdk";
try {
await ostuu.brands.list();
} catch (err) {
if (err instanceof OstuuApiError) {
console.error(err.status, err.code, err.requestId);
}
}API keys never appear in error messages.
Media upload
- Direct API upload: images only, max 3.5 MB file
- Larger files and video: use the Ostuu web media library until a future upload protocol ships
- Responses are metadata only (no private Blob URLs)
import { blobFromBytes } from "@ostuu/sdk";
const file = blobFromBytes(pngBytes, "image/png");
await ostuu.media.uploadImage(
{ file, fileName: "pixel.png", brandId, altText: "…" },
{ idempotencyKey }
);Pagination
List methods accept { limit, cursor, … } and return { data, pagination: { nextCursor, … } }.
Timeouts / cancellation
const ostuu = new Ostuu({ apiKey, timeoutMs: 30_000 });
const ac = new AbortController();
await ostuu.brands.list({ signal: ac.signal });Version stability
Pin exact alpha versions. Initial npm publish (when approved) will use tag alpha, not latest.
