From focus-skills
Integrate applications with Focus API for authentication, wallet/credits, and job management. Use when implementing Clerk JWT auth, device-code flow for CLI tools, credit reservation and settlement, or job lifecycle (create/complete/fail). Trigger when building apps that connect to account.thefocus.ai or need to manage user credits and jobs.
npx claudepluginhub the-focus-ai/claude-marketplace --plugin focus-skillsThis skill uses the workspace's default tool permissions.
Connect your application to the Focus API for authentication, credit management, and job tracking.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Connect your application to the Focus API for authentication, credit management, and job tracking.
Use this skill when:
Choose based on your use case:
# Get a PAT for automation
pnpm --filter @thefocus/focus-cli dev -- login
# Opens browser for confirmation
# PAT stored locally (~90 days validity)
# Verify token
pnpm --filter @thefocus/focus-cli dev -- whoami
Use PAT as: Authorization: Bearer <token>
// Redirect to shared sign-in
const returnUrl = window.location.href;
window.location.href = `https://account.thefocus.ai/signin?redirect_to=${encodeURIComponent(returnUrl)}`;
// On return, get session token
const response = await fetch("https://account.thefocus.ai/api/sessionToken", {
method: "GET",
credentials: "include",
});
// Returns 401 with signin_url if unauthenticated
import { useAuth } from "@clerk/nextjs";
const { getToken } = useAuth();
const token = await getToken();
// Use token for API calls
await fetch("https://account.thefocus.ai/api/wallet", {
headers: { Authorization: `Bearer ${token}` },
credentials: "include",
});
// Basic wallet check
const wallet = await fetch("https://account.thefocus.ai/api/wallet", {
headers: { Authorization: `Bearer ${token}` },
credentials: "include",
});
// With app grant (receive starter credits once per app)
const wallet = await fetch("https://account.thefocus.ai/api/wallet?app=video", {
headers: { Authorization: `Bearer ${token}` },
credentials: "include",
});
Response:
{
"account": {
"id": "uuid",
"clerk_id": "string",
"plan": "free",
"credits": 123
},
"apps": [
{
"slug": "video",
"starter_credits": 20,
"granted": true,
"granted_at": "2025-10-28T..."
}
],
"app_grant": {
"slug": "video",
"starter_credits": 20,
"granted": true
}
}
const response = await fetch("https://account.thefocus.ai/api/jobs", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
credentials: "include",
body: JSON.stringify({
app: "video",
action: "render",
cost_estimate: 5,
metadata: {
description: "Render preview clip",
previewUrl: "https://video.example.com/previews/abc123.jpg",
},
}),
});
const { job_id } = await response.json();
Errors: 402 (insufficient credits), 401 (auth missing/invalid)
await fetch("https://account.thefocus.ai/api/jobs/complete", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
credentials: "include",
body: JSON.stringify({
job_id,
actual_cost: 3, // Refunds unused reserve or charges overage
metadata: {
description: "Render completed (1080p)",
previewUrl: "https://video.example.com/final.jpg",
durationMs: 1200,
},
}),
});
await fetch("https://account.thefocus.ai/api/jobs/fail", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
credentials: "include",
body: JSON.stringify({
job_id,
refund: true, // Default: true
}),
});
await fetch("https://account.thefocus.ai/api/jobs?app=video&status=started&limit=50", {
headers: { Authorization: `Bearer ${token}` },
credentials: "include",
});
For building your own CLI tools:
Start flow: POST /api/device/start
{
"device_code": "...",
"user_code": "ABCD-1234",
"verification_uri": "https://account.thefocus.ai/device",
"expires_in": 900,
"interval": 5
}
Complete (browser): POST /api/device/complete
{ ok: true }Poll for token: GET /api/device/poll?device_code=...
202 while pending{ token } (PAT) when ready// Get X/Twitter OAuth token
await fetch("https://account.thefocus.ai/api/xToken", {
headers: { Authorization: `Bearer ${token}` },
});
// Get token for any provider
await fetch("https://account.thefocus.ai/api/oauthToken/{provider}", {
headers: { Authorization: `Bearer ${token}` },
});
// Proxy to Twitter API
await fetch("https://account.thefocus.ai/api/xMe", {
headers: { Authorization: `Bearer ${twitter_token}` },
});
| Status | Meaning | Action |
|---|---|---|
| 401 | Missing/invalid auth | Redirect to signin_url |
| 402 | Insufficient credits | Show credit purchase UI |
| 429 | Rate limited | Retry after delay |
const response = await fetch("https://account.thefocus.ai/api/sessionToken", {
credentials: "include",
});
if (response.status === 401) {
const { signin_url } = await response.json();
window.location.href = signin_url;
}
Choose auth method
Register your app
Implement credit flow
Add job metadata
description: Human-readable summarypreviewUrl: Thumbnail or result linkBefore deploying Focus-integrated app:
For complete API specification, endpoint details, and advanced patterns, see: