# Assistiv Gateway — API (HTTP / curl) reference feed This file concatenates every per-feature integration guide, filtered to the raw HTTP surface (curl, fetch). Use this as agent context for any agent integrating against api.assistiv.ai directly. For the @assistiv/sdk flavour, see /llms-sdk.txt. # Assistiv — API Keys API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Manage the platform's API keys. Create new platform keys (multiple allowed for rotation), list with prefix-only visibility, revoke immediately. Full hashes are never returned after creation — store the raw key on issuance or generate a new one. ## How to integrate 1. List with `GET /v1/platforms/{platformId}/api-keys` — returns `key_prefix` only. 2. Create with `POST /v1/platforms/{platformId}/api-keys` — `raw_key` returned ONCE. 3. Revoke with `DELETE /v1/platforms/{platformId}/api-keys/{keyId}` — invalidates Redis cache within ~1s. ## curl example ```bash # Create a new platform API key (raw_key returned ONCE). curl -X POST https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/api-keys \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Production server"}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Authentication API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Two long-lived bearer tokens. `sk-plat_*` (platform key) authorizes management — create end-users, configure LLM providers, manage budgets. `sk-eu_*` (end-user key) authorizes runtime inference and tool calls on behalf of one user. Send the token in the `Authorization: Bearer` header. Multi-platform owners must also send `X-Assistiv-Platform-Id`. ## How to integrate 1. Provision a platform key in the Assistiv dashboard (Settings → API Keys). 2. Store it server-side only. Never ship to the browser. 3. For inference, mint an end-user key per user via `POST /v1/platforms/{platformId}/end-users` and store its `raw_key` — it is shown ONCE. ## curl example ```bash # Every request uses Authorization: Bearer . # Multi-platform owners also send X-Assistiv-Platform-Id. curl https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/end-users \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "X-Assistiv-Platform-Id: $ASSISTIV_PLATFORM_ID" ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Budgets API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Per-end-user USD budgets with one_time / daily / monthly periods. Idempotent topup/debit via `Idempotency-Key` header, full transaction ledger at `/budget/transactions`, and a `is_suspended` flag to pause access without losing state. ## How to integrate 1. Create with `POST /v1/platforms/{platformId}/end-users/{endUserId}/budget`. 2. Top up with `POST /v1/.../budget/topup` — pass `Idempotency-Key` to make retries safe. 3. Inspect ledger with `GET /v1/.../budget/transactions?limit=100`. ## curl example ```bash # Top up an end-user's budget with idempotency. curl -X POST https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/end-users/$END_USER_ID/budget/topup \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: stipend-2026-05" \ -d '{"amount_usd":5,"reason":"monthly_stipend"}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Capabilities API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Capabilities are paid, real-world API actions your end users' agents can discover and call on demand — image generation, geolocation, web scraping, data enrichment, translation, and more. Two levels: a **Capability** is the category (e.g. "Image Generation"); a **Capability Provider** is one concrete endpoint under it, listed cheapest-first with an observed price range, a rating, and a health state. Calls are pay-per-use, billed to the calling end user's USD budget. ## How it works - **Enablement is set by Assistiv.** Turning Capabilities on grants your platform access to a shared settlement wallet and a spend policy: curated vs open mode, an allowlist/denylist, a per-call price ceiling, and rating + health bars. Ask Assistiv to enable it for your platform. Until then the catalog is browseable but `search` and `run` return `403`. - **You roll it out to end users** by giving each one a `sk-eu_*` key and a budget. A run with no budget returns `402`. - **Every call re-quotes live.** Catalog prices are indicative; the binding price is the fresh quote at call time, capped by your policy ceiling and optionally tightened per call by `max_pay` (it can only lower the ceiling, never raise it). ## How to integrate 1. Browse the shelf: `GET /v1/capabilities` (categories + aggregates) and `GET /v1/capabilities/{slug}` (providers under a category). The detail endpoint takes optional `sort` (cost|rating), `max_cost`, `min_rating`, `verified_only`, and `limit` filters, and each provider carries `call_method` + `input_example` (a copy-and-tweak template for the run input). Works with any key, even before enablement. 2. Provision an end user and a budget with your platform key: `POST /v1/platforms/{platformId}/end-users`, then create the budget. A budget is required before a run can be charged. 3. Your end user's agent searches with its own `sk-eu_*` key: `POST /v1/capabilities/search` with a `query`. Returns only providers your policy allows — no spend. 4. Run one: `POST /v1/capabilities/run` with the candidate's `capability` uid (`cap_*`), an optional `input` body, and an optional `max_pay` ceiling. The response carries the authoritative `cost_usd`, `charged_end_user`, and the capability's `result`. ## Agent tools (MCP) When Capabilities is enabled, four tools auto-register on the platform's per-user MCP URL (`mcp.assistiv.ai/mcp`); the agent forwards its `sk-eu_*` key. The agent plans over the menu, resolves to a provider, then executes. The whole surface is product-named — tool names, descriptions, fields, and errors never expose the upstream marketplace: - `list_capabilities` — the ~45-category menu (no spend). Plan over this first. Wraps `GET /v1/capabilities`. - `list_providers(capability, sort?, max_cost?, min_rating?, verified_only?, limit?)` — providers under one category, filtered/sorted, each carrying `call_method` + `input_example` (the copy-and-tweak template). Default `limit` 12. No spend. Wraps `GET /v1/capabilities/{slug}`. - `capability_search(query, limit?)` — freeform marketplace discovery when the category isn't obvious. No spend. Wraps `POST /v1/capabilities/search`. - `capability_run(capability, input?, max_pay?)` — call one provider by uid; spends the end-user budget. `max_pay` caps the spend. Wraps `POST /v1/capabilities/run`. The capability call itself is a plain REST request authenticated with the end user's `sk-eu_*` key (a typed SDK helper is on the way). ## curl example ```bash # 1. Discover providers the policy allows (no spend). curl -X POST https://api.assistiv.ai/v1/capabilities/search \ -H "Authorization: Bearer $ASSISTIV_END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "generate an image", "limit": 8 }' # 2. Run one — pass the candidate's `capability` uid (cap_*), an optional input # body, and an optional max_pay ceiling. The end user's budget is debited. curl -X POST https://api.assistiv.ai/v1/capabilities/run \ -H "Authorization: Bearer $ASSISTIV_END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{ "capability": "cap_abc123", "input": { "prompt": "a cat wearing sunglasses" }, "max_pay": 0.02 }' ``` ## Costs & billing - `run` returns the authoritative settled `cost_usd`, a `charged_end_user` flag, a `final_state` (`released` | `billed` | `failed`), and a `run_id` for your audit trail. - The per-call ceiling is your policy's `max_cost_per_call_usd`, optionally lowered (never raised) by `max_pay`. - A settled-but-failed call may still be charged (a platform-policy choice, on by default) — branch on `final_state`, not just `ok`. - End users read their remaining balance with `GET /v1/me/budget`. ## Errors to handle - `403` — Capabilities not enabled for the platform, or a platform key was used on `search`/`run` (those require an `sk-eu_*` key with the `inference` scope). - `402` — denied by policy (above ceiling / denylisted / not allowlisted) or by balance (no budget, budget exhausted, wallet empty). - `404` — unknown capability slug on `GET /v1/capabilities/{slug}`. --- # Assistiv — Chat Completions API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does OpenAI-compatible `POST /v1/chat/completions`. Supports streaming, tool calling, structured output, and routing across providers (OpenAI, Anthropic, Google, xAI) by model name. Authenticate with the end-user's `sk-eu_*` key — the platform key is rejected here. ## How to integrate 1. Mint or load the end-user key (see end-users.md). 2. Pass `stream: true` for server-sent events. 3. Branch on 402 to handle wallet / budget cases. ## curl example ```bash # OpenAI-compatible chat completion. Use the end-user key. curl -X POST https://api.assistiv.ai/v1/chat/completions \ -H "Authorization: Bearer $END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-6", "messages": [{"role":"user","content":"Plan a trip to Tokyo"}], "stream": true }' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — End-user wallet (display ledger) API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Opt-in product-billing surface that runs in parallel to the USD ledger on `end_user_budgets`. Each end-user row gets TWO ledgers: - **USD ledger** (`max_usd`, `used_usd`): mandatory cost control. Debited by actual provider cost. Hidden from end users. - **Display ledger** (`max_display`, `used_display`): opt-in. Debited per platform-configured rules + admin adjustments. End users see the translated balance via `GET /v1/me/budget`. Both ledgers live on the same row; either exhausting fires a 402 on inference. `NULL max_display` = display ledger disabled for that user. ## Configure rules Rules live on `platforms.settings.end_user_wallet`: ```json { "enabled": true, "unit": "credits", "rules": [ { "trigger": "inference_call", "amount": 1 }, { "trigger": "tool_call", "amount": 5 }, { "trigger": "usd_spent", "amount_per_usd": 20 } ] } ``` Rules are additive (every matching one contributes per inference event). Max 8 rules, no duplicate triggers. Set via the dashboard settings page or `PATCH /v1/platforms/{pid}` with `{ settings: { end_user_wallet: {...} } }` — the server shallow-merges `settings`, so adjacent keys (`branding`, `rate_limits`, ...) are preserved. ## Admin endpoints All require platform key (`sk-plat_*`) or Supabase session. End-user keys → 403. - `GET /v1/platforms/{pid}/end-users/{euid}/wallet` — read both ledgers + active rules - `POST /v1/platforms/{pid}/end-users/{euid}/wallet` — set `max_display` (init or overwrite) - `POST /v1/platforms/{pid}/end-users/{euid}/wallet/topup` — additive grow of `max_display` - `POST /v1/platforms/{pid}/end-users/{euid}/wallet/adjust` — manual ± to balance, clamps to `[0, max_display]`, reports clamping in response - `DELETE /v1/platforms/{pid}/end-users/{euid}/wallet` — soft-disable, NULLs `max_display`, USD ledger untouched All mutating endpoints accept an `Idempotency-Key` header (Stripe-style: same key + same body → replay; same key + different body → 409). ## End-user view `GET /v1/me/budget` returns: ```json { "unit": "credits", "max": 100, "used": 20, "remaining": 80, "period": "monthly", "period_start": "2026-04-01T00:00:00Z" } ``` No `max_usd` / `used_usd` fields. Dual-gated: 404 if either platform `enabled=false` or per-user `max_display IS NULL`. End users cannot distinguish the two reasons. ## Audit ledger Every change to `max_display` / `used_display` writes one row to `end_user_display_transactions`. Types: `opening`, `topup`, `debit`, `adjustment`, `backfill`. Inference debits store the per-rule breakdown in `metadata.rules_breakdown` and the live rules array in `rules_snapshot` so audit history survives later rule edits. ## Common patterns - **Flat per-message billing**: rules = `[{trigger: "inference_call", amount: 1}]` with admin setting `max_display: 100` per month. - **Match real cost** (legacy USD shape): rules = `[{trigger: "usd_spent", amount_per_usd: 1}]` with `unit: "USD"`. - **Marked-up display** ($1 real = 5 credits to user): rules = `[{trigger: "usd_spent", amount_per_usd: 5}]`. - **Bonus / refund**: `POST /wallet/adjust { delta: +50, reason: "promo bonus" }`. USD ledger unaffected. ## Errors to handle - `402 display_exhausted` on `/v1/chat/completions` or `/v1/responses` — end user's display balance is empty. Message is in the platform's chosen unit ("You have 0 credits remaining."). Top up via `POST /wallet/topup` or `POST /wallet/adjust`. - `404 not_found` on `GET /v1/me/budget` — wallet disabled platform-wide or not initialized for this end user. - `409 display_ledger_not_initialized` on `POST /wallet/topup` — call `POST /wallet` first. - `409 fingerprint_mismatch` on retry with a reused `Idempotency-Key` but different body. - `422 reason_required` on `POST /wallet/adjust` with empty/whitespace reason. --- # Assistiv — End Users API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does End-users represent your platform's users. Each one gets an auto-generated `sk-eu_*` key, an optional budget, and (if configured) MCP tool connections. `external_id` is your stable identifier; create is idempotent on it. ## How to integrate 1. Create with `POST /v1/platforms/{platformId}/end-users`. The response contains `api_key.raw_key` — store it. 2. Repeat calls with the same `external_id` return `200 OK` plus a fresh key (retry safety, NOT a key-retrieval mechanism). 3. Delete with `DELETE /v1/.../end-users/{endUserId}` — cascades to keys, budgets, and connections. ## curl example ```bash # Create an end-user (idempotent on external_id). # api_key.raw_key is in the response — store immediately. curl -X POST https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/end-users \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -d '{ "external_id": "user-42", "display_name": "Jane Smith", "metadata": { "plan": "pro" } }' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — LLM Provider Configs API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Connect your own OpenAI / Anthropic / Google / xAI keys so the gateway can route inference to the upstream you chose. Keys are encrypted AES-256-GCM at rest. ## Where to do this Dashboard → LLM Configs (https://www.assistiv.ai/dashboard/llm-configs) 1. Open the LLM Configs page in your dashboard. 2. Click "Add provider" and pick OpenAI / Anthropic / Google / xAI. 3. Paste your provider API key. Submit. Encrypted at rest immediately. 4. Toggle "Enabled" — inference can now route through this provider. To rotate a key, click the existing provider row, paste a new key, submit. Old credentials are decrypted, replaced, re-encrypted in one transaction. ## Why no REST endpoint Provider keys are write-once secrets entered by a human. Exposing them over the API would mean platforms shipping those secrets through their own backend — an unnecessary handling surface. The dashboard form is the single entry point. ## Errors to handle None at integration time — the dashboard form surfaces validation errors inline. --- # Assistiv — Logs API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Per-platform structured logs of every inference and tool call. Filter by end-user, model, time range. Includes token counts, cost, latency, status code, error code. ## How to integrate 1. Fetch with `GET /v1/platforms/{platformId}/logs?start=…&end=…`. 2. Page with `cursor`, not offset — large platforms get bursty. 3. Cross-reference `request_id` to debug a specific call. ## curl example ```bash # Read structured logs filtered by end-user and time range. curl "https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/logs?end_user_id=$END_USER_ID&since=2026-05-01T00:00:00Z" \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — MCP / Tools API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does OAuth-backed third-party tool execution. Today: GitHub, Slack, Zoho Mail, Zendesk. Two surfaces: - **Activating apps for your platform** (one-time setup) — dashboard only. - **End-user runtime calls** (list/connect/execute) — API and agent MCP calls. ## Where to activate an MCP app Dashboard → MCP (https://www.assistiv.ai/dashboard/mcp) 1. Open Dashboard → MCP. Every supported app is listed with active/inactive state. 2. Click an inactive app (e.g. GitHub). Paste OAuth Client ID, OAuth Client Secret (encrypted AES-256-GCM), your platform's landing URL (end users return to `{base}/mcp/oauth-callback`), and any non-default scopes. 3. At your provider's OAuth settings (GitHub OAuth Apps, Slack app config, etc.), set the Authorization callback URL to `https://mcp.assistiv.ai/oauth/callback`. 4. Save. End users can now connect this app from your product. 5. To rotate credentials, edit the same row. To turn off the app, toggle inactive — existing end-user connections are revoked. OAuth Client Secrets are write-once secrets, so there is no curl or SDK path for these mutations. ## How agents call tools at runtime After activation, end users connect their accounts via OAuth, then your agent calls the MCP protocol at `https://mcp.assistiv.ai/mcp` using the end-user's `sk-eu_*` key. The gateway runs OAuth + tool execution server-side. ## curl example ```bash # Agent-side: list available tools for this end-user (over MCP, not REST). curl -N -X POST https://mcp.assistiv.ai/mcp \ -H "Authorization: Bearer $END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid end-user key - MCP protocol errors come back as JSON-RPC `error` payloads, not HTTP status codes - An end-user who hasn't completed OAuth for an app gets a `not_connected` error from the relevant tool --- # Assistiv — Models API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Lists the model IDs your platform can call right now. Filtered by which LLM provider keys you've configured. Use the returned IDs as the `model` field for chat-completions. ## How to integrate 1. Call `GET /v1/models` with the platform key OR end-user key. 2. Display only models your UI supports — don't paginate to the user. ## curl example ```bash # List models your platform can call right now. curl https://api.assistiv.ai/v1/models \ -H "Authorization: Bearer $END_USER_KEY" ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Overview API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Assistiv is a multi-tenant API gateway. Your platform gets one platform key (`sk-plat_*`), connects its own LLM provider keys, and each end-user gets their own `sk-eu_*` key. The gateway handles auth, billing, rate-limits, MCP tool execution, and OpenAI-compatible inference behind a single base URL. ## How to integrate 1. Pick the right key type: `sk-plat_*` for management calls, `sk-eu_*` for end-user inference. 2. Read [authentication.md] before any other snippet — every call needs `Authorization: Bearer …`. 3. Follow the integration steps in order: configure LLM → create end-user → first call → budgets → tools → webhooks → logs. ## curl example ```bash # Sanity-check your platform key works (returns 200 if valid). curl https://api.assistiv.ai/v1/me \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Platform settings API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does A platform is one tenant on the gateway — its own API keys, end-users, wallet, LLM configs, MCP apps. Settings (display name, default budget, markup, branding, feature flags like `skills_enabled`) are edited in the dashboard. ## Where to do this Dashboard → Settings (https://www.assistiv.ai/dashboard/settings) 1. Open Settings in your dashboard. 2. Adjust display name, default budget, markup, branding, feature toggles. 3. Submit — changes apply immediately to all end-users on this platform. Team management lives under Dashboard → Team. Each teammate signs in with their own email and inherits your platform's admin scope. Platform provisioning is NOT self-serve. Email platforms@assistiv.ai to request a new platform; Assistiv issues a `sk-plat_*` key and grants dashboard access. ## What your backend sees Read-only platform info (id, slug, created_at, settings) is included in: - Every outbound webhook payload (`data.platform_id`) - Every inference log entry Your backend rarely needs to query platform settings directly. ## Errors to handle None — platform settings are managed in the dashboard; your runtime code doesn't interact with this surface. --- # Assistiv — Quickstart API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Five steps to first inference. Install the SDK, set env vars, create an end-user, call chat-completions with that user's key, top up the wallet if you hit a 402. ## How to integrate 1. `npm install @assistiv/sdk` 2. Set `ASSISTIV_PLATFORM_KEY`, `ASSISTIV_PLATFORM_ID`. 3. `assistiv.endUsers.create({ external_id })` → store `result.api_key.raw_key`. 4. Call `assistiv.chat.completions.create({ model, messages })` using the end-user key. ## curl example ```bash # 1. Provision an end-user (idempotent on external_id). curl -X POST https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/end-users \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -d '{"external_id":"user-42"}' # 2. Use the returned api_key.raw_key (sk-eu_*) to run inference. curl -X POST https://api.assistiv.ai/v1/chat/completions \ -H "Authorization: Bearer $END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Say hi"}]}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Responses API API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does OpenAI-compatible `POST /v1/responses` — the newer, stateful inference shape. Supports the same provider routing as chat-completions and adds server-side conversation state. ## How to integrate 1. Use this when you want Assistiv to track conversation history server-side. 2. Otherwise prefer chat-completions for cross-provider portability. ## curl example ```bash # Stateful Responses API (server-side conversation state). curl -X POST https://api.assistiv.ai/v1/responses \ -H "Authorization: Bearer $END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","input":"Plan a trip"}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Self-Service (rate limits) API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Per-end-user rate-limit overrides. Set custom RPM / TPM / RPD for individual users without touching the platform default. Useful for high-value customers on a free product tier. ## How to integrate 1. Read defaults with `GET /v1/platforms/{platformId}/rate-limits`. 2. Override per user with `PUT /v1/platforms/{platformId}/end-users/{endUserId}/rate-limits`. 3. Clear an override with `DELETE` on the same path. ## curl example ```bash # Override rate limits for a single end-user. curl -X PUT https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID/end-users/$END_USER_ID/rate-limits \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -d '{"requests_per_minute":600,"tokens_per_minute":250000}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Skills (uploads & catalog) API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Skills are agent-fetchable code packages. Upload a private skill from the dashboard; your end-users' agents can then discover and fetch it via the five skill MCP tools at mcp.assistiv.ai/mcp/skills. ## Where to do this Dashboard → Skills (https://www.assistiv.ai/dashboard/skills) 1. Enable skills for your platform first (Dashboard → MCP → toggle `skills_enabled`). 2. Open Dashboard → Skills. 3. Click "Upload skill", drop in your folder (zipped), fill in name + short description, submit. Encrypted in GCS and content-sha deduped. 4. Skill is immediately available via `find_skill` and `fetch_skill` MCP tools. 5. Reviews and rankings come from agent usage; see the 4-dimension scorecard on each skill detail page. Skills uploaded by your platform are PRIVATE to your platform. ## Runtime usage Agents do not call this REST surface. They use the MCP tools at `https://mcp.assistiv.ai/mcp/skills`: - `find_skill` — search the catalog (public + your private skills) - `fetch_skill` — download the full folder - `create_skill` / `delete_skill` / `submit_skill_review` — agent-driven (use with caution) See skills-mcp.md for agent integration. ## Errors to handle None at upload time (dashboard form). Runtime errors from agent calls are handled by your MCP client. --- # Assistiv — Skills via MCP API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Five MCP tools auto-register when `platform.skills_enabled = true`: `find_skill`, `fetch_skill`, `create_skill`, `delete_skill`, `submit_skill_review`. Hit `https://mcp.assistiv.ai/mcp/skills` for a clean skills-only tool list, or `/mcp` to merge with your connected OAuth apps (GitHub, Slack, Zoho, Zendesk). ## How to integrate 1. Point your agent's MCP client at `https://mcp.assistiv.ai/mcp/skills`. 2. Authenticate with the end-user's `sk-eu_*` key in the `Authorization` header. 3. Use `find_skill` first, then `fetch_skill` to retrieve the full folder, then run locally. ## curl example ```bash # List the five skill tools available to an agent. curl -N -X POST https://mcp.assistiv.ai/mcp/skills \ -H "Authorization: Bearer $END_USER_KEY" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Skills (overview) API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Skills are agent-fetchable code packages. Public skills come from admin-vetted GitHub repos; private skills are uploaded by your platform and encrypted in GCS. Agents discover them via the `find_skill` MCP tool, then `fetch_skill` to download the full folder and run it locally. ## How to integrate 1. Toggle skills on for your platform: `PATCH /v1/platforms/{platformId}` with `{ skills_enabled: true }`. 2. Point your agent at `https://mcp.assistiv.ai/mcp/skills` for the five skill tools only, or `/mcp` to combine with connected apps. 3. Submit your own skill via `POST /v1/skills` (private to your platform until reviewed). ## curl example ```bash # Toggle skills on for your platform. curl -X PATCH https://api.assistiv.ai/v1/platforms/$ASSISTIV_PLATFORM_ID \ -H "Authorization: Bearer $ASSISTIV_PLATFORM_KEY" \ -H "Content-Type: application/json" \ -d '{"skills_enabled":true}' ``` ## Errors to handle - `AssistivAuthError` — missing or invalid platform/end-user key - `AssistivPaymentRequiredError` (HTTP 402) — wallet exhausted or budget suspended - `AssistivRateLimitError` (HTTP 429) — exceeded the configured rate limit - `AssistivError` — generic 4xx/5xx with a structured `error.code` body --- # Assistiv — Wallet & top-ups API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Every platform has one wallet with a USD balance. Each LLM call atomically debits the wallet by actual token cost. Top-ups are Stripe-backed and happen in the dashboard. ## Where to do this Dashboard → Settings → Billing (https://www.assistiv.ai/dashboard/settings) 1. Open Settings → Billing in the dashboard to see the current balance. 2. Click "Top up", pick the USD amount, complete Stripe checkout in the new tab. 3. Balance updates within seconds; a ledger row is written. 4. Toggle "Auto top-up" to refill automatically when balance drops below a threshold. Auto top-up fires a `wallet.low_balance` webhook (if registered) BEFORE the Stripe charge, so your systems can react. ## Reading the balance programmatically Don't poll a REST endpoint. Subscribe to the `wallet.low_balance` and `wallet.topped_up` outbound webhooks (see webhooks.md). The current balance is in every payload. ## Errors to handle - `402 wallet_insufficient` on `/v1/chat/completions` or `/v1/responses` — wallet empty. Pause inference for this platform; surface empty-state to the platform admin; require a dashboard top-up before resuming. --- # Assistiv — Outbound Webhooks API: v0.1.0 — base URL https://api.assistiv.ai SDK: @assistiv/sdk@0.0.0 — `npm install @assistiv/sdk` ## What this does Receive real-time events (`budget.topped_up`, `budget.low_balance`, `budget.suspended`, `budget.unsuspended`, `budget.debited`, `wallet.low_balance`, `wallet.topped_up`). Delivery is Svix-backed with automatic retry and signed payloads. ## Where to register an endpoint Dashboard → Outbound Webhooks (https://www.assistiv.ai/dashboard/outbound-webhooks) 1. Open Outbound Webhooks in your dashboard. 2. Click "Add endpoint", paste the HTTPS URL your server is listening on, and check the event types you want. 3. Reveal the signing secret from the table and store it in your server's env vars (`ASSISTIV_WEBHOOK_SECRET`). It is required to verify incoming payloads. 4. Failed deliveries are retried automatically. Click into an endpoint to see the delivery log and replay events from the Svix portal. ## How to handle incoming events Your server receives signed POST requests at the URL you registered. Verify the signature with the SDK's `verifyWebhook` helper, then branch on `event_type`. ## Errors to handle - Signature mismatch — respond `400`. The Svix dashboard treats this as a delivery failure and retries. - Slow handler — respond `200` quickly; do heavy work async. Svix retries on >10s. - `wallet_insufficient` 402s from inference are NOT delivered via webhooks (they're synchronous API errors). Webhooks only fire on balance-change events.