{"_id":"@assistiv/sdk","_rev":"2-a82504d37e0c16bda8b3abb8ae07aca7","name":"@assistiv/sdk","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@assistiv/sdk","version":"0.1.0","keywords":["assistiv","ai","llm","gateway","inference","openai","mcp","sdk"],"license":"MIT","_id":"@assistiv/sdk@0.1.0","maintainers":[{"name":"itsmeshrey","email":"assistivai@gmail.com"}],"homepage":"https://assistiv.ai/docs","bugs":{"url":"https://github.com/Assistiv-AI/assistiv-sdk/issues"},"dist":{"shasum":"541271aa26a2021c801ea742af48016e6d1f5ade","tarball":"https://registry.npmjs.org/@assistiv/sdk/-/sdk-0.1.0.tgz","fileCount":17,"integrity":"sha512-D5mrn37NbLcjmtxEqPRWCK9ko1dWf7WZgKDt46Js5Hhsy+B6yuAutT9WQCecqgq7Sn/3Ox1dgKsjRZciTjufxg==","signatures":[{"sig":"MEQCIFLCO98EGEg6FCtm+WoybzmrYu1MczgmoXUfslqsps60AiB6OxOllM3yQBu7GRIRkHBsbtPYNuc+NUaanFqjxs5kjQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@assistiv%2fsdk@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":444470},"main":"./dist/server.cjs","type":"module","types":"./dist/server.d.ts","module":"./dist/server.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js","require":"./dist/server.cjs"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"}},"gitHead":"be8cb7e259064690fca8cfa41d330722379a299c","scripts":{"dev":"tsup --watch","lint":"eslint --ext .ts src tests --max-warnings 0","test":"vitest run","build":"tsup","generate":"tsx scripts/generate.ts","typecheck":"tsc --noEmit","test:watch":"vitest","drift-check":"tsx scripts/drift-check.ts"},"_npmUser":{"name":"itsmeshrey","email":"assistivai@gmail.com"},"repository":{"url":"git+https://github.com/Assistiv-AI/assistiv-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Official JavaScript SDK for the Assistiv AI Gateway. Inference, end-user management, billing, MCP, webhooks — one client.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"svix":"^1.28.0","openai":"^4.70.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.4.0","tsx":"^4.7.0","tsup":"^8.0.0","eslint":"^8.57.0","undici":"^6.19.0","vitest":"^2.0.0","typescript":"^5.4.0","@types/node":"^20.11.0","openapi-fetch":"^0.13.0","@changesets/cli":"^2.31.0","openapi-typescript":"^7.4.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1779285572458_0.5535263038722136","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@assistiv/sdk","version":"0.2.0","description":"Official JavaScript SDK for the Assistiv AI Gateway. Inference, end-user management, billing, MCP, webhooks — one client.","license":"MIT","type":"module","exports":{".":{"types":"./dist/server.d.ts","import":"./dist/server.js","require":"./dist/server.cjs"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"}},"main":"./dist/server.cjs","module":"./dist/server.js","types":"./dist/server.d.ts","scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","lint":"eslint --ext .ts src tests --max-warnings 0","generate":"tsx scripts/generate.ts","drift-check":"tsx scripts/drift-check.ts"},"devDependencies":{"@changesets/cli":"^2.31.0","@types/node":"^20.11.0","@typescript-eslint/eslint-plugin":"^7.0.0","@typescript-eslint/parser":"^7.0.0","eslint":"^8.57.0","msw":"^2.4.0","openapi-fetch":"^0.13.0","openapi-typescript":"^7.4.0","tsup":"^8.0.0","tsx":"^4.7.0","typescript":"^5.4.0","undici":"^6.19.0","vitest":"^2.0.0"},"dependencies":{"openai":"^4.70.0","svix":"^1.28.0"},"engines":{"node":">=18"},"publishConfig":{"access":"public","provenance":true},"keywords":["assistiv","ai","llm","gateway","inference","openai","mcp","sdk"],"repository":{"type":"git","url":"git+https://github.com/Assistiv-AI/assistiv-sdk.git"},"homepage":"https://assistiv.ai/docs","_id":"@assistiv/sdk@0.2.0","gitHead":"b8d6e5314e0f9900f55a274c396793484119cfcf","bugs":{"url":"https://github.com/Assistiv-AI/assistiv-sdk/issues"},"_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-IHBm8SpYDKpEJ0sPn5KEU+JclRaFfLRDVeMiL+g9OeQIWjxIW2G+4etI7PTsJiT/mMmhuLO/q/XXgE7Rzmnwdg==","shasum":"ecb7fb7a909f5cb94eb81d653ae2c79696efa20b","tarball":"https://registry.npmjs.org/@assistiv/sdk/-/sdk-0.2.0.tgz","fileCount":17,"unpackedSize":450294,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@assistiv%2fsdk@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIC6/22nvgwWBRPovAOkyE31KeF3gFdWsLrTLLKdTpttnAiEAkWopK4hNaHYZ7Wp/uZEjouRF3EalhV5cqhjRxpwUDLQ="}]},"_npmUser":{"name":"itsmeshrey","email":"assistivai@gmail.com"},"directories":{},"maintainers":[{"name":"itsmeshrey","email":"assistivai@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.2.0_1779286905610_0.8379221803475356"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-20T13:59:32.265Z","modified":"2026-05-20T14:21:46.235Z","0.1.0":"2026-05-20T13:59:32.650Z","0.2.0":"2026-05-20T14:21:45.783Z"},"bugs":{"url":"https://github.com/Assistiv-AI/assistiv-sdk/issues"},"license":"MIT","homepage":"https://assistiv.ai/docs","keywords":["assistiv","ai","llm","gateway","inference","openai","mcp","sdk"],"repository":{"type":"git","url":"git+https://github.com/Assistiv-AI/assistiv-sdk.git"},"description":"Official JavaScript SDK for the Assistiv AI Gateway. Inference, end-user management, billing, MCP, webhooks — one client.","maintainers":[{"name":"itsmeshrey","email":"assistivai@gmail.com"}],"readme":"# @assistiv/sdk\n\nOfficial TypeScript / JavaScript SDK for the **[Assistiv AI Gateway](https://assistiv.ai)**.\nOne client, OpenAI-compatible, with per-user wallets, budgets, rate\nlimits, tool calls, and webhooks built in.\n\n```bash\nnpm install @assistiv/sdk\n```\n\n```ts\nimport { Assistiv } from \"@assistiv/sdk\";\n\nconst platform = new Assistiv({ apiKey: process.env.ASSISTIV_PLATFORM_KEY! });\n\n// Provision one of your end-users (idempotent).\nconst { endUserId, apiKey } = await platform.bootstrap({\n  platformId: process.env.ASSISTIV_PLATFORM_ID!,\n  externalId: \"user_42\",\n  defaultBudget: { max_usd: 5, period: \"monthly\" },\n});\n\n// Use the returned sk-eu_* key to run inference for that user.\nconst assistiv = new Assistiv({ apiKey });\nconst reply = await assistiv.chat.completions.create({\n  model: \"gpt-4o-mini\",\n  messages: [{ role: \"user\", content: \"Say hi\" }],\n});\nconsole.log(reply.choices[0].message.content);\n```\n\nWhat this gives you in three sentences: every popular LLM (OpenAI,\nAnthropic, Google, xAI) behind one endpoint that speaks the OpenAI\nschema; per-end-user spend caps, rate limits, and audit logs without\nbuilding any of that yourself; and an MCP-compatible tool layer so\nagents can hit GitHub / Slack / Zoho / Zendesk through the same key.\n\n> **For AI agents reading this file** — this README is the canonical\n> integration doc. Hit `https://www.assistiv.ai/llms-sdk.txt` for the\n> machine-friendly feed if you want every per-feature snippet in one\n> blob. The patterns below are sufficient for adding Assistiv to any\n> product.\n\n---\n\n## Auth model\n\nAssistiv has two key types. Use the right one for the call:\n\n| Key prefix     | Lives where           | What it can do                                                                                  |\n|----------------|-----------------------|-------------------------------------------------------------------------------------------------|\n| `sk-plat_*`    | Your **server only**  | Provision end-users, mint per-user keys, manage budgets, read logs, register MCP configs.       |\n| `sk-eu_*`      | Server OR browser     | Run inference (`chat`, `responses`, `models`), call tools, read own budget / rate-limit / logs. |\n\n```ts\n// Server (Node 18+ / Bun / Deno / serverless)\nimport { Assistiv } from \"@assistiv/sdk\";\nconst platform = new Assistiv({ apiKey: process.env.ASSISTIV_PLATFORM_KEY! });\n\n// Browser / mobile / Electron\nimport { Assistiv } from \"@assistiv/sdk/browser\";\nconst assistiv = new Assistiv({ apiKey: endUserKey }); // sk-eu_* only\n```\n\nThe browser entry refuses any `sk-plat_*` key at construction time.\nNever ship a platform key to a client.\n\n---\n\n## Provisioning end-users — `bootstrap()`\n\nMost platforms do one operation when a new user signs up: create the\nend-user record, mint their key, seed a budget, optionally set a rate\nlimit. `bootstrap()` is the one-call version of that flow.\n\n```ts\nconst { endUserId, apiKey, budget, rateLimit } = await platform.bootstrap({\n  platformId: process.env.ASSISTIV_PLATFORM_ID!,\n  externalId: \"user_42\",                            // your stable user id\n  displayName: \"Jane Smith\",                        // optional\n  metadata: { plan: \"pro\" },                        // optional, opaque JSON\n\n  defaultBudget: { max_usd: 5, period: \"monthly\" }, // optional\n  defaultRateLimit: { rpm_limit: 60, tpm_limit: 50_000 }, // optional\n});\n\n// Persist `apiKey` immediately — the raw key is shown ONCE.\n// Recommended: store alongside your user row, encrypted at rest.\nawait db.users.update(user.id, { assistiv_key: apiKey, assistiv_end_user_id: endUserId });\n```\n\nIdempotent on `externalId` — repeat calls with the same id return the\nexisting user and **mint a fresh key**. This is for retry safety, not\nkey retrieval. Store the key once and reuse it.\n\n---\n\n## Inference\n\nOpenAI-compatible. Anything `openai.chat.completions.create` accepts\nworks here, with the same response shape.\n\n### Non-streaming\n\n```ts\nconst reply = await assistiv.chat.completions.create({\n  model: \"gpt-4o-mini\",            // or claude-sonnet-4-6, gemini-2.0-flash, grok-2, …\n  messages: [\n    { role: \"system\", content: \"You are a helpful assistant.\" },\n    { role: \"user\", content: \"Plan a 3-day trip to Tokyo.\" },\n  ],\n  temperature: 0.7,\n  max_tokens: 800,\n});\n```\n\n### Streaming\n\n```ts\nconst stream = await assistiv.chat.completions.create({\n  model: \"gpt-4o-mini\",\n  messages: [{ role: \"user\", content: \"Count to 10, one number per line.\" }],\n  stream: true,\n});\nfor await (const chunk of stream) {\n  process.stdout.write(chunk.choices[0]?.delta?.content ?? \"\");\n}\n```\n\n### Tool calling\n\n```ts\nconst reply = await assistiv.chat.completions.create({\n  model: \"gpt-4o-mini\",\n  messages,\n  tools: [{\n    type: \"function\",\n    function: {\n      name: \"get_weather\",\n      description: \"Get the current weather in a city.\",\n      parameters: { type: \"object\", properties: { city: { type: \"string\" } } },\n    },\n  }],\n});\n```\n\n### Responses API (stateful alt)\n\n```ts\nconst res = await assistiv.responses.create({\n  model: \"gpt-4o-mini\",\n  input: \"Plan a trip\",\n});\n```\n\n### Listing available models\n\n```ts\nconst { data: models } = await assistiv.models.list();\n// Only models your platform has configured providers for.\n```\n\n### Engine-native escape hatch\n\nAnything OpenAI's npm client supports, you can do too:\n\n```ts\nconst openai = Assistiv.openai(assistiv);\nconst parsed = await openai.beta.chat.completions.parse({ /* ... */ });\n```\n\n---\n\n## Per-end-user state\n\n### From the platform side (`sk-plat_*`)\n\n```ts\n// Budgets — per-user spend caps with idempotent topups\nawait platform.budgets(platformId).create(endUserId, {\n  max_usd: 10,\n  period: \"monthly\",\n  auto_replenish: true,\n  replenish_amount: 10,\n  low_balance_threshold: 1,\n});\n\nawait platform.budgets(platformId).topup(\n  endUserId,\n  { amount_usd: 5, reason: \"promo_grant\" },\n  { idempotencyKey: \"promo-2026-q2\" }, // safe to retry the same call\n);\n\n// Per-user rate-limit overrides (higher than platform default)\nawait platform.rateLimits(platformId).setForEndUser(endUserId, {\n  rpm_limit: 600,\n  tpm_limit: 250_000,\n});\n\n// Logs — what did this user do\nconst logs = await platform.logs(platformId).search({\n  end_user_id: endUserId,\n  since: new Date(Date.now() - 86_400_000).toISOString(),\n});\n```\n\n### From the end-user side (`sk-eu_*` — used by your app frontend)\n\n```ts\nconst me = await assistiv.me.budget();           // { max_usd, used_usd, remaining_usd, period }\nconst limits = await assistiv.me.rateLimits();   // current effective limits\nconst ledger = await assistiv.me.budgetTransactions({ limit: 100 });\nconst myLogs = await assistiv.me.logs();\n```\n\n---\n\n## MCP tools (GitHub, Slack, Zoho, Zendesk, …)\n\nTwo-step model: you activate an app for your platform in the dashboard\n(OAuth secret never leaves the Assistiv UI), then your end-users connect\ntheir own account via OAuth from your product.\n\n```ts\n// Read which apps your platform has activated — to render\n// \"Connect GitHub\" / \"Connect Slack\" UI in your product.\nconst { data: apps } = await platform.mcp(platformId).listApps();\n\n// For your end-users at runtime: the agent connects directly to\n// the MCP protocol endpoint with their sk-eu_* key.\n//   POST https://mcp.assistiv.ai/mcp\n//   Authorization: Bearer sk-eu_...\n//   { \"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools/list\" }\n```\n\nActivating, editing, and rotating OAuth credentials for an MCP app is a\ndashboard task — there is no SDK or REST API for it (write-once secrets\nshould not round-trip through your code).\n\n---\n\n## Webhooks\n\nAssistiv pushes real-time events when budgets and wallets change. Six\nevent types you can subscribe to:\n\n- `budget.topped_up` — credit added to an end-user's budget\n- `budget.debited` — any debit (inference call, manual debit, etc.)\n- `budget.low_balance` — crossed your low-balance threshold\n- `budget.suspended` — explicit suspension\n- `budget.unsuspended` — reactivated\n- `wallet.low_balance` — platform-wallet warning\n\nRegister endpoint URLs in **Dashboard → Outbound Webhooks** and copy the\nsigning secret into your server. Verify every payload:\n\n```ts\nimport express from \"express\";\nimport { verifyWebhook } from \"@assistiv/sdk\";\n\nconst app = express();\n\napp.post(\n  \"/assistiv-events\",\n  express.raw({ type: \"application/json\" }),\n  (req, res) => {\n    const ok = verifyWebhook(\n      req.body,\n      req.headers,\n      process.env.ASSISTIV_WEBHOOK_SECRET!,\n    );\n    if (!ok) return res.status(400).end();\n\n    const event = JSON.parse(req.body.toString());\n    switch (event.event_type) {\n      case \"budget.low_balance\":\n        // notify the user, top up, or pause\n        break;\n      case \"wallet.low_balance\":\n        // top up the platform wallet\n        break;\n    }\n    res.status(200).end();\n  },\n);\n```\n\nFailed deliveries retry automatically. Use the Svix portal in the\ndashboard to inspect or replay any event.\n\n---\n\n## Errors\n\nThe SDK throws a small typed hierarchy. Catch specifically — never just\n`catch (e)` without inspecting.\n\n```ts\nimport {\n  AssistivAuthError,            // 401 — bad / missing key\n  AssistivPaymentRequiredError, // 402 — wallet OR budget exhausted\n  AssistivForbiddenError,       // 403 — key-type or scope violation\n  AssistivNotFoundError,        // 404 — resource missing\n  AssistivConflictError,        // 409 — idempotency clash\n  AssistivRateLimitError,       // 429 — has `.retryAfter` seconds\n  AssistivServerError,          // 5xx — Assistiv-side\n  AssistivError,                // base class for everything above\n} from \"@assistiv/sdk\";\n```\n\n### 402 branching — what's actually wrong\n\nOn a 402 from `chat.completions.create`, branch on `error.code`:\n\n```ts\ntry {\n  await assistiv.chat.completions.create({ /* … */ });\n} catch (e) {\n  if (e instanceof AssistivPaymentRequiredError) {\n    switch (e.code) {\n      case \"wallet_insufficient\":\n        // The platform wallet is empty. Surface to platform admin;\n        // top up the wallet in the Assistiv dashboard.\n        break;\n      case \"budget_exhausted\":\n        // This end-user's per-user budget is empty.\n        // Top up with platform.budgets(pid).topup(...).\n        break;\n      case \"budget_suspended\":\n        // is_suspended=true on this user. Unsuspend manually.\n        break;\n    }\n  }\n}\n```\n\n### Rate-limit handling\n\n```ts\ntry {\n  await assistiv.chat.completions.create({ /* … */ });\n} catch (e) {\n  if (e instanceof AssistivRateLimitError) {\n    await new Promise((r) => setTimeout(r, (e.retryAfter ?? 1) * 1000));\n    // retry…\n  }\n}\n```\n\nEvery error carries `.status`, `.code`, `.message`, and `.requestId` so\nyou can report incidents back to Assistiv with one click.\n\n---\n\n## What this SDK does NOT do\n\nEverything below is dashboard-only (Supabase auth, not an API key) and\nis intentionally absent from the SDK. The dashboard URL points to the\nright form:\n\n| Operation                              | Where                                            |\n|----------------------------------------|--------------------------------------------------|\n| Top up the platform wallet (Stripe)    | `assistiv.ai/dashboard/settings`                 |\n| Add OpenAI / Anthropic / Google keys   | `assistiv.ai/dashboard/llm-configs`              |\n| Register outbound webhook endpoints    | `assistiv.ai/dashboard/outbound-webhooks`        |\n| Invite teammates                       | `assistiv.ai/dashboard/team`                     |\n| Activate an MCP app (OAuth secrets)    | `assistiv.ai/dashboard/mcp`                      |\n| Upload a private skill                 | `assistiv.ai/dashboard/skills`                   |\n| Provision a new platform               | Email `platforms@assistiv.ai` (not self-serve)   |\n\nThese are write-once secret operations or one-time setup steps. Putting\nthem in the SDK would mean those secrets round-tripping through your\ncode, which adds an unnecessary handling surface.\n\n---\n\n## Versions\n\n- **SDK semver:** strict semver from `1.0.0` onward. Pre-1.0 minor bumps\n  may include breaking changes; check the\n  [CHANGELOG](./CHANGELOG.md).\n- **API version:** `v0.1.0` (the URL prefix `/v1` is stable; the\n  underlying schema version ships in `X-Assistiv-Api-Version`).\n- **Provenance:** each npm release ships a Sigstore SLSA v1 attestation\n  linked to its source commit. `npm install --foreground-scripts\n  @assistiv/sdk` shows the verification badge.\n\n---\n\n## References\n\n- **Docs site:** https://www.assistiv.ai/docs\n- **Per-feature feed for AI agents:**\n  - https://www.assistiv.ai/llms-sdk.txt — SDK-flavoured (this surface)\n  - https://www.assistiv.ai/llms-api.txt — raw HTTP / curl flavoured\n  - https://www.assistiv.ai/llms-full.txt — everything\n- **API status:** https://status.assistiv.ai\n- **Support:** support@assistiv.ai\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}