API de Talkyria v1
Integra Talkyria con tu plataforma para automatizar llamadas de confirmacion de pedidos COD. Consulta ordenes, dispara llamadas, recibe webhooks con el resultado.
Introduccion
Base URL
https://api.talkyria.com/api/v1
Autenticacion
Bearer token
Rate limit
60 req/min
Formato
JSON
/orders/:id— Consultar orden con llamadas/orders?phone=X— Buscar ordenes/calls/trigger— Disparar llamada/orders/:id/status— Actualizar estado logisticoAutenticacion
Todas las requests requieren un API key en el header Authorization. Genera tu key en app.talkyria.com → Vinculacion → API.
curl -H "Authorization: Bearer tk_live_abc123def456..." \ https://api.talkyria.com/api/v1/orders
Ordenes
Consultar orden
/api/v1/orders/:idRetorna la orden con todas sus llamadas asociadas.
// Response
{
"id": "cmmut6in0009...",
"shopifyOrderId": "6789012345",
"externalId": "chateapro_123",
"orderNumber": "#1234",
"status": "confirmed",
"customer": {
"name": "Juan Perez",
"phone": "+573001234567",
"city": "Bogota"
},
"products": "Samsung Galaxy S25 x1",
"totalPrice": 85600,
"address": {
"address1": "Calle 45 #23-12",
"city": "Bogota",
"province": "Cundinamarca"
},
"addressFinal": "Calle 45 #23-12, Apto 301",
"callAttempts": 2,
"confirmedAt": "2026-03-17T21:00:00Z",
"calls": [
{
"id": "call_log_id",
"callType": "confirmation",
"outcome": "confirmed",
"durationSeconds": 87,
"recordingUrl": "https://...",
"transcript": "Hola, hablo con Juan?...",
"summary": "El agente confirmo el pedido...",
"createdAt": "2026-03-17T20:58:00Z"
}
]
}Buscar ordenes
/api/v1/ordersBusca ordenes por telefono, ID externo, o ID de Shopify.
| Parametro | Tipo | Descripcion |
|---|---|---|
| phone | string | Telefono E.164 (+573001234567) |
| externalId | string | ID de tu plataforma |
| shopifyOrderId | string | ID de orden Shopify |
| limit | number | Max resultados (default 50, max 100) |
| offset | number | Paginacion |
Disparar llamada
/api/v1/calls/triggerCrea una orden y encola una llamada de confirmacion. Usa los mismos billing guards, working hours y deduplicacion que las llamadas de Shopify.
// Request
curl -X POST \
-H "Authorization: Bearer tk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"source": "chateapro",
"callType": "confirmation",
"customer": {
"name": "Juan Perez",
"phone": "+573001234567",
"ns": "contact_123",
"city": "Bogota"
},
"address": {
"address1": "Calle 45 #23-12",
"address2": "Apto 301",
"city": "Bogota",
"province": "Cundinamarca"
},
"order": {
"externalId": "CP-12345",
"products": "Samsung Galaxy S25 x1",
"totalPrice": 85600,
"currency": "COP"
}
}' \
https://app.talkyria.com/api/v1/calls/trigger
// Response (200)
{
"success": true,
"orderId": "cmmxyz...",
"callId": "cmmyyy...",
"message": "Llamada encolada exitosamente",
"estimatedCallTime": "< 30 segundos"
}| Campo | Requerido | Descripcion |
|---|---|---|
| source | Si | Origen: "chateapro", "dropi", "api" |
| callType | Si | "confirmation" | "novelty" | "office" |
| customer.name | Si | Nombre completo del cliente |
| customer.phone | Si | Telefono E.164 (+573001234567) |
| customer.ns | No | NS del contacto (ChateaPro) — se devuelve en webhook |
| order.externalId | Si | ID unico del pedido en tu plataforma |
| order.products | Si | Productos como texto: "Gel x1" |
| order.totalPrice | Si | Valor total (numero): 72990 |
| order.currency | Si | Moneda: COP, MXN, USD |
| address.address1 | Si | Direccion principal |
| address.city | Si | Ciudad de entrega |
| products | Si | Array de productos |
| totalPrice | Si | Total como string |
| shippingAddress | No | Direccion de envio |
| metadata | No | Datos extra (JSON libre) |
Actualizar estado logistico
/api/v1/orders/:id/statuscurl -X PATCH \
-H "Authorization: Bearer tk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "logisticStatus": "shipped", "trackingNumber": "CR123456789", "carrier": "InterRapidisimo" }' \
https://api.talkyria.com/api/v1/orders/cmmxyz.../status| logisticStatus | Descripcion |
|---|---|
| processing | En preparacion |
| shipped | Despachado |
| in_transit | En transito |
| delivered | Entregado |
| returned | Devuelto |
| failed_delivery | Entrega fallida |
Webhooks
Recibe un POST cuando Talkyria determina el resultado final de una llamada. Configura tu webhook en app.talkyria.com → Vinculacion → API.
Evento: call.outcome_final
Se dispara UNA vez por orden cuando el outcome final se determina. No se envia en reintentos intermedios.
// Payload enviado a tu webhook URL
{
"event": "call.outcome_final",
"timestamp": "2026-03-17T21:00:00Z",
"order": {
"id": "cmmut6in...",
"externalId": "chateapro_123",
"orderNumber": "#1234",
"status": "confirmed",
"products": "Samsung Galaxy S25 x1",
"totalPrice": "85600",
"customer": { "name": "Juan", "phone": "+573001234567" },
"address": { "address1": "Calle 45 #23-12", "city": "Bogota" }
},
"call": {
"id": "call_log_id",
"outcomeFinal": "confirmed",
"durationSeconds": 87,
"recordingUrl": "https://...",
"transcript": "...",
"summary": "..."
},
"shop": { "domain": "mitienda.myshopify.com", "country": "CO" }
}Verificar firma HMAC
Cada webhook incluye X-Talkyria-Signature: sha256=xxx. Verifica la firma con tu secret.
Node.js
const crypto = require("crypto");
function verifySignature(body, signature, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Python
import hmac, hashlib
def verify_signature(body: str, signature: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Reintentos: 3 intentos con backoff (1 min, 5 min, 30 min).
Outcomes
| Outcome | Descripcion |
|---|---|
| confirmed | Pedido confirmado por el cliente |
| cancelled | Pedido cancelado por el cliente |
| no_answer | Cliente no contesto despues de todos los reintentos |
| novedad | Requiere revision manual (direccion incorrecta, etc.) |
| recovered | Carrito abandonado recuperado |
| not_recovered | Carrito abandonado no recuperado |
Errores
| Codigo | Descripcion |
|---|---|
| 401 | API key invalida o faltante |
| 400 | Datos invalidos (ver mensaje de error) |
| 404 | Orden no encontrada |
| 405 | Metodo HTTP no permitido |
| 429 | Rate limit excedido (60 req/min) |
| 500 | Error interno del servidor |
// Error response format
{ "error": "Descripcion del error" }Ejemplos completos
JavaScript (fetch)
const API_KEY = "tk_live_abc123...";
const BASE = "https://api.talkyria.com/api/v1";
// Disparar llamada
const res = await fetch(`${BASE}/calls/trigger`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
externalId: "mi_orden_123",
customer: { name: "Juan", phone: "+573001234567" },
products: [{ name: "Producto X", quantity: 1 }],
totalPrice: "85600",
}),
});
const data = await res.json();
console.log(data.orderId, data.status);
// Consultar resultado
const order = await fetch(`${BASE}/orders/${data.orderId}`, {
headers: { "Authorization": `Bearer ${API_KEY}` },
}).then(r => r.json());
console.log(order.calls[0]?.outcome);Python (requests)
import requests
API_KEY = "tk_live_abc123..."
BASE = "https://api.talkyria.com/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}
# Disparar llamada
res = requests.post(f"{BASE}/calls/trigger", headers=headers, json={
"externalId": "mi_orden_123",
"customer": {"name": "Juan", "phone": "+573001234567"},
"products": [{"name": "Producto X", "quantity": 1}],
"totalPrice": "85600",
})
data = res.json()
print(data["orderId"], data["status"])
# Consultar resultado
order = requests.get(f"{BASE}/orders/{data['orderId']}", headers=headers).json()
print(order["calls"][0]["outcome"])Talkyria API v1 — Confirma pedidos COD con IA
Preguntas? contacto@talkyria.com