Saltar al contenido principal
Sigue estas recomendaciones para construir integraciones robustas y eficientes.

Elegir modo de solicitud

ModoIdeal paraProsContras
Async (Polling)Apps cliente, scripts simplesFácil de implementarRequiere lógica de polling
Callback (Webhooks)Servidores de producciónTiempo real, sin pollingRequiere endpoint público
Comienza con modo async en desarrollo, cambia a callback para producción.

Estrategia de polling

Para modo async, implementa polling inteligente para equilibrar capacidad de respuesta y eficiencia.

Intervalos recomendados

Tipo de modeloEspera inicialIntervalo de pollingEspera máxima
Imagen (rápido)5s3s2 min
Imagen (calidad)10s5s3 min
Video60s15s10 min
Audio30s10s5 min

Backoff exponencial

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');
}

Manejo de errores

Siempre gestiona los fallos

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;
  }
}

Implementa reintentos

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.
    }
  }
}

Ingeniería de prompts

Consejos para generación de imágenes

HazNo hagas
Sé específico: “Un cachorro golden retriever jugando en hojas otoñales”Sé vago: “Un perro”
Incluye estilo: “pintura acuarela, iluminación suave”Da por hecho los valores por defecto
Especifica composición: “retrato primer plano, centrado”Deja la composición al azar
Usa descripciones positivasUsa negativos como “sin fondo”

Estructura efectiva del prompt

[Sujeto] + [Acción/Pose] + [Entorno] + [Estilo] + [Detalles técnicos]
Ejemplo:
Una joven leyendo un libro en una acogedora cafetería, 
luz cálida de tarde a través de ventanas, 
estilo pintura al óleo impresionista, 
fondo con enfoque suave, iluminación hora dorada

Gestión de recursos

Descarga los resultados con prontitud

// 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
}

Almacena los IDs de tarea

// 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(),
});

Optimización de costes

Elige el modelo adecuado

Caso de usoModelo recomendadoNotas
PrototipadoNano BananaIteración rápida para feedback
Calidad producciónFlux-2 ProFidelidad y control equilibrados
Calidad premiumMidjourneyEstilo artístico potente
Video (corto)Wan 2.5Generación corta eficiente
Video (cinematográfico)Sora 2Mayor calidad de video
Para precios actuales, consulta siempre la página de Precios.

Agrupa solicitudes similares

Si generas múltiples variaciones, usa modo image-to-image en lugar de generar desde cero cada vez.

Monitorea el uso

// 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');
}

Seguridad

Protege tu clave 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

Valida la entrada del usuario

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();
}

Rendimiento

Usa conexiones reutilizables

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

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

Paraleliza cuando sea posible

// 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))
);

Monitoreo

Registra las llamadas a la 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,
  });
}

Configura alertas

Monitoriza:
  • Tasa de errores alta
  • Latencia inusual
  • Picos de costo
  • Impactos en el límite de tasa