name: perplexity-multi-env-setup description: 'Configure Perplexity Sonar API across development, staging, and production environments.
Use when setting up multi-environment search integrations, managing API keys
per environment, or controlling cost through model routing by env.
Trigger with phrases like "perplexity environments", "perplexity staging",
"perplexity dev prod", "perplexity environment config".
' allowed-tools: Read, Write, Edit, Bash(aws:), Bash(gcloud:), Bash(vault:*) version: 1.0.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
- saas
- perplexity
- api
- cost-optimization compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
Perplexity Multi-Environment Setup
Overview
Configure Perplexity Sonar API across dev/staging/prod. Key decisions per environment: which models are allowed (sonar vs sonar-pro), rate limits, and cost caps. All environments use the same base URL (https://api.perplexity.ai) but different API keys with different budget limits.
Environment Strategy
| Environment | Model | Rate Limit | Key Source | Monthly Budget |
|---|---|---|---|---|
| Development | sonar only | 5 RPM self-imposed | .env.local | $10 |
| Staging | sonar only | 20 RPM | CI secrets | $50 |
| Production | sonar + sonar-pro | 50 RPM | Secret manager | $500+ |
Prerequisites
- Separate Perplexity API keys per environment
openaipackage installed- Secret management (env files for dev, vault/KMS for prod)
Instructions
Step 1: Configuration Structure
config/
perplexity/
base.ts # OpenAI client + base URL
development.ts # Dev: sonar only, low limits
staging.ts # Staging: sonar only, moderate limits
production.ts # Prod: full model access
index.ts # Environment resolver
Step 2: Base Configuration
// config/perplexity/base.ts
import OpenAI from "openai";
export const PERPLEXITY_BASE_URL = "https://api.perplexity.ai";
export function createPerplexityClient(apiKey: string): OpenAI {
if (!apiKey) throw new Error("Perplexity API key is required");
if (!apiKey.startsWith("pplx-")) throw new Error("Invalid Perplexity API key format");
return new OpenAI({ apiKey, baseURL: PERPLEXITY_BASE_URL });
}
Step 3: Environment Configs
// config/perplexity/development.ts
export const devConfig = {
apiKey: process.env.PERPLEXITY_API_KEY!,
defaultModel: "sonar" as const,
deepModel: "sonar" as const, // No sonar-pro in dev (cost)
maxTokens: 512,
maxConcurrentRequests: 1,
cacheTTLMs: 24 * 3600_000, // Long cache in dev
};
// config/perplexity/staging.ts
export const stagingConfig = {
apiKey: process.env.PERPLEXITY_API_KEY_STAGING!,
defaultModel: "sonar" as const,
deepModel: "sonar" as const, // Keep sonar in staging
maxTokens: 1024,
maxConcurrentRequests: 2,
cacheTTLMs: 4 * 3600_000,
};
// config/perplexity/production.ts
export const productionConfig = {
apiKey: process.env.PERPLEXITY_API_KEY_PROD!,
defaultModel: "sonar" as const, // Fast queries use sonar
deepModel: "sonar-pro" as const, // Research queries use sonar-pro
maxTokens: 4096,
maxConcurrentRequests: 10,
cacheTTLMs: 1 * 3600_000, // Shorter cache in prod (freshness)
};
Step 4: Environment Resolver
// config/perplexity/index.ts
import { createPerplexityClient } from "./base";
import { devConfig } from "./development";
import { stagingConfig } from "./staging";
import { productionConfig } from "./production";
type SearchDepth = "quick" | "deep";
const configs = {
development: devConfig,
staging: stagingConfig,
production: productionConfig,
};
export function getConfig() {
const env = process.env.NODE_ENV || "development";
const config = configs[env as keyof typeof configs];
if (!config) throw new Error(`Unknown environment: ${env}`);
if (!config.apiKey) throw new Error(`PERPLEXITY_API_KEY not set for ${env}`);
return config;
}
export function getClient() {
return createPerplexityClient(getConfig().apiKey);
}
export function getModelForDepth(depth: SearchDepth): string {
const cfg = getConfig();
return depth === "deep" ? cfg.deepModel : cfg.defaultModel;
}
Step 5: Usage with Environment-Aware Search
// lib/search.ts
import { getClient, getModelForDepth, getConfig } from "../config/perplexity";
export async function search(query: string, depth: "quick" | "deep" = "quick") {
const client = getClient();
const model = getModelForDepth(depth);
const config = getConfig();
const result = await client.chat.completions.create({
model,
messages: [
{ role: "system", content: "Provide accurate, well-sourced answers." },
{ role: "user", content: query },
],
max_tokens: depth === "deep" ? config.maxTokens : Math.min(512, config.maxTokens),
});
return {
answer: result.choices[0].message.content,
citations: (result as any).citations || [],
model,
environment: process.env.NODE_ENV,
usage: result.usage,
};
}
Step 6: Secret Manager Integration (Production)
set -euo pipefail
# Google Cloud Secret Manager
gcloud secrets create perplexity-api-key-prod \
--data-file=<(echo -n "$PERPLEXITY_API_KEY_PROD")
# AWS Secrets Manager
aws secretsmanager create-secret \
--name perplexity/api-key-prod \
--secret-string "$PERPLEXITY_API_KEY_PROD"
# HashiCorp Vault
vault kv put secret/perplexity api_key="$PERPLEXITY_API_KEY_PROD"
Error Handling
| Issue | Cause | Solution |
|---|---|---|
401 in staging | Wrong API key for environment | Verify PERPLEXITY_API_KEY_STAGING |
429 in dev | Exceeding self-imposed limit | Add request queuing |
| sonar-pro in dev | Config not restricting models | Set deepModel: "sonar" in dev config |
| High dev costs | Using production config locally | Ensure NODE_ENV=development is set |
Output
- Environment-specific Perplexity configurations
- Model routing by environment and query depth
- Secret manager integration for production keys
- Cost controls per environment
Resources
Next Steps
For deployment configuration, see perplexity-deploy-integration.