openrouter-compliance-review
Review OpenRouter integration for regulatory compliance (SOC2, GDPR,
juicebox-sdk-patterns
Apply production Juicebox SDK patterns.
Full skill instructions
Production-ready patterns for the Juicebox AI-powered people search API. Juicebox provides REST endpoints for searching professional profiles and enriching candidate data. The API authenticates via JUICEBOX_API_KEY and returns structured profile objects with LinkedIn URLs as natural dedup keys. A singleton client centralizes rate-limit handling across search and enrich endpoints.
const JUICEBOX_BASE = 'https://api.juicebox.work/v1';
let _client: JuiceboxClient | null = null;
export function getClient(): JuiceboxClient {
if (!_client) {
const apiKey = process.env.JUICEBOX_API_KEY;
if (!apiKey) throw new Error('JUICEBOX_API_KEY must be set — get it from juicebox.work/settings');
_client = new JuiceboxClient(apiKey);
}
return _client;
}
class JuiceboxClient {
private headers: Record<string, string>;
constructor(apiKey: string) { this.headers = { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }; }
async search(query: string, limit = 20): Promise<SearchResponse> {
const res = await fetch(`${JUICEBOX_BASE}/search`, {
method: 'POST', headers: this.headers, body: JSON.stringify({ query, limit }) });
if (!res.ok) throw new JuiceboxError(res.status, await res.text()); return res.json();
}
async enrich(linkedinUrl: string): Promise<Profile> {
const res = await fetch(`${JUICEBOX_BASE}/enrich`, {
method: 'POST', headers: this.headers, body: JSON.stringify({ linkedin_url: linkedinUrl }) });
if (!res.ok) throw new JuiceboxError(res.status, await res.text()); return res.json();
}
}
export class JuiceboxError extends Error {
constructor(public status: number, message: string) { super(message); this.name = 'JuiceboxError'; }
}
export async function safeCall<T>(operation: string, fn: () => Promise<T>): Promise<T> {
try { return await fn(); }
catch (err: any) {
if (err instanceof JuiceboxError && err.status === 429) { await new Promise(r => setTimeout(r, 5000)); return fn(); }
if (err instanceof JuiceboxError && err.status === 401) throw new JuiceboxError(401, 'Invalid JUICEBOX_API_KEY');
throw new JuiceboxError(err.status ?? 0, `${operation} failed: ${err.message}`);
}
}
class JuiceboxSearchBuilder {
private body: Record<string, any> = {};
query(q: string) { this.body.query = q; return this; }
limit(n: number) { this.body.limit = Math.min(n, 100); return this; }
location(loc: string) { this.body.location = loc; return this; }
title(t: string) { this.body.title_filter = t; return this; }
company(c: string) { this.body.company_filter = c; return this; }
yearsExp(min: number, max: number) { this.body.years_experience = { min, max }; return this; }
build() { return this.body; }
}
// Usage: new JuiceboxSearchBuilder().query('ML engineer').location('San Francisco').yearsExp(3, 8).build();
interface Profile {
id: string; name: string; title: string; company: string;
linkedin_url: string; location: string; skills: string[]; experience_years: number;
}
interface SearchResponse {
profiles: Profile[]; total: number; has_more: boolean; cursor?: string;
}
interface EnrichResult {
profile: Profile; education: Array<{ school: string; degree: string; year: number }>;
experience: Array<{ company: string; title: string; start: string; end: string | null }>;
}
export function mockProfile(overrides: Partial<Profile> = {}): Profile {
return { id: 'prof-001', name: 'Jane Smith', title: 'Senior ML Engineer',
company: 'Acme Corp', linkedin_url: 'https://linkedin.com/in/janesmith',
location: 'San Francisco, CA', skills: ['Python', 'PyTorch', 'MLOps'],
experience_years: 6, ...overrides };
}
export function mockSearchResponse(count = 3): SearchResponse {
return { profiles: Array.from({ length: count }, (_, i) => mockProfile({ id: `prof-${i}` })),
total: count, has_more: false };
}
| Pattern | When to Use | Example |
|---|---|---|
safeCall wrapper | All Juicebox API calls | Structured error with operation context |
| Retry on 429 | Batch search pipelines | 5s backoff before retry |
| LinkedIn dedup | Multi-query search | Set<string> on linkedin_url prevents duplicates |
| Cursor pagination | Search results > 100 | Pass cursor from previous response |
Apply patterns in juicebox-core-workflow-a.
Review OpenRouter integration for regulatory compliance (SOC2, GDPR,
Data synchronization, ETL patterns, and data management for MaintainX.
Execute Groq primary workflow: chat completions with tool use and JSON
Validate CSRF protection implementations for security gaps. Use when
Configure this skill should be used when the user asks about "API contract",
Execute Ideogram incident response with triage, mitigation, and postmortem.
Execute create, select, and transform features to improve machine learning
Reusable patterns for the Gamma REST API (no SDK exists).
Apply production-ready Deepgram SDK patterns for TypeScript and Python.
Migrate to OpenRouter from direct provider APIs or upgrade between SDK/model
Diagnose and fix common OpenRouter API errors. Use when encountering
Optimize Linear API usage, reduce unnecessary calls, and maximize
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience