Skip to Content
Providers & BYOK

Providers & BYOK

PickLayer routes every AI call to an upstream provider (OpenRouter, OpenAI, Anthropic, AWS, Azure, Deepgram, etc.). By default your application uses PickLayer’s managed credentials. Bring Your Own Key (BYOK) lets you substitute your own upstream API keys so that traffic is attributed to your accounts.

Managed vs BYOK

ManagedBYOK
SetupNone — works out of the boxConfigure credentials per-application
BillingPickLayer billing includes provider cost + markupYou pay upstream providers directly; PickLayer markup applies on top of zero provider cost
Rate limitsShared PickLayer upstream quotaYour own upstream quota
Data isolationTraffic flows through PickLayer’s upstream accountsTraffic flows through your accounts
Best forGetting started, prototypingProduction apps, negotiated rates, high quota needs

When to switch to BYOK

  • You have negotiated rates with a provider and want to apply them.
  • You need higher rate limits than PickLayer’s shared pool provides.
  • Your compliance requirements mandate that all upstream API traffic originate from your own accounts.
  • You want to use a provider or deployment not available on the managed tier (e.g. a private Azure OpenAI deployment).

How credential encryption works

When you enter a secret field (API key, secret access key, subscription key) in the console or via the POST /providers/upsert-credentials API:

  1. The browser retrieves PickLayer’s relay public key.
  2. The secret is encrypted in the browser with RSA-OAEP (SHA-256) before any network transmission. The plaintext never leaves your device.
  3. The ciphertext is stored in PickLayer’s database. It is write-only — it cannot be read back via GraphQL or the API.
  4. At call time, the AI service decrypts the ciphertext server-side using the corresponding private key, uses the secret to call the upstream provider, then discards it.

Non-secret fields (region, deployment name, voice, etc.) are stored as plain text metadata and are readable via the config_safe field on the provider record.

Configuring providers

Via the console

  1. Open Settings → Provider API Keys in the builder console.
  2. Click Add provider and select a preset.
  3. Fill in the required fields. Secret fields are encrypted before save.
  4. Click Save. The provider becomes active immediately.

Via the API

Use POST /providers/upsert-credentials. See the BUILDER_API_REFERENCE §4.2 for the full parameter reference including how to encrypt secret fields programmatically.

# 1. Fetch the relay public key (no auth required) PUB=$(curl -s https://api.picklayer.ai/providers/relay-public-key | jq -r '.data.publicKey') # 2. Encrypt your secret (example using node) CIPHER=$(node -e " const crypto = require('crypto'); const key = crypto.createPublicKey('$PUB'); const enc = crypto.publicEncrypt({ key, oaepHash: 'sha256', padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }, Buffer.from(process.env.OPENAI_KEY)); console.log(enc.toString('base64')); ") # 3. Upsert the provider curl -X POST https://api.picklayer.ai/providers/upsert-credentials \ -H "Authorization: Bearer $ORG_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"orgId\": \"$ORG_ID\", \"appId\": \"$APP_ID\", \"presetId\": \"openai\", \"name\": \"OpenAI production\", \"fields\": { \"apiKey\": { \"ciphertext\": \"$CIPHER\" }, \"organizationId\": { \"value\": \"org-...\" } } }"

Available providers

PresetProviderKey capabilities
openrouterOpenRouterchat, vision, embeddings
openaiOpenAIchat, embeddings, TTS, STT, vision
xaixAI (Grok)chat, responses, vision, tools, web search
anthropicAnthropic Claudechat, responses, vision, tools, reasoning
geminiGoogle Geminichat, responses, vision, tools, web search
bedrockAmazon Bedrockchat, responses, vision, tools, reasoning
aws-pollyAmazon PollyTTS
aws-transcribeAmazon TranscribeSTT
azure-openaiAzure OpenAIchat, embeddings
azure-speechAzure SpeechTTS, STT
deepgramDeepgramSTT, TTS

Use GET /providers/presets (no auth) to retrieve the current list with per-field definitions including which fields are secret vs plain text.

Listing and updating providers

# List all providers for an application (secrets hidden) query { providers(where: { application_id: { _eq: "<appId>" } }) { id name type enabled config_safe created_at } } # Disable a provider mutation { update_providers_by_pk(pk_columns: { id: "<providerId>" }, _set: { enabled: false }) { id enabled } }

Note: config_safe exposes field metadata (e.g. { "apiKey": { "hasSecret": true } }) but never the plaintext secret.

Last updated on