Skip to content

Create an account and an API key

An org developer authenticates the SDK with a VIITE_API_KEY — a single key that identifies your org and the admin who created it. It gives you read access to your organization’s public surfaces (the offers/pricing catalog and the headless blog), and it can drive the AI and storage features described below.

Keys are minted from Business Studio, the hosted dashboard — the docs site can’t create one, because issuing a key requires an authenticated, org-admin session.

If you don’t have an account yet, sign up at business-studio.viite.ai/signup. It’s free: the Free tier includes 1 seat, 5,000 one-off AI credits and 100 MB of storage. Signing up creates your organization, and you are its owner — so you can mint keys immediately.

Already have one? Sign in instead.

  1. In the dashboard, go to Settings → API keys (/settings/api-keys).
  2. Click New API key, give it a name (e.g. viite.ai site) and an expiry, and create it.
  3. Copy the key immediately — it’s shown only once. The dashboard stores only a hash; if you lose it, revoke and mint a new one.

Only org admins/owners can create or revoke keys. Members can view the list.

Pass the key via getToken; every request is sent as Authorization: Bearer <key>:

import { PlatformApiClient } from '@viite-ai/platform-sdk';
const client = new PlatformApiClient({
baseUrl: 'https://platform-api.viite.ai',
getToken: () => process.env.VIITE_API_KEY,
});
// Your org's active offers (the pricing page):
const offers = await client.offers.listPublic();
// Your org's published blog posts:
const posts = await client.blog.listPublished();

Both reads are scoped to the key’s org — no IDs to pass, no cross-org leakage.

A key is not read-only. It can also drive the metered features, which is what makes the SDK usable for real work:

// Storage — counts against your org's quota.
const asset = await client.assets.upload(file);
const { bytes } = await client.assets.usage();
// AI — spends credits.
const link = await client.tasks.createLink({ url: 'https://example.com/post' });
await client.tasks.process(link.id); // enrich it
await client.tasks.createBlogFromLink(link.id); // compose a draft
// Check what's left before you spend it.
const credits = await client.credits.getMyBalance();

Both are gated. When your org is out of credits or over its storage quota, the call fails with HTTP 402 and a message telling you which limit you hit:

import { ApiRequestError } from '@viite-ai/platform-sdk';
try {
await client.assets.upload(file);
} catch (error) {
if (error instanceof ApiRequestError && error.status === 402) {
// Out of credits, or over the storage ceiling — see error.message.
}
}

See Credits and limits for what a credit is, what spends one, and how the two quotas differ.

A key is a long-lived, copy-pasteable credential, so it is deliberately barred from anything that would let it escalate or destroy:

  • Minting or revoking keys — a key that mints keys is an unrevokable chain.
  • Managing connectors — those hold third-party OAuth refresh tokens.
  • Admin and entitlement routes, and any checkout.
  • Deleting cards, pruning, and account changes.

Those all need a signed-in session in the dashboard. Requests made with a key are refused there.

Keys are also rate limited to 100 requests per minute — a batch import will hit that well before it hits any quota.

  • Rotate: create a new key, deploy it to your consumer site’s env, then revoke the old one.
  • Revoke: delete the key from Settings → API keys. Revocation is immediate; any site still using it starts getting 401s.

For scripted/CI minting there’s a server-side script that performs the same flow (sign in → POST /api/api-keys):

Terminal window
PLATFORM_API_URL=https://platform-api.viite.ai \
bun run apps/api/scripts/mint-blog-key.ts --name "viite.ai site" --expires-days 365

It prints a ready-to-paste VIITE_API_KEY=… line. The signed-in account must be an admin/owner of its active org.