Authentication
Every remote request is authenticated with an API key that maps you to a tenant.
API keys
Create and revoke keys in the app under Account → API keys. A key maps every request to a tenant; all stored decks and brand profiles are scoped to that tenant. Keep keys secret. Treat them like passwords; anyone with a key can spend your token quota.
Sending your key
Send the key on every request to the REST (/v1) and MCP (/mcp) doors, using either header:
x-api-key: YOUR_API_KEY
# or
Authorization: Bearer YOUR_API_KEY
Example:
curl https://slides.product-masterclass.com/v1/decks \
-H "x-api-key: $AGENTIC_SLIDES_KEY"
Failed authentication
A missing or unknown/revoked key returns 401 Unauthorized and no work is done:
{
"error": {
"code": "unauthorized",
"message": "Missing API key."
}
}
The tenant model
Your key resolves to a tenant id. Most endpoints infer the tenant from the key, so you never pass it. A few endpoints accept an optional tenantId in the body for operators managing multiple tenants; omit it to use the tenant bound to your key.
The model provider key stays server-side
You never send an LLM provider key. The server holds the budget key (a shared key, or a dedicated per-tenant key) and runs generation on your behalf. As a fail-safe, these fields are stripped from request bodies before any handler runs:
apiKey, api_key, anthropicApiKey, baseUrl, budgetKey
So you can never accidentally (or intentionally) override the provider credentials or base URL through the API.
Local development (key-free)
For local work, run the MCP server over stdio. It does not require an API key:
pnpm install
pnpm mcp:stdio
Only the remote HTTP doors (/v1, /mcp) require a key.
API_KEYS environment variable as comma-separated key:tenantId[:budgetKey] entries. Self-service keys created in the app are stored hashed (sha256); the raw key is shown once at creation.