Juicebox upgrade migration
'Plan Juicebox SDK upgrades.From its SKILL.md
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill juicebox-upgrade-migrationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Juicebox Upgrade & Migration
Overview
Juicebox is an AI-powered people search and analysis platform used for recruiting and market research. The API provides endpoints for dataset management, people searches, and AI-generated analyses. Tracking API versions is essential because Juicebox evolves its search query syntax, dataset schema, and analysis output format — upgrading without testing can break saved search filters, corrupt dataset imports, and change the structure of AI-generated candidate profiles that downstream systems consume.
Version Detection
const JUICEBOX_BASE = "https://api.juicebox.work/v1";
async function detectJuiceboxVersion(apiKey: string): Promise<void> {
const res = await fetch(`${JUICEBOX_BASE}/datasets`, {
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
});
const version = res.headers.get("x-juicebox-api-version") ?? "v1";
console.log(`Juicebox API version: ${version}`);
// Check for deprecated search parameters
const searchRes = await fetch(`${JUICEBOX_BASE}/search`, {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
body: JSON.stringify({ query: "test", limit: 1 }),
});
const deprecation = searchRes.headers.get("x-deprecated-params");
if (deprecation) console.warn(`Deprecated search params: ${deprecation}`);
}
Migration Checklist
- Review Juicebox changelog for API breaking changes
- Audit codebase for hardcoded dataset field names
- Verify search query syntax — filter operators may have changed
- Check analysis output format for new or renamed fields
- Update dataset import schema if column mapping changed
- Test people search result structure (profile fields, enrichment data)
- Validate pagination — cursor-based vs. offset may have changed
- Update SDK version in
package.jsonand verify type compatibility - Check webhook payloads for analysis completion events
- Run integration tests with sample dataset to verify search quality
Schema Migration
// Juicebox search results evolved: flat profile → enriched profile with sources
interface OldSearchResult {
id: string;
name: string;
title: string;
company: string;
email?: string;
linkedin_url?: string;
}
interface NewSearchResult {
id: string;
profile: {
full_name: string;
current_title: string;
current_company: { name: string; domain: string };
emails: Array<{ address: string; type: "work" | "personal"; verified: boolean }>;
social: { linkedin?: string; twitter?: string };
};
match_score: number;
enrichment_sources: string[];
}
function migrateSearchResult(old: OldSearchResult): NewSearchResult {
return {
id: old.id,
profile: {
full_name: old.name,
current_title: old.title,
current_company: { name: old.company, domain: "" },
emails: old.email ? [{ address: old.email, type: "work", verified: false }] : [],
social: { linkedin: old.linkedin_url },
},
match_score: 0,
enrichment_sources: [],
};
}
Rollback Strategy
class JuiceboxClient {
private currentVersion: "v1" | "v2";
constructor(private apiKey: string, version: "v1" | "v2" = "v2") {
this.currentVersion = version;
}
async search(query: string, filters?: Record<string, any>): Promise<any> {
try {
const res = await fetch(`https://api.juicebox.work/${this.currentVersion}/search`, {
method: "POST",
headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
body: JSON.stringify({ query, filters }),
});
if (!res.ok) throw new Error(`Juicebox search ${res.status}`);
return await res.json();
} catch (err) {
if (this.currentVersion === "v2") {
console.warn("Falling back to Juicebox API v1");
this.currentVersion = "v1";
return this.search(query, filters);
}
throw err;
}
}
}
Error Handling
| Migration Issue | Symptom | Fix |
|---|---|---|
| Search filter syntax changed | 400 Bad Request with invalid filter operator | Update filter syntax to new query DSL format |
| Dataset schema mismatch | Import succeeds but columns mapped incorrectly | Re-map dataset columns using /datasets/schema endpoint |
| Profile field restructured | Code crashes accessing result.name (now result.profile.full_name) | Update all property access paths to new nested structure |
| Analysis format changed | AI analysis output missing expected sections | Update parser for new structured analysis response |
| Rate limit reduced | 429 Too Many Requests on previously working batch sizes | Reduce batch size and implement request queuing |
Resources
- Juicebox Changelog
- Juicebox API Documentation
Next Steps
For CI pipeline integration, see juicebox-ci-integration.
What ships with it: 2 files
5.4 KB alongside SKILL.md
references/
- implementation-guide.md3.7 KB
- implementation.md1.6 KB