Ruta del menú: Panel > Tareas

Tareas

Resumen

Las tareas permiten que una IA como ChatGPT o Claude ejecute trabajo en su propio servidor (un worker). Diga "Haz un pedido de 30 unidades de A-1042 en nuestro ERP" y la IA envía el trabajo a su worker y le muestra el resultado en la conversación.

  • 3Min API solo entrega la tarea y registra su estado; el trabajo real lo hace el worker
  • Un worker es un servidor HTTP que usted mismo opera

Cuándo usarlo

  • Para que sistemas internos hagan algo — registrar un pedido en el ERP, consultar stock, buscar en una base de datos interna
  • Trabajo que lleva tiempo — generar informes, conversiones masivas (hasta 24 horas)
  • Scripts que solo funcionan en su propio equipo — añada una URL pública con un túnel (ver abajo)

Si el objetivo es guardar y recopilar datos, use un endpoint.

¿No se siente cómodo escribiendo el código del worker? Pídaselo a la IA que ya usa: "Hazme un worker de tareas de 3minapi". La IA lee el mismo contrato que esta página desde la herramienta help y escribe el código.

Cómo llegar aquí

  • Registrar un worker: Panel → Tareas → pestaña WorkersRegistrar worker
  • Ver ejecuciones: Panel → Tareas → pestaña Ejecuciones

Cómo funciona

① Registrar un worker en la web     (una sola vez)
② IA → task_create                  tarea creada, estado working
③ 3Min API → POST al worker         solicitud firmada (incluye callback_url)
④ Worker → 2xx de inmediato         solo significa "recibido", no es un resultado
⑤ Worker → callback_url             mensajes de progreso (opcional) → completed o failed
⑥ IA → task_get                     lee el resultado
Dónde Qué se hace
Panel web Registrar, editar y eliminar workers; ver y renovar secretos; ver ejecuciones
Chat con la IA Listar workers, enviar tareas, consultar estado y resultados, cancelar
Servidor del worker Recibir solicitudes, hacer el trabajo, informar el resultado

La IA no puede ver la URL ni los secretos de un worker. Ambos se gestionan solo en la web.

Registrar un worker (web)

Campo Descripción Límite
Nombre Obligatorio. El nombre que usa la IA. Único sin distinguir mayúsculas, no se puede cambiar 50 caracteres
Descripción Obligatorio. La IA elige el worker a partir de esta descripción 500 caracteres
URL del worker Obligatorio. La dirección que recibe las tareas por POST 2.048 bytes
Encabezado de autorización / Valor de autorización Opcional. Para la autenticación propia del worker. Con solo el valor, el encabezado es Authorization 128 / 8.192 bytes
  • Escriba una descripción concreta. La IA solo ve el nombre y la descripción, nunca la URL. En lugar de erp-1, escriba algo como "Registra un pedido en nuestro ERP y devuelve el número de pedido" — qué recibe y qué devuelve — para que la IA pueda elegirlo

Dos secretos en direcciones opuestas

Al registrarse se generan dos secretos automáticamente. Consúltelos en la página del worker (Panel → Tareas → pestaña Workers → seleccione un worker) con Mostrar secreto · Copiar secreto.

Secreto Formato Dirección Uso
Secreto de firma whsec_... 3Min API → worker Verificar que una solicitud viene realmente de 3Min API
Clave de respuesta tm_task_... worker → 3Min API Se envía como Authorization: Bearer al informar
  • Los dos valores son distintos y no intercambiables. Una clave de API de endpoint (tm_live_ · tm_test_) tampoco sirve como clave de respuesta
Cambio Qué ocurre Qué debe hacer el worker
Rotar secreto de firma Durante 48 horas, las tareas nuevas llevan la firma nueva y la anterior. Los reintentos de tareas creadas antes de la rotación (hasta unas 5 horas) llevan solo la anterior Conservar el secreto anterior al menos 6 horas y cambiar dentro de las 48 horas
Regenerar clave de respuesta La clave anterior deja de funcionar de inmediato (incluidas las tareas en curso) Cambiarla de inmediato

Si vuelve a rotar dentro de las 48 horas, el secreto original deja de funcionar de inmediato. El panel solo muestra el secreto actual, así que cópielo antes de rotar si su worker debe seguir aceptando el anterior.

Implementar un worker

Cinco reglas para workers

  1. Devuelva 2xx en menos de 15 segundos. Haga el trabajo después de responder
  2. Acepte la solicitud con 2xx aunque su trabajo falle. Informe el fallo en su lugar (5xx se reintenta, otros 4xx hacen fallar la tarea al instante — vea los códigos de respuesta)
  3. Elimine duplicados por task_id. La misma tarea puede llegar dos veces (at-least-once)
  4. La verificación de la firma es opcional, pero recomendable. Sin ella, cualquiera que conozca la URL del worker puede enviar tareas falsas (verificación de firma)
  5. Informe el resultado a callback_url. Envíe completed o failed una vez. Sin informe, la tarea pasa a failed a las 24 horas (API de informe de estado)

Solicitud de entrega

La solicitud que 3Min API envía a la URL del worker.

POST https://worker.example.com/tasks
Content-Type: application/json
webhook-id: 0199a1b2-...
webhook-timestamp: 1757650867
webhook-signature: v1,K3XkZ1n0...
X-3minapi-Task-Id: 0199a1b2-...
X-3minapi-Delivery-Attempt: 1
Authorization: Bearer xxx
Encabezado Contenido
webhook-id ID de la tarea (mismo valor que task_id)
webhook-timestamp Hora de envío (segundos Unix). Nueva en cada intento
webhook-signature Firma. Dos valores separados por espacio durante una rotación (verificación de firma)
X-3minapi-Task-Id ID de la tarea (mismo valor que webhook-id)
X-3minapi-Delivery-Attempt Número de intento de entrega (desde 1)
Su encabezado de autorización Solo si introdujo un encabezado y valor de autorización al registrar

Cuerpo:

{
	"type": "task.created",
	"timestamp": "2026-09-12T04:21:07.123Z",
	"data": {
		"task_id": "0199a1b2-...",
		"input": { "sku": "A-1042", "qty": 30 },
		"callback_url": "https://api.3minapi.com/api/v1/tasks/0199a1b2-.../result"
	}
}
Campo Contenido
task_id ID de la tarea. Úselo para eliminar duplicados
input El objeto JSON que envió la IA (mismos valores; el orden de las claves puede variar)
callback_url La URL de informe de esta tarea. Envíe aquí el estado y los resultados

Códigos de respuesta del worker

Solo cuenta el código de estado; el cuerpo de la respuesta se ignora.

Respuesta Resultado
2xx Aceptada. La tarea sigue en working hasta que llega un informe
5xx (excepto 501 · 505), 429, tiempo de espera de 15 s, error de red Reintento a los 30 s · 2 min · 10 min · 1 h · 4 h — 6 intentos en total (unas 5 horas). El Retry-After de un 429 solo se aplica si es más largo
Otros 4xx (401 · 404 · 409, …), 501, 505 failed al instante, sin reintento
  • Devuelva 401 cuando falle la verificación de la firma. Si el secreto se introdujo mal, la primera tarea falla de inmediato y detecta el problema de configuración enseguida

Verificación de firma (opcional)

El encabezado webhook-signature es la firma. 3Min API la calcula con el secreto de firma del worker, y el worker repite el cálculo para comprobar que coincide.

contenido firmado = "{webhook-id}.{webhook-timestamp}.{cuerpo original}"
clave             = el secreto de firma sin whsec_, decodificado en base64
firma             = "v1," + base64( HMAC-SHA256(clave, contenido firmado) )
  • Con una biblioteca oficial de Standard Webhooks bastan unas líneas (código de ejemplo). Para paquetes por lenguaje e implementación manual, consulte Verificar la firma del webhook (mismo esquema)
  • Verifique sobre los bytes originales del cuerpo. Analizar el JSON y volver a serializarlo siempre falla
  • La biblioteca rechaza un webhook-timestamp desfasado más de 5 minutos (bloquea solicitudes reenviadas)
  • Si llegan dos firmas, basta con que cualquiera coincida (reglas de rotación)
  • Si no verifica, compruebe al menos que callback_url empiece por https://api.3minapi.com/ — su clave de respuesta se envía a esa dirección

API de informe de estado

Envíe el estado a la callback_url de la solicitud de entrega. Los mensajes de progreso pueden enviarse muchas veces; completed o failed se envía una vez.

POST https://api.3minapi.com/api/v1/tasks/{task_id}/result
Authorization: Bearer tm_task_...
Content-Type: application/json
  • URL: callback_url llega con este formato y el ID de la tarea ya incluido. No la construya usted — úsela tal cual
  • Clave de respuesta: Clave de respuesta en la página del worker → Copiar secreto. Guárdela en las variables de entorno del servidor del worker o similar

En curso — la tarea sigue en working y la IA ve el mensaje con task_get

{ "status": "working", "status_message": "1/2 Comprobando stock" }

Completada

{
	"status": "completed",
	"result": { "order_id": "PO-20260912-001" },
	"status_message": "Pedido PO-20260912-001 registrado"
}

Fallida

{
	"status": "failed",
	"error": { "code": 1001, "message": "Sin stock", "data": { "available": 12 } }
}
Campo Regla
status Uno de working · completed · failed
status_message Obligatorio para working, opcional en los demás. Se recorta a partir de 256 caracteres. En failed sin mensaje se usa error.message
result Obligatorio para completed. Cualquier JSON excepto null
error Obligatorio para failed. code (entero) + message (cadena); data es opcional
  • El cuerpo completo debe ser de 100 KB o menos. result y error nunca se recortan, así que un cuerpo mayor se rechaza con 413
  • Cada informe aceptado cuenta como una llamada a la API. Envíe mensajes de progreso solo en pasos significativos

Códigos de respuesta de la API de informe de estado

Código Significado Qué debe hacer el worker
202 Aceptado. Normalmente se aplica en unos segundos
400 Cuerpo mal formado, ID de tarea no válido, carácter NUL en una cadena Corregir el código
401 Clave de respuesta ausente o incorrecta (incluidas claves de API de endpoint) Revisar la clave
404 No es una tarea de este worker Revisar callback_url
409 La tarea ya terminó (completada · fallida · cancelada) Dejar de informar
413 Cuerpo mayor de 100 KB. No se registró nada Si la tarea sigue en working, reducir y reenviar
415 Content-Type no es JSON Corregir el encabezado
503 Interrupción temporal Reenviar en breve

Código de ejemplo (Node.js)

Requiere Node.js 18 o posterior y "type": "module" en package.json.

// npm i express standardwebhooks
import express from 'express';
import { Webhook } from 'standardwebhooks';

// El secreto de firma (whsec_...) y la clave de respuesta (tm_task_...) son valores distintos
const wh = new Webhook(process.env.TASK_SIGNING_SECRET.replace('whsec_', ''));
const CALLBACK_KEY = process.env.TASK_CALLBACK_KEY;
// task_id aceptados — en producción guárdelos en una base de datos o Redis
const seen = new Set();

const app = express();

// La firma cubre los bytes originales. Analizar el JSON antes hace fallar la verificación.
app.post('/tasks', express.raw({ type: 'application/json' }), (req, res) => {
	let envelope;
	try {
		envelope = wh.verify(req.body, {
			'webhook-id': req.header('webhook-id'),
			'webhook-timestamp': req.header('webhook-timestamp'),
			'webhook-signature': req.header('webhook-signature')
		});
	} catch {
		return res.sendStatus(401);
	}

	const { task_id, input, callback_url } = envelope.data;

	// Regla 3 — no procesar una tarea ya aceptada
	if (seen.has(task_id)) return res.sendStatus(202);
	seen.add(task_id);

	// Regla 1 — responder primero, trabajar después
	res.sendStatus(202);
	run(input, callback_url);
});

async function run(input, callbackUrl) {
	try {
		// Mensaje de progreso — la tarea sigue en working; la IA lo ve con task_get
		await report(callbackUrl, { status: 'working', status_message: '1/2 Comprobando stock' });
		await checkStock(input); // ← su trabajo real

		await report(callbackUrl, { status: 'working', status_message: '2/2 Registrando el pedido' });
		const orderId = await createOrder(input);

		// Completada — el resultado y un resumen
		await report(callbackUrl, {
			status: 'completed',
			result: { order_id: orderId },
			status_message: `Pedido ${orderId} registrado`
		});
	} catch (err) {
		// Regla 2 — si el trabajo o un informe falla, informar failed
		await report(callbackUrl, {
			status: 'failed',
			error: { code: 1001, message: String(err?.message ?? err) },
			status_message: 'No se pudo registrar el pedido'
		}).catch(console.error);
	}
}

// callbackUrl — la callback_url de la solicitud de entrega, usada tal cual
async function report(callbackUrl, body) {
	for (let attempt = 1; attempt <= 3; attempt++) {
		const res = await fetch(callbackUrl, {
			method: 'POST',
			headers: {
				Authorization: `Bearer ${CALLBACK_KEY}`,
				'Content-Type': 'application/json'
			},
			body: JSON.stringify(body)
		}).catch(() => null);

		// 202 aceptado, 409 tarea ya terminada — no hace falta enviar más
		if (res?.status === 202 || res?.status === 409) return;
		// 400 · 401 · 404 · 413 dan el mismo resultado al reenviar
		if (res && res.status !== 503) throw new Error(`report rejected: HTTP ${res.status}`);
		// Solo 503 y los errores de red se reintentan tras una pausa
		if (attempt < 3) await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt));
	}
	throw new Error('report failed: service unavailable');
}

app.listen(8080);

Ejecutar un worker en su propio equipo

Un worker necesita una URL pública accesible desde internet. Si el equipo está detrás de un router, use un túnel para asignar una dirección HTTPS pública a un puerto local.

cloudflared tunnel --url http://localhost:8080
ngrok http 8080
  • Instalación y uso: Cloudflare Quick Tunnels · Primeros pasos con ngrok
  • Añada su ruta a la dirección que se muestra (p. ej. https://xxxx.trycloudflare.com/tasks) y regístrela como URL del worker
  • Las direcciones temporales sin cuenta cambian en cada ejecución. Actualice la URL del worker cada vez o use la opción de dirección fija del servicio
  • Si el equipo está apagado o el túnel caído, la tarea suele pasar a failed tras los reintentos (unas 5 horas). Un servicio que devuelve 404 para una dirección desconectada la hace fallar al instante

Enviar tareas (IA)

Con un worker registrado, puede usarlo directamente desde un chat con la IA. No necesita conocer los nombres de las herramientas.

  • "Haz un pedido de 30 unidades de A-1042 en nuestro ERP"
  • "¿Qué pasó con el pedido que envié antes?"
  • "Cancela la tarea que acabo de enviar"
Herramienta Qué hace
worker_list Nombres y descripciones de los workers registrados (sin URL ni secretos)
task_create Crea una tarea a partir del nombre de un worker y un input (objeto JSON, hasta 100 KB)
task_get Estado, mensaje y resultado o error de una tarea
task_list Tareas recientes (sin el cuerpo de los resultados)
task_cancel Cancela tareas en curso (hasta 100)
  • El mismo worker y el mismo input en menos de 2 minutos (hasta unos 4 minutos según el momento) devuelven la tarea existente. Las tareas completadas y canceladas se devuelven tal cual; solo una tarea fallida se crea de nuevo
  • Cancelar no avisa al worker. Solo se detienen los intentos de entrega pendientes; los informes posteriores de un worker que ya recibió la tarea obtienen 409

Consultar el estado

Estado Significado ¿Puede cambiar?
working En entrega o en proceso en el worker
completed El worker informó que terminó Final
failed El worker informó un fallo, la entrega falló o pasaron 24 horas Final
cancelled Cancelada Final

El motivo de failed queda en status_message.

Causa Ejemplo de status_message
El worker informó un fallo El mensaje del worker (o error.message si no hay)
Reintentos agotados The task could not be delivered to the worker after 6 attempts (no response within 15s).
Respuesta de fallo inmediato The task could not be delivered to the worker after 1 attempt (HTTP 401).
Pasaron 24 horas Worker did not respond within 24 hours.

Dónde consultarlo:

  • IAtask_get · task_list. El result del worker se entrega tal cual, sin resumir
  • Web — pestaña Ejecuciones. Filtre por periodo (7 · 30 · 60 días; 7 en Free) y estado, y haga clic en una fila para ver entrada, resultado, error y entrega. Si la entrega falló definitivamente, Entrega muestra intentos, última respuesta y motivo

Límites

Elemento Valor
Workers 1 en Free / ilimitados en planes de pago
Tareas · ejecuciones simultáneas Ilimitadas (dentro de su cuota mensual de llamadas a la API)
Plazo 24 horas desde la creación — después, failed (se comprueba cada hora, así que hasta unas 25 horas)
Conservación del historial Al menos 60 días en planes de pago / en Free, los workers y sus ejecuciones se eliminan 7 días después de registrar el worker
Tamaño de input 100 KB
Cuerpo del informe 100 KB (status_message se recorta a 256 caracteres)
Tiempo de espera de entrega · reintentos 15 segundos · 6 intentos en unas 5 horas
Gracia de rotación del secreto de firma 48 horas
Regeneración de la clave de respuesta La clave anterior deja de funcionar de inmediato
Cómputo de llamadas a la API Una llamada correcta a una herramienta de tareas y un informe aceptado cuentan 1 cada uno. Entregas y reintentos cuentan 0. Los informes se aceptan aunque se supere la cuota
Garantía de entrega At-least-once (la misma tarea puede llegar dos veces)

Privacidad

  • El result y el error de un worker llegan a la conversación con la IA sin enmascarar, tal cual
  • 3Min API no detecta datos personales dentro de JSON libre, así que no incluya en los resultados más datos personales de los necesarios

Solución de problemas

  • Todas las tareas fallan de inmediato: revise Entrega → Última respuesta en el detalle de la ejecución. Un 401 suele indicar que se pegó la clave de respuesta en lugar del secreto de firma, o que se eliminó el secreto anterior justo después de una rotación
  • Una tarea sigue en working: el worker devuelve 2xx pero nunca informa. Revise en los registros del worker los códigos de respuesta de la API de informe de estado
  • Los informes reciben 401: asegúrese de usar la clave de respuesta que empieza por tm_task_ y no una clave anterior a una regeneración
  • Los informes reciben 409: la tarea ya terminó o fue cancelada. No hace falta enviar más
  • Los informes reciben 413: el cuerpo supera 100 KB. Reduzca result y reenvíe
  • Enviar la misma solicitud no crea una tarea nueva: el mismo input en menos de 2 minutos devuelve la tarea existente. Añada algo como una fecha a input para distinguirlas