Saltar al contenido principal
APIXO ofrece dos formas de recibir resultados de tareas: polling (modo async) y webhooks (modo callback). Esta guía te ayuda a elegir el enfoque adecuado e implementarlo de forma efectiva.

Comparación rápida

AspectoPolling (Async)Webhooks (Callback)
ConfiguraciónSimpleRequiere endpoint público
Tiempo realCasi tiempo realInstantáneo
Llamadas APIMúltiples por tareaUna por tarea
Ideal paraDesarrollo, apps clienteServidores de producción
InfraestructuraNingunaEndpoint HTTPS

Cuándo usar Polling

Elige polling cuando:
  • Construyes aplicaciones del lado del cliente
  • Prototipas o pruebas
  • No tienes un servidor público
  • Procesas bajo volumen de tareas

Implementación básica de polling

async function pollForResult(model, taskId, apiKey) {
  const interval = 3000; // 3 seconds
  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));
  }
  
  throw new Error('Timeout');
}

Backoff exponencial

Para mejor eficiencia, usa backoff exponencial:
async function pollWithBackoff(model, taskId, apiKey) {
  let interval = 3000; // Start at 3s
  const maxInterval = 30000; // Max 30s
  const maxTime = 300000; // 5 min timeout
  let elapsed = 0;
  
  while (elapsed < maxTime) {
    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));
    elapsed += interval;
    interval = Math.min(interval * 1.5, maxInterval);
  }
  
  throw new Error('Timeout');
}

Intervalos recomendados por tipo de modelo

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

Cuándo usar Webhooks

Elige webhooks cuando:
  • Ejecutas un servidor de producción
  • Procesas alto volumen de tareas
  • Necesitas notificaciones en tiempo real
  • Quieres minimizar las llamadas a la API

Configuración de webhook

1. Crea un endpoint:
const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook/apixo', (req, res) => {
  const { taskId, state, resultJson, failCode, failMsg } = req.body.data;
  
  if (state === 'success') {
    const urls = JSON.parse(resultJson).resultUrls;
    console.log('Generated:', urls);
    // Process your images/videos
  } else if (state === 'failed') {
    console.error(`Task ${taskId} failed: ${failCode}`);
  }
  
  res.status(200).send('OK');
});

app.listen(3000);
2. Envía tarea con callback:
const response = await fetch('https://api.apixo.ai/api/v1/generateTask/nano-banana', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    request_type: 'callback',
    callback_url: 'https://your-domain.com/webhook/apixo',
    input: {
      mode: 'text-to-image',
      prompt: 'A beautiful landscape',
    },
  }),
});

Requisitos del webhook

  • Debe ser accesible públicamente por HTTPS
  • Debe responder con HTTP 200 en 30 segundos
  • Debe manejar entregas duplicadas (usa taskId para idempotencia)

Política de reintentos

Si tu webhook falla:
IntentoRetraso
1º reintento30 segundos
2º reintento2 minutos
3º reintento10 minutos
Tras 3 intentos fallidos, se abandona el webhook. Aún puedes consultar vía el endpoint de estado.

Enfoque híbrido

Para máxima fiabilidad, combina ambos enfoques:
class TaskManager {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.pendingTasks = new Map();
  }
  
  async submit(model, input, callbackUrl = null) {
    const response = await fetch(
      `https://api.apixo.ai/api/v1/generateTask/${model}`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${this.apiKey}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          request_type: callbackUrl ? 'callback' : 'async',
          callback_url: callbackUrl,
          input,
        }),
      }
    );
    
    const { data } = await response.json();
    
    if (!callbackUrl) {
      // Fallback to polling if no webhook
      return this.poll(model, data.taskId);
    }
    
    // Track task for webhook
    this.pendingTasks.set(data.taskId, { model, status: 'pending' });
    return data.taskId;
  }
  
  handleWebhook(body) {
    const { taskId, state, resultJson, failMsg } = body.data;
    
    if (state === 'success') {
      this.pendingTasks.delete(taskId);
      return JSON.parse(resultJson).resultUrls;
    }
    
    if (state === 'failed') {
      this.pendingTasks.delete(taskId);
      throw new Error(failMsg);
    }
  }
  
  async poll(model, taskId) {
    // Fallback polling implementation
    return pollWithBackoff(model, taskId, this.apiKey);
  }
}

Desarrollo local con ngrok

Para probar webhooks localmente:
# Install ngrok
npm install -g ngrok

# Start your local server
node server.js  # runs on port 3000

# Tunnel to local server
ngrok http 3000
# Returns: https://abc123.ngrok.io

# Use ngrok URL as callback_url

Resumen

EscenarioRecomendación
Desarrollo / PruebasPolling
App del clientePolling
Backend de producciónWebhooks
Alto volumenWebhooks
Máxima fiabilidadHíbrido (webhooks + fallback polling)
Comienza con polling por simplicidad, luego migra a webhooks conforme escale tu aplicación.