Перейти к основному содержанию
Следуйте этим рекомендациям для построения надёжной и эффективной интеграции.

Выбор режима запроса

РежимЛучше дляПлюсыМинусы
Async (Polling)Клиентские приложения, простые скриптыЛегко реализоватьНужна логика polling
Callback (Webhooks)Продакшен-серверыReal-time, без pollingНужен публичный эндпоинт
Используйте режим async при разработке, переключайтесь на callback для продакшена.

Стратегия polling

Для режима async реализуйте умный polling, чтобы балансировать отзывчивость и эффективность.

Рекомендуемые интервалы

Тип моделиНачальная паузаИнтервал опросаМакс. ожидание
Image (быстрая)5 с3 с2 мин
Image (качество)10 с5 с3 мин
Video60 с15 с10 мин
Audio30 с10 с5 мин

Экспоненциальный backoff

async function pollWithBackoff(model, taskId, apiKey) {
  let interval = 3000; // Start at 3s
  const maxInterval = 30000; // Max 30s
  const maxAttempts = 60;
  
  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(
      `https://api.apixo.ai/api/v1/statusTask/${model}?taskId=${taskId}`,
      { headers: { 'Authorization': `Bearer ${apiKey}` } }
    );
    
    const { data } = await response.json();
    
    if (data.state === 'success') {
      return JSON.parse(data.resultJson).resultUrls;
    }
    if (data.state === 'failed') {
      throw new Error(data.failMsg);
    }
    
    await new Promise(r => setTimeout(r, interval));
    interval = Math.min(interval * 1.5, maxInterval);
  }
  
  throw new Error('Timeout');
}

Обработка ошибок

Всегда обрабатывайте сбои

const result = await pollForResult(taskId);

if (!result) {
  // Handle null/undefined
}

// Check for specific error codes
if (result.state === 'failed') {
  switch (result.failCode) {
    case 'CONTENT_VIOLATION':
      // Prompt needs modification
      break;
    case 'PROCESSING_TIMEOUT':
      // Retry the request
      break;
    case 'INSUFFICIENT_CREDITS':
      // Alert user to add credits
      break;
  }
}

Реализуйте повторы

async function generateWithRetry(params, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await generateImage(params);
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      
      // Only retry on transient errors
      if (error.failCode === 'PROCESSING_TIMEOUT') {
        await new Promise(r => setTimeout(r, 5000));
        continue;
      }
      
      throw error; // Don't retry content violations etc.
    }
  }
}

Prompt Engineering

Советы по генерации изображений

РекомендуетсяНе рекомендуется
Конкретно: «Щенок золотистого ретривера играет в осенних листьях»Расплывчато: «Собака»
Указывать стиль: «акварель, мягкий свет»Полагаться на значения по умолчанию
Состав: «крупный портрет, по центру»Оставлять композицию на волю случая
Использовать позитивные описанияНегативы вроде «без фона»

Эффективная структура prompt

[Объект] + [Действие/Поза] + [Окружение] + [Стиль] + [Технические детали]
Пример:
Молодая женщина читает книгу в уютном кафе, 
тёплый дневной свет через окна, 
импрессионистский масляный стиль, 
мягкий фокус на фоне, освещение golden hour

Управление ресурсами

Скачивайте результаты вовремя

// Result URLs expire after 24 hours
const urls = await generateImage(prompt);

// Download immediately
for (const url of urls) {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  // Save to your storage
}

Сохраняйте ID задач

// Log task IDs for debugging
console.log(`Task submitted: ${taskId}`);

// Store in database for reference
await db.tasks.create({
  taskId,
  userId: user.id,
  model,
  prompt,
  status: 'pending',
  createdAt: new Date(),
});

Оптимизация стоимости

Выбор модели

ИспользованиеРекомендуемая модельПримечания
ПрототипированиеNano BananaБыстрая итерация
Продакшен-качествоFlux-2 ProБаланс качества и контроля
Премиум-качествоMidjourneyВыразительный художественный стиль
Видео (короткие)Wan 2.5Эффективная короткая генерация
Видео (кинематограф)Sora 2Максимальное качество видео
Актуальные цены — на странице Цены.

Группируйте похожие запросы

Для нескольких вариаций используйте режим image-to-image вместо генерации с нуля каждый раз.

Мониторьте использование

// Track costs per user/project
await db.usage.create({
  userId: user.id,
  model,
  cost: MODEL_COSTS[model],
  timestamp: new Date(),
});

// Set up alerts for unusual usage
if (dailyCost > threshold) {
  sendAlert('High API usage detected');
}

Безопасность

Защита API-ключа

// DO: Use environment variables
const apiKey = process.env.APIXO_API_KEY;

// DON'T: Hardcode in source
const apiKey = 'sk-abc123'; // Never do this!

// DON'T: Expose in client-side code
// API calls should go through your backend

Валидация пользовательского ввода

function validatePrompt(prompt) {
  if (!prompt || typeof prompt !== 'string') {
    throw new Error('Invalid prompt');
  }
  
  if (prompt.length > 5000) {
    throw new Error('Prompt too long');
  }
  
  // Sanitize before sending to API
  return prompt.trim();
}

Производительность

Connection pooling

// Reuse HTTP connections
const agent = new https.Agent({ keepAlive: true });

const response = await fetch(url, {
  agent,
  // ...
});

Параллелизация

// Generate multiple images in parallel
const prompts = ['prompt1', 'prompt2', 'prompt3'];

const tasks = await Promise.all(
  prompts.map(prompt => submitTask(prompt))
);

const results = await Promise.all(
  tasks.map(task => pollForResult(task.taskId))
);

Мониторинг

Логирование вызовов API

const startTime = Date.now();

try {
  const result = await generateImage(prompt);
  
  logger.info('Generation successful', {
    taskId: result.taskId,
    duration: Date.now() - startTime,
    model,
  });
} catch (error) {
  logger.error('Generation failed', {
    error: error.message,
    duration: Date.now() - startTime,
    model,
  });
}

Настройка алертов

Отслеживайте:
  • Высокий процент ошибок
  • Необычную задержку
  • Резкие скачки стоимости
  • Срабатывания лимитов