En esta sección
Guías / Cuánto cuesta cada llamada

Cuánto cuesta cada llamada

El costo en Energía de cada ejecución, de un Run, de un Met o de una línea de WhatsApp — con filtros, totales y el consumo agrupado por línea.

Actualizada el Ver .md

Cada vez que un Met trabaja —responde un WhatsApp, corre un Run que lanzaste por API, ejecuta una automatización— se debita Energía de tu saldo. Esta guía muestra cómo saber cuánto costó cada llamada y cómo sumarlo por Run, por Met o por línea de WhatsApp.

Todo lo de esta guía es de solo lectura y pide el scope billing:read (el costo de un Run, runs:read). Los montos son la Energía que se te debitó, en USD: lo mismo que ves en el panel.

Cada ejecución, con su origen

GET /billing/executions lista las ejecuciones de tu workspace, de la más reciente a la más vieja. Cada una dice cuánto costó y de dónde vino:

CampoQué dice
cost_final_usdLa Energía que se debitó por esta ejecución, en USD.
met_id, met_nameEl Met que trabajó.
model_displayEl nivel de inteligencia que usó (Ágil, Brillante, Genio…).
run_idEl Run de la API que la causó (run_…), o null si no vino de un Run.
channelPor dónde llegó el trabajo: whatsapp, instagram, messenger, widget, panel, api…
whatsapp_lineLa línea de WhatsApp: { id, number_masked }, o null (ver qué lleva línea).

whatsapp_line.id es el phone_number_id de Meta, el mismo valor que usas en sender_line_id y que devuelve GET /channels/{channelId}/whatsapp/lines. El número va enmascarado (+57 300 ••• 4567): alcanza para reconocer la línea sin copiar el número completo en cada fila.

import Met from '@meteor.ia/sdk';

const met = new Met(process.env.MET_API_KEY, { workspaceId: 7 });

const pagina = await met.billing.executions({ limit: 20 });
for (const e of pagina.rows) {
  console.log(e.executed_at, e.met_name, e.channel, e.whatsapp_line?.number_masked ?? '-', e.cost_final_usd);
}
console.log('Total del filtro:', pagina.totals?.cost_final_usd);
import os
from meteor_ia import Met

met = Met(os.environ["MET_API_KEY"], workspace_id=7)

pagina = met.billing.executions(limit=20)
for e in pagina["rows"]:
    linea = (e.get("whatsapp_line") or {}).get("number_masked", "-")
    print(e["executed_at"], e["met_name"], e["channel"], linea, e["cost_final_usd"])
print("Total del filtro:", (pagina.get("totals") or {}).get("cost_final_usd"))
curl "https://api.met.meteor.com.co/api/v1/billing/executions?limit=20" \
  -H "Authorization: Bearer $MET_API_KEY"

La respuesta es una página { rows, total, limit, offset, totals }. El máximo es 100 por página: un limit mayor se ajusta a 100 sin error, y el limit de la respuesta es el que se aplicó. totals suma todas las ejecuciones que cumplen el filtro, no solo las de la página.

Lo que nunca sale: el costo del proveedor, el margen ni el nombre del modelo. Tampoco el contacto ni la conversación: para saber cuánto se gastó por contacto está GET /billing/consumption?by=contact.

Filtrar por Met, línea o Run

Tres filtros responden «¿cuánto me costó esto?»:

FiltroEjemploQué trae
met_idmet_id=41207Solo lo que hizo ese Met.
line_idline_id=1210946622112871Solo lo que entró por esa línea de WhatsApp.
run_idrun_id=run_01JB8ZQ4…Solo lo que causó ese Run.

Se combinan entre sí y con from, to, type, costMin y costMax. totals respeta los mismos filtros, así que con una sola llamada tienes el total:

// ¿Cuánto costó la línea de ventas en octubre?
const octubre = await met.billing.executions({
  line_id: '1210946622112871',
  from: '2026-10-01T00:00:00Z',
  to: '2026-10-31T23:59:59Z',
  limit: 1,
});
console.log(octubre.total, 'ejecuciones ·', octubre.totals?.cost_final_usd, 'USD');
octubre = met.billing.executions(
    line_id="1210946622112871",
    from_="2026-10-01T00:00:00Z",
    to="2026-10-31T23:59:59Z",
    limit=1,
)
print(octubre["total"], "ejecuciones ·", octubre["totals"]["cost_final_usd"], "USD")
curl "https://api.met.meteor.com.co/api/v1/billing/executions?line_id=1210946622112871&from=2026-10-01T00:00:00Z&to=2026-10-31T23:59:59Z&limit=1" \
  -H "Authorization: Bearer $MET_API_KEY"

Un filtro mal escrito responde 400, con el parámetro en param (invalid_met_id, invalid_line_id, invalid_run_id): nunca se ignora en silencio, porque devolver todas las ejecuciones te haría creer que esa línea gastó lo de toda la cuenta. line_id es el phone_number_id (solo dígitos), no el número de teléfono.

Para recorrer todas las ejecuciones de un filtro sin manejar el offset:

let suma = 0;
for await (const e of met.billing.iterateExecutions({ met_id: 41207, from: '2026-10-01T00:00:00Z' })) {
  suma += e.cost_final_usd;
}
suma = sum(e["cost_final_usd"] for e in met.billing.iterate_executions(met_id=41207, from_="2026-10-01T00:00:00Z"))

Lo que costó un Run

GET /runs/{id} trae cost_final_usd: lo que costó ese Run, sumando la Energía de todas las ejecuciones que causó (las mismas de GET /billing/executions?run_id=…).

const run = await met.runs.create({ input: 'Resume los leads de hoy' });
const detalle = await met.runs.retrieve(run.id);
console.log(detalle.status, detalle.cost_final_usd);
run = met.runs.create("Resume los leads de hoy")
detalle = met.runs.retrieve(run["id"])
print(detalle["status"], detalle.get("cost_final_usd"))
curl https://api.met.meteor.com.co/api/v1/runs/run_01JB8ZQ4W8X3K7M2N5P6R9T0VA \
  -H "Authorization: Bearer $MET_API_KEY"

Tres cosas para leerlo bien:

energy, que ya venía en el detalle, suma la conversación del Run: si reusaste conversation_id, incluye otros Runs. Para el costo de uno solo, usa cost_final_usd.

Consumo agrupado por línea

GET /billing/consumption?by=line reparte la Energía de un período por línea de WhatsApp, de la que más gastó a la que menos:

const porLinea = await met.billing.consumption({ by: 'line', from: '2026-10-01T00:00:00Z' });
for (const l of porLinea) {
  console.log(l.whatsapp_line?.number_masked, l.executions, l.energia_usd);
}
por_linea = met.billing.consumption(by="line", **{"from": "2026-10-01T00:00:00Z"})
for l in por_linea:
    print(l["whatsapp_line"]["number_masked"], l["executions"], l["energia_usd"])
curl "https://api.met.meteor.com.co/api/v1/billing/consumption?by=line&from=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $MET_API_KEY"

Cada fila trae energia_usd, executions, time_saved_minutes y whatsapp_line. Usa whatsapp_line.id para bajar al detalle con line_id; dim_key es el id interno de la línea en Met (null si la línea ya no está conectada a tu cuenta). Si una línea se desconectó, su consumo sigue apareciendo, con number_masked en null.

El mismo endpoint agrupa por met (por defecto), contact, actor (miembro del equipo) y conversation.

Qué lleva línea y desde cuándo

Met registra el Run y la línea de cada ejecución desde la versión 3.51.0 del contrato. Lo anterior no se reconstruye: esas ejecuciones traen run_id y whatsapp_line en null y no cuentan en line_id, run_id ni by=line. En ejecuciones viejas, channel puede decir whatsapp para cualquier canal. El costo (cost_final_usd) sí está completo desde siempre.

Llevan línea:

No llevan línea, aunque el gasto sea de WhatsApp:

Por eso whatsapp_line puede ser null en un gasto de WhatsApp, y la suma de by=line puede ser menor que lo que gastó el canal entero. Para el total del canal, suma cost_final_usd de las ejecuciones con channel igual a whatsapp.