- Scheduled runs — the cron-driven agent loop that calls
generateTextagainst the configured provider. blocks.create— the AI block generator that streams a new block from a prompt.
BYOK keys are a Builder beta feature. Free workspaces can read this page, but
/settings/api-keys shows an upgrade panel and MCP byokKeys.* writes require Builder.Why BYOK
Two reasons:- Your provider, your billing. Every LLM call is metered against your Anthropic or OpenAI account. The platform doesn’t mark up tokens.
- Your model choice. You pick the model per scheduled run from the supported list, and you can swap to a cheaper model without us pushing a release.
Add a key
1
Go to API keys
/settings/api-keys → BYOK panel. Scheduled runs and MCP AI generation are labeled Beta in settings; Free workspaces see an upsell to /settings/billing.2
Paste the API key
Anthropic (
sk-ant-*) or OpenAI (sk-* or sk-proj-*). Optionally pick a label so you can tell multiple keys apart.The platform validates against the provider’s /v1/models endpoint with a 5-second timeout. Validation failures bubble up with a clear message — “Provider rejected the key” on 401/403, “Could not reach <provider>” on network errors.3
Save
The plaintext is envelope-encrypted with your workspace DEK. The list view shows the last 4 characters (after stripping known prefixes like
sk-ant-api01-, sk-proj-, etc.) plus the provider and label — never the full key.Supported providers and models
Two providers in v1. Each carries a whitelist of model IDs the platform will accept at scheduled-run-set time.- Anthropic
- OpenAI
The whitelist lives in
packages/shared/src/byokProviders.ts. To add a model, open a PR there.How keys get used
The runner decrypts your key just-in-time and passes it directly to the provider — the plaintext never travels back out of the action.Scheduled runs
Scheduled runs
convex/scheduledRuns/runner.ts looks up the BYOK row by id, calls _decryptForRunner({ actor: "system:scheduledRunner" }), and instantiates @ai-sdk/anthropic or @ai-sdk/openai with the plaintext as the API key.AI Gateway is intentionally skipped — gateway BYOK is project-scoped, so per-workspace BYOK has to use the provider SDKs directly.schedule.preview
schedule.preview
The streaming preview tool decrypts with
actor: "system:schedulePreview" so preview events are distinguishable from production runs in the audit log.blocks.create
blocks.create
The AI block generator uses a separate inference path (
@vercel/ai streamObject) but the BYOK selection is the same — pick the key, pick the model, run.auditLog row with the calling actor (system:scheduledRunner, system:schedulePreview, etc.), the BYOK key id, and the timestamp. Customers can see exactly when their key was used and by which flow.
MCP tools
Three tools surface the BYOK panel to agents. Admin-only.
See the MCP tool reference for the argument shapes.
Encryption details
- AES-256-GCM with a per-workspace data encryption key (DEK).
- DEK is wrapped with a master key encryption key (KEK) held in Convex env (
KEK_V1). - Ciphertext is stored inline on the
customerApiKeysrow (vs. data sources, which store ciphertext in a separate table). keyVersionfield tracks the KEK version for rotation.
kekVersion). Until then, KEK is set once at platform install and stays put.
What’s next
Scheduled runs
Cron-driven agent loops powered by your BYOK key.
Audit log
Every BYOK decrypt is logged with actor + key id + timestamp.