This document provides comprehensive documentation for the Civitai API integration in the Oshun platform.
Overview#
The Civitai integration provides access to the Civitai ecosystem for:
- Image Generation: Text-to-image with SD1.5, SDXL, Flux, and Pony models
- Video Generation: 10 video models including Vidu, Veo3, Hunyuan, and Wan
- Model Discovery: Search and browse the Civitai model library
- LoRA Training: Train custom LoRAs for image and video generation
- Model Downloads: Queue and manage model downloads
Authentication#
API Key Setup#
typescript
import { CivitaiProvider } from '@oshun/civitai-provider';
const provider = new CivitaiProvider({
apiKey: process.env.CIVITAI_API_KEY,
});
Environment Variables#
| Variable | Description | Required |
|---|---|---|
CIVITAI_API_KEY |
Civitai API key for authentication | Yes |
CIVITAI_LINK_ENDPOINT |
WebSocket endpoint for Civitai Link | No |
CIVITAI_LINK_KEY |
Civitai Link authentication key | No |
CIVITAI_MAX_CONCURRENT_DOWNLOADS |
Max concurrent downloads (default: 3) | No |
CIVITAI_PRELOAD_ENABLED |
Enable predictive model loading | No |
Factory Functions#
typescript
// Create provider with configuration
const provider = createCivitaiProvider('your-api-key', {
baseUrl: 'https://civitai.com/api',
timeoutMs: 300000,
enableCostTracking: true,
});
// Create from environment
const provider = createCivitaiProviderFromEnv();
// Specialized providers
const imageProvider = createCivitaiImageProvider('your-api-key');
const videoProvider = createCivitaiVideoProvider('your-api-key');
AIR URN System#
Civitai uses the AIR (Artificial Intelligence Resource) URN format to reference models consistently.
URN Format#
text
urn:air:{ecosystem}:{type}:{source}:{id}@{version}.{format}
| Component | Description | Example Values |
|---|---|---|
ecosystem |
AI ecosystem | sd1, sd2, sdxl, flux, pony, video |
type |
Resource type | checkpoint, lora, lycoris, embedding, vae, controlnet |
source |
Model source | civitai, huggingface |
id |
Model ID | Numeric ID |
version |
Version ID (optional) | Numeric ID |
format |
File format (optional) | safetensor, ckpt, diffuser |
URN Examples#
typescript
// Popular SDXL checkpoint
const juggernautXL = 'urn:air:sdxl:checkpoint:civitai:133005@348913';
// SD 1.5 checkpoint
const realisticVision = 'urn:air:sd1:checkpoint:civitai:4201@130072';
// Flux checkpoint
const fluxDev = 'urn:air:flux:checkpoint:civitai:618692@691639';
// LoRA
const styleLora = 'urn:air:sdxl:lora:civitai:123456@789012';
Parsing and Building URNs#
typescript
import { parseAIRURN, buildAIRURN } from '@oshun/civitai-provider';
// Parse URN string
const urn = parseAIRURN('urn:air:sdxl:checkpoint:civitai:133005@348913');
console.log(urn);
// {
// ecosystem: 'sdxl',
// type: 'checkpoint',
// source: 'civitai',
// id: 133005,
// version: 348913
// }
// Build URN from components
const urnString = buildAIRURN({
ecosystem: 'sdxl',
type: 'lora',
source: 'civitai',
id: 123456,
version: 789012,
format: 'safetensor',
});
// 'urn:air:sdxl:lora:civitai:123456@789012.safetensor'
Image Generation#
Basic Generation#
typescript
const job = await provider.generateImage({
model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
params: {
prompt: 'A majestic dragon flying over a castle at sunset',
negativePrompt: 'blurry, low quality, artifacts',
scheduler: 'EulerA',
steps: 20,
cfgScale: 7,
width: 1024,
height: 1024,
seed: 12345,
clipSkip: 1,
},
batchSize: 4,
callbackUrl: 'https://api.myapp.com/webhooks/civitai',
});
console.log('Job ID:', job.jobId);
console.log('Cost:', job.cost, 'Buzz');
Quality Presets#
typescript
// Fast generation
const fastJob = await provider.generateImageWithPreset(
'urn:air:sdxl:checkpoint:civitai:133005@348913',
'A beautiful landscape',
'fast' // 12 steps, EulerA, CFG 4
);
// Balanced quality
const balancedJob = await provider.generateImageWithPreset(
'urn:air:sdxl:checkpoint:civitai:133005@348913',
'A beautiful landscape',
'balanced' // 20 steps, EulerA, CFG 6
);
// High quality
const qualityJob = await provider.generateImageWithPreset(
'urn:air:sdxl:checkpoint:civitai:133005@348913',
'A beautiful landscape',
'quality' // 30 steps, DPM2MKarras, CFG 7
);
// Maximum quality
const highQualityJob = await provider.generateImageWithPreset(
'urn:air:sdxl:checkpoint:civitai:133005@348913',
'A beautiful landscape',
'highQuality' // 50 steps, DPM2MKarras, CFG 7
);
Preset Configuration Reference#
| Preset | Scheduler | Steps | CFG Scale |
|---|---|---|---|
fast |
EulerA | 12 | 4 |
balanced |
EulerA | 20 | 6 |
quality |
DPM2MKarras | 30 | 7 |
highQuality |
DPM2MKarras | 50 | 7 |
Using Additional Networks#
typescript
const job = await provider.generateImage({
model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
params: {
prompt: 'myperson, portrait, high quality',
width: 1024,
height: 1024,
},
additionalNetworks: [
{
urn: 'urn:air:sdxl:lora:civitai:123456@789012',
strength: 0.8,
triggerWord: 'myperson',
},
{
urn: 'urn:air:sdxl:embedding:civitai:98765',
strength: 0.5,
},
],
});
Using ControlNet#
typescript
const job = await provider.generateImage({
model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
params: {
prompt: 'A woman standing',
width: 1024,
height: 1024,
},
controlNets: [
{
preprocessor: 'openpose',
model: 'urn:air:sdxl:controlnet:civitai:111222',
weight: 1.0,
startStep: 0,
endStep: 0.8,
image: 'https://example.com/pose-reference.png',
},
],
});
Schedulers#
| Scheduler | Description | Best For |
|---|---|---|
EulerA |
Euler ancestral | Fast, general purpose |
Euler |
Euler | Consistent results |
DPM2M |
DPM++ 2M | Balanced quality |
DPM2MKarras |
DPM++ 2M Karras | High quality |
DPMSDEKarras |
DPM++ SDE Karras | Best quality, slower |
DDIM |
DDIM | Inpainting |
UniPC |
UniPC | Fast convergence |
LCM |
Latent Consistency | Very fast (4-8 steps) |
Video Generation#
Supported Video Models#
| Model | Name | Max Duration | LoRA | Image-to-Video |
|---|---|---|---|---|
vidu-q1 |
Vidu Q1 | 8s | No | Yes |
veo3 |
Google Veo3 | 10s | No | Yes |
hailuo |
Hailuo (MiniMax) | 6s | No | Yes |
kling |
Kling | 5s | No | Yes |
ltxv |
Lightricks LTXV | 4s | No | No |
hunyuan |
Hunyuan (Tencent) | 8s | Yes | Yes |
wan-2.1 |
Wan 2.1 (Alibaba) | 8s | Yes | Yes |
wan-2.2 |
Wan 2.2 (Alibaba) | 8s | Yes | Yes |
mochi |
Mochi | 5s | No | No |
haiper |
Haiper | 4s | No | Yes |
Basic Video Generation#
typescript
const job = await provider.generateVideo({
model: 'wan-2.1',
params: {
prompt: 'A person walking through a field of flowers',
negativePrompt: 'blurry, distorted',
duration: 4,
width: 1280,
height: 720,
quality: 'standard',
movement: 'medium',
enhancePrompt: true,
seed: 12345,
},
callbackUrl: 'https://api.myapp.com/webhooks/video',
});
Convenience Methods#
typescript
// Wan 2.1 video
const wanJob = await provider.generateWanVideo(
'A beautiful sunset over the ocean',
{ duration: 6, quality: 'professional' },
[{ urn: 'urn:air:video:lora:civitai:123456', strength: 0.8 }]
);
// Hunyuan video
const hunyuanJob = await provider.generateHunyuanVideo(
'A cat playing with yarn',
{ duration: 4, movement: 'large' }
);
// Vidu video
const viduJob = await provider.generateViduVideo('Abstract flowing colors', {
quality: 'professional',
});
Image-to-Video#
typescript
const job = await provider.generateVideo({
model: 'wan-2.1',
params: {
prompt: 'The scene comes to life with subtle movement',
referenceImage: 'https://example.com/source-image.png',
duration: 4,
movement: 'small',
},
});
Video Quality Modes#
| Mode | Description | Cost Multiplier |
|---|---|---|
draft |
Fast preview | 0.5x |
standard |
Balanced quality | 1.0x |
professional |
Highest quality | 1.5x |
Job Management#
Job Status Flow#
text
queued → processing → completed
→ failed
→ cancelled
Getting Job Status#
typescript
// Get job by ID
const job = provider.getJob('job-id');
console.log('Status:', job.status);
console.log('Cost:', job.cost);
// Get job status from API
const status = await provider.getJobStatus('job-id');
console.log('Availability:', status.availability);
console.log('Blob URL:', status.blobUrl);
// Get jobs by token
const jobs = await provider.getJobsByToken('token');
Waiting for Completion#
typescript
// Wait for job with default timeout
const completedJob = await provider.waitForJob('job-id');
console.log('Result URL:', completedJob.result.blobUrl);
// Wait with custom timeout
const job = await provider.waitForJob('job-id', 60000); // 60 seconds
// Generate and wait
const result = await provider.generateImageAndWait({
model: 'urn:air:sdxl:checkpoint:civitai:133005@348913',
params: { prompt: 'A landscape' },
});
console.log('Image URL:', result.blobUrl);
Cancelling Jobs#
typescript
await provider.cancelJob('job-id');
Event Handling#
typescript
// Listen for job events
provider.on('job:submitted', ({ job }) => {
console.log('Job submitted:', job.jobId);
});
provider.on('job:started', ({ jobId }) => {
console.log('Job started:', jobId);
});
provider.on('job:completed', ({ job }) => {
console.log('Job completed:', job.jobId, job.result?.blobUrl);
});
provider.on('job:failed', ({ jobId, error }) => {
console.error('Job failed:', jobId, error);
});
provider.on('cost:recorded', ({ jobId, cost }) => {
console.log('Cost recorded:', jobId, cost, 'Buzz');
});
Model Discovery#
Searching Models#
typescript
const models = await provider.searchModels({
query: 'realistic portrait',
types: ['Checkpoint', 'LORA'],
baseModels: ['SDXL 1.0'],
tags: ['photorealistic'],
sort: 'Highest Rated',
page: 1,
limit: 20,
nsfw: false,
});
for (const model of models) {
console.log(`${model.name} by ${model.creator.username}`);
console.log(`Downloads: ${model.downloadCount}`);
console.log(`Rating: ${model.rating} (${model.ratingCount} ratings)`);
}
Getting Model Details#
typescript
// Get model by ID
const model = await provider.getModel(133005);
console.log('Name:', model.name);
console.log('Type:', model.type);
console.log('Versions:', model.versions.length);
// Get specific version
const version = await provider.getModelVersion(348913);
console.log('Version:', version.name);
console.log('Base Model:', version.baseModel);
console.log('Trained Words:', version.trainedWords);
Building Model URN#
typescript
// Build URN from model and version
const urn = provider.buildModelURN(
133005, // modelId
348913, // versionId
'sdxl', // ecosystem
'checkpoint' // type
);
// 'urn:air:sdxl:checkpoint:civitai:133005@348913'
Cost Estimation#
Image Generation Cost#
typescript
import { estimateImageCost } from '@oshun/civitai-provider';
// Estimate cost
const estimate = estimateImageCost(
'sdxl', // ecosystem
2, // number of LoRAs
4, // batch size
false // is draft mode
);
console.log('Base cost:', estimate.baseCost);
console.log('Network cost:', estimate.networkCost);
console.log('Total cost:', estimate.totalCost, 'Buzz');
console.log('Breakdown:', estimate.breakdown);
Cost by Ecosystem#
| Ecosystem | Base Cost | Draft Cost |
|---|---|---|
sd1 |
2 Buzz | - |
sd2 |
2 Buzz | - |
sdxl |
5 Buzz | 3 Buzz |
flux |
8 Buzz | - |
pony |
4 Buzz | - |
Video Generation Cost#
typescript
import { estimateVideoCost } from '@oshun/civitai-provider';
const estimate = estimateVideoCost(
'wan-2.1', // model
6, // duration in seconds
'professional' // quality
);
console.log('Total cost:', estimate.totalCost, 'Buzz');
Video Cost Per Second#
| Model | Base Cost/Second |
|---|---|
vidu-q1 |
15 Buzz |
veo3 |
25 Buzz |
hailuo |
12 Buzz |
kling |
18 Buzz |
ltxv |
8 Buzz |
hunyuan |
10 Buzz |
wan-2.1 |
10 Buzz |
wan-2.2 |
12 Buzz |
mochi |
8 Buzz |
haiper |
10 Buzz |
Cost Tracking#
typescript
// Get total Buzz spent in session
const totalSpent = provider.getTotalBuzzSpent();
console.log('Total spent:', totalSpent, 'Buzz');
// Estimate before generating
const imageEst = provider.estimateImageCost(
'urn:air:sdxl:checkpoint:civitai:133005@348913',
2 // LoRA count
);
const videoEst = provider.estimateVideoCost(
'wan-2.1',
6, // duration
'standard'
);
Error Handling#
Error Codes#
| Code | Description | Retryable |
|---|---|---|
AUTH_FAILED |
Invalid API key | No |
RATE_LIMITED |
Rate limit exceeded | Yes |
INSUFFICIENT_BUZZ |
Not enough Buzz balance | No |
MODEL_NOT_FOUND |
Model doesn't exist | No |
INVALID_PARAMETERS |
Invalid generation params | No |
JOB_NOT_FOUND |
Job doesn't exist | No |
JOB_FAILED |
Generation failed | No |
TIMEOUT |
Request timed out | Yes |
NETWORK_ERROR |
Network connectivity issue | Yes |
Error Handling Example#
typescript
import { CivitaiError } from '@oshun/civitai-provider';
try {
const result = await provider.generateImageAndWait({
model: modelUrn,
params: { prompt: 'Test' },
});
} catch (error) {
if (error instanceof CivitaiError) {
switch (error.code) {
case 'RATE_LIMITED':
console.log('Rate limited. Retry after:', error.details?.retryAfter);
break;
case 'INSUFFICIENT_BUZZ':
console.log('Not enough Buzz. Please top up your account.');
break;
case 'MODEL_NOT_FOUND':
console.log('Model not found:', error.details?.model);
break;
case 'TIMEOUT':
console.log('Request timed out. Retrying...');
break;
default:
console.error('Error:', error.message);
}
}
}
Configuration Reference#
CivitaiConfig#
typescript
interface CivitaiConfig {
/** API key (required) */
apiKey: string;
/** Base API URL */
baseUrl?: string; // default: 'https://civitai.com/api'
/** Request timeout in milliseconds */
timeoutMs?: number; // default: 300000 (5 minutes)
/** Enable cost tracking */
enableCostTracking?: boolean; // default: true
/** Default scheduler for image generation */
defaultScheduler?: Scheduler; // default: 'EulerA'
/** Default number of steps */
defaultSteps?: number; // default: 20
/** Default CFG scale */
defaultCfgScale?: number; // default: 7
/** Poll interval for job status (ms) */
pollIntervalMs?: number; // default: 2000
/** Maximum poll attempts */
maxPollAttempts?: number; // default: 150
}
Popular Models#
The provider includes pre-defined URNs for popular models:
typescript
import { POPULAR_MODELS } from '@oshun/civitai-provider';
// SD 1.5 models
POPULAR_MODELS.realisticVision; // Realistic Vision
POPULAR_MODELS.deliberate; // Deliberate
POPULAR_MODELS.dreamshaper; // DreamShaper
// SDXL models
POPULAR_MODELS.juggernautXL; // Juggernaut XL
POPULAR_MODELS.realvisXL; // RealVisXL
POPULAR_MODELS.animagineXL; // Animagine XL
// Flux models
POPULAR_MODELS.fluxDev; // Flux.1 Dev
// Pony models
POPULAR_MODELS.ponyDiffusion; // Pony Diffusion
TypeScript Types#
typescript
import type {
// URN Types
AIRURN,
AIEcosystem,
ResourceType,
ModelSource,
ModelFormat,
// Generation Types
ImageGenerationParams,
ImageGenerationRequest,
VideoGenerationParams,
VideoGenerationRequest,
AdditionalNetwork,
ControlNetConfig,
// Video Types
VideoModel,
VideoQuality,
MovementAmplitude,
// Job Types
GenerationJob,
JobStatus,
JobResult,
JobAvailability,
// Model Types
ModelInfo,
ModelVersionInfo,
ModelSearchQuery,
ModelTypeFilter,
ModelSort,
// Cost Types
CostEstimate,
BuzzBalance,
// Configuration
CivitaiConfig,
Scheduler,
} from '@oshun/civitai-provider';
Related Documentation#
- Model Management - Managing models, downloads, and versions
- Training Guide - Training custom LoRAs
- Best Practices - Optimization and cost management