Installation
Copy
npm install @bijou/sdk
# or
yarn add @bijou/sdk
# or
pnpm add @bijou/sdk
Quick Start
Copy
import { BijouClient } from '@bijou/sdk';
import fs from 'fs';
// Initialize the client
const client = new BijouClient({ apiKey: 'bijou_your-key' });
// Detect an image
const buffer = fs.readFileSync('image.jpg');
const result = await client.detect(buffer);
console.log(`Prediction: ${result.prediction}`);
console.log(`Confidence: ${(result.confidence * 100).toFixed(1)}%`);
console.log(`Verdict: ${result.verdict}`);
Client Options
Copy
import { BijouClient } from '@bijou/sdk';
const client = new BijouClient({
apiKey: 'bijou_your-key', // Required
baseUrl: 'https://api.trybijou.com/v1', // Optional
timeout: 30000, // Optional, ms
maxRetries: 3, // Optional
});
Detection Methods
From Buffer (Node.js)
Copy
import fs from 'fs';
const buffer = fs.readFileSync('image.jpg');
const result = await client.detect(buffer);
From Blob (Browser)
Copy
// From file input
const file = document.querySelector('input[type="file"]').files[0];
const result = await client.detect(file);
// From fetch
const response = await fetch('https://example.com/image.jpg');
const blob = await response.blob();
const result = await client.detect(blob);
From Base64 String
Copy
const base64 = 'iVBORw0KGgoAAAANSUhEUg...';
const result = await client.detect(base64);
// With data URL prefix (automatically stripped)
const dataUrl = 'data:image/jpeg;base64,iVBORw0KGgo...';
const result = await client.detect(dataUrl);
Detection Result
TheDetectionResult object contains:
Copy
interface DetectionResult {
prediction: 'ai' | 'real' | 'uncertain';
confidence: number; // 0.0 - 1.0
ensembleScore: number; // 0.0 - 1.0
verdict: 'ai_generated' | 'likely_real' | 'uncertain';
modelsSucceeded: number;
modelsTotal: number;
modelResults: Record<string, { score: number; latency_ms: number }>;
detectionLatencyMs: number;
}
Error Handling
Copy
import {
BijouClient,
BijouAPIError,
BijouInsufficientCreditsError,
BijouRateLimitError,
BijouValidationError,
BijouTimeoutError,
} from '@bijou/sdk';
const client = new BijouClient({ apiKey: 'bijou_your-key' });
try {
const result = await client.detect(imageBuffer);
} catch (error) {
if (error instanceof BijouInsufficientCreditsError) {
console.log(`Out of credits: ${error.message}`);
} else if (error instanceof BijouRateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof BijouValidationError) {
console.log(`Invalid input: ${error.message}`);
} else if (error instanceof BijouTimeoutError) {
console.log(`Timed out after ${error.timeoutMs}ms`);
} else if (error instanceof BijouAPIError) {
console.log(`API error: ${error.message} (HTTP ${error.statusCode})`);
}
}
Batch Detection
Process multiple images efficiently:Copy
import { BijouClient } from '@bijou/sdk';
import fs from 'fs';
import path from 'path';
const client = new BijouClient({ apiKey: 'bijou_your-key' });
// Load images
const imageDir = './images';
const images = fs.readdirSync(imageDir)
.filter(f => f.endsWith('.jpg'))
.map(f => fs.readFileSync(path.join(imageDir, f)));
// Submit batch job
const job = await client.detectBatch(images);
console.log(`Job ID: ${job.jobId}`);
// Wait for results
const results = await client.waitForBatch(job.jobId);
for (const result of results.results) {
console.log(`${result.prediction}: ${(result.confidence * 100).toFixed(1)}%`);
}
Factory Function
UsecreateClient for a more functional style:
Copy
import { createClient } from '@bijou/sdk';
const client = createClient({ apiKey: 'bijou_your-key' });
const result = await client.detect(imageBuffer);
Environment Variables
Copy
import { BijouClient } from '@bijou/sdk';
const client = new BijouClient({
apiKey: process.env.BIJOU_API_KEY!,
});
Browser Usage
The SDK works in browsers too:Copy
import { BijouClient } from '@bijou/sdk';
const client = new BijouClient({ apiKey: 'bijou_your-key' });
// From file input
document.querySelector('input[type="file"]')?.addEventListener('change', async (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
try {
const result = await client.detect(file);
console.log(`Prediction: ${result.prediction}`);
} catch (error) {
console.error('Detection failed:', error);
}
});
Never expose your API key in client-side code in production. Use a backend proxy to keep your key secure.
Full Example (Node.js)
Copy
#!/usr/bin/env npx ts-node
/**
* Bijou AI Detection Example
*/
import { BijouClient, BijouInsufficientCreditsError } from '@bijou/sdk';
import fs from 'fs';
import path from 'path';
async function main() {
// Initialize client
const apiKey = process.env.BIJOU_API_KEY;
if (!apiKey) {
console.log('Set BIJOU_API_KEY environment variable');
process.exit(1);
}
const client = new BijouClient({ apiKey });
// Process images
const imageDir = './test_images';
const files = fs.readdirSync(imageDir).filter(f => f.endsWith('.jpg'));
for (const file of files) {
try {
const buffer = fs.readFileSync(path.join(imageDir, file));
const result = await client.detect(buffer);
const status = result.prediction === 'ai' ? '🤖 AI' : '📷 Real';
console.log(`${file}: ${status} (${(result.confidence * 100).toFixed(1)}%)`);
// Show individual model scores
for (const [model, data] of Object.entries(result.modelResults)) {
console.log(` ${model}: ${data.score.toFixed(2)}`);
}
} catch (error) {
if (error instanceof BijouInsufficientCreditsError) {
console.log('Out of credits! Buy more at trybijou.com/profile');
break;
}
throw error;
}
}
}
main().catch(console.error);
TypeScript Types
All types are exported for use in your application:Copy
import type {
BijouClientOptions,
DetectionResult,
DetectionOptions,
ModelScore,
BatchDetectionResult,
BatchJobStatus,
CreditBalance,
} from '@bijou/sdk';