En esta sección
Partners API · met.partner.*

La API propia de Partners

Además de operar los workspaces de sus clientes (la superficie de meteorus, compartida con las keys de workspace), una key de partner accede a su propio negocio: oportunidades, proyectos de implementación, tickets de soporte, clientes atribuidos, comisiones y payouts. En el SDK vive bajo el namespace met.partner.*.

Exclusiva de keys de partner. Ningún scope partner:* se puede emitir en una key de workspace, y el servidor lo re-verifica en cada request. Una key de workspace que intente estas rutas recibe 403.

Escribes oportunidades, proyectos y tickets, con su hilo de conversación y adjuntos. Los dominios financieros —comisiones y payouts— se mantienen solo lectura a propósito: crearlos o editarlos desde afuera son procesos con reconciliación humana.

Referencia interactiva de met.partner.* (generada del contrato OpenAPI, con try-it).

Autenticación

Usas la misma key met_* que para el resto del SDK. El SDK enruta automáticamente las llamadas met.partner.* al backend de partners — no tienes que configurar nada.

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

const met = new Met(process.env.MET_API_KEY!);

// El namespace partner usa el host de partners de forma transparente.
const clientes = await met.partner.clients.list();

Si operas contra un entorno distinto (staging), puedes apuntar el host de partners a mano:

const met = new Met(process.env.MET_API_KEY!, {
  partnerBaseUrl: 'https://api.partners.staging.meteor.com.co',
});

Clientes

Lista los clientes (workspaces) atribuidos a tu organización, con su estado, plan y consumo — lo mismo que ves en tu panel. Paginado y con búsqueda.

const page = await met.partner.clients.list({
  page: 1,
  limit: 50,
  search: 'acme',   // opcional: filtra por nombre
});
// → { items: [{ workspace_id, status, plan_name, price_usd,
//               commission_usd, energy_usd, ... }], pagination }

Cada cliente incluye su plan y estado en Met, la tarifa de comisión del originador y el consumo de Energía del periodo. Nunca verás datos de clientes de otro partner: el tenancy se aplica por el dueño de la key.

Leads

Lista tus oportunidades (leads) — contacto, empresa, industria y estado, igual que en tu CRM de partner. La salida es curada: nunca expone internals de asignación, atribución ni notas del staff. Excluye las convertidas por defecto. Para crearlas y moverlas, mira Escritura.

const leads = await met.partner.leads.list({
  status: 'NEW',   // opcional: NEW · ASSIGNED · ACCEPTED · REJECTED · CONVERTED
  limit: 100,
});
// → { data: [{ id, status, stage, contact_name, contact_email,
//              company_name, vertical, zone, plan_target, tags,
//              partner_name, created_at }], has_more }

const lead = await met.partner.leads.get(id);   // detalle de una propia

Comisiones

Lista tus comisiones. Filtra por estado (PENDING, APPROVED, PAID, CANCELLED).

const comisiones = await met.partner.commissions.list({
  status: 'PAID',
  page: 1,
  limit: 50,
});

Payouts

Lista tus payouts (liquidaciones) y consulta el resumen de tu wallet.

const payouts = await met.partner.payouts.list({ page: 1, limit: 50 });

const wallet = await met.partner.payouts.summary();
// → { pending, approved, paid, scheduled, next_payout, ... }

Proyectos

Lista los proyectos de implementación donde tu organización es originadora o implementadora — fase, estado, precio, deadline y responsables. Salida curada: sin los ids internos de partner ni la mecánica del tablero. Para crearlos y avanzarlos, mira Escritura.

const proyectos = await met.partner.projects.list({ limit: 100 });
// → { data: [{ id, title, phase, status, price_amount, price_status,
//              deadline_at, workspace_id, originator_name,
//              implementer_name, created_at }], has_more }

const proyecto = await met.partner.projects.get(id);   // detalle de uno propio

Escritura

Si operas tu propio portal, puedes registrar y mover oportunidades y proyectos desde ahí. Lo que creas por API es tuyo desde el primer momento: una oportunidad nace aceptada y a tu nombre, sin pasar por el pool de Meteor.

Oportunidades

const lead = await met.partner.leads.create({
  company_name: 'Acme',
  contact_name: 'Ada Lovelace',
  contact_email: 'ada@acme.co',
  vertical: 'retail',
});

await met.partner.leads.update(lead.id, { notes: 'Primera llamada hecha' });
await met.partner.leads.move(lead.id, 'CONTACTADO');
await met.partner.leads.delete(lead.id);          // solo las tuyas

Las etapas del pipeline son NUEVO, CONTACTADO, CALIFICADO, PROPUESTA, GANADO y PERDIDO.

Proyectos, tareas e hitos

const proyecto = await met.partner.projects.create({
  title: 'Implementación Acme',
  workspace_id: 42,          // debe ser un cliente atribuido a ti
  deadline_at: '2026-09-01T00:00:00Z',
});

await met.partner.projects.tasks.create(proyecto.id, { title: 'Kickoff' });
await met.partner.projects.addMilestone(proyecto.id, 'Alcance firmado');
await met.partner.projects.advancePhase(proyecto.id);

Tres cosas se gestionan solo desde el portal de Meteor, porque mueven dinero o atribución: proponer y aprobar el precio, asignar implementador, y convertir una oportunidad en cliente. advancePhase() las respeta — falla si el precio no está aprobado, si quedan hitos pendientes, o si el implementador no aceptó su oferta.

Los POST aceptan Idempotency-Key; el SDK genera uno por request, así que un reintento por timeout no te deja dos oportunidades iguales. Un proyecto creado por API es siempre de cliente: los proyectos internos son trabajo del equipo de Meteor.

Tickets de soporte

Con workspace_id abres el ticket a nombre de un cliente de tu cartera y ese cliente lo ve en su Met; sin él es un ticket tuyo hacia Meteor. Es la pieza que te deja poner una mesa de ayuda de primer nivel en tu propio portal.

const motivos = await met.partner.support.reasons();

const ticket = await met.partner.support.create({
  subject: 'No llega el mensaje de WhatsApp',
  description: 'Desde ayer 3pm no salen las notificaciones.',
  workspace_id: 42,        // cliente de tu cartera; omitir = ticket propio
  reason_id: motivos[0].id,
});

await met.partner.support.reply(ticket.id, 'Ya revisamos la plantilla.');
await met.partner.support.updateStatus(ticket.id, 'resolved');

Estados: new, in_progress, waiting_client, resolved y closed. Las notas internas del equipo de Meteor nunca salen por esta superficie, y los tickets de prioridad crítica los gestiona solo Meteor.

Hilo de la relación y adjuntos

Una oportunidad y el proyecto en que se convierte no son dos cosas para nosotros: son la misma relación en dos momentos. Por eso la conversación es una sola — lo que escribiste mientras vendías sigue ahí cuando estás implementando, sin copiar nada.

// El hilo de la oportunidad
await met.partner.leads.comments.create(lead.id, { body: 'Pidieron demo el viernes.' });
const hilo = await met.partner.leads.comments.list(lead.id);

// Adjuntar un archivo: primero se sube, después se manda su metadata
const adjunto = await met.partner.leads.comments.upload(lead.id, archivo, {
  filename: 'propuesta.pdf',
  contentType: 'application/pdf',
});
await met.partner.leads.comments.create(lead.id, {
  body: 'Adjunto la propuesta firmada.',
  attachments: [adjunto],
});

// Lo mismo, sobre un proyecto
await met.partner.projects.comments.create(proyecto.id, { body: 'Kickoff hecho.' });

El hilo no tiene scope propio: monta el de su dominio. Leerlo pide partner:leads:read o partner:projects:read; escribirlo, el :write correspondiente. Quien puede ver la oportunidad ve su conversación, y no antes. Solo borras los mensajes que escribiste con esa key.

Los adjuntos van a un bucket privado y se sirven firmados. La URL que te devuelve el hilo caduca: para volver a abrir un archivo, pide una nueva con attachments.signedUrl(storage_path) — el campo estable es storage_path, no la URL. El tope por archivo es 25 MB, y las menciones (@persona) no se pueden mandar por API: dependen de ids internos del equipo.

Los adjuntos de un ticket van por su propia vía (met.partner.support); el hilo del cliente —el que no cuelga ni de una oportunidad ni de un proyecto— todavía no se expone.

Scopes

Cada key de partner porta solo los scopes que le asignes al crearla.

RecursoMétodo del SDKScope
Clientes atribuidosmet.partner.clients.list()partner:clients:read
Oportunidades (leads)met.partner.leads.list() · .get()partner:leads:read
Oportunidades · escritura.create() · .update() · .move() · .delete()partner:leads:write
Comisionesmet.partner.commissions.list()partner:commissions:read
Payoutsmet.partner.payouts.list() · .summary()partner:payouts:read
Proyectosmet.partner.projects.list() · .get() · .tasks.list()partner:projects:read
Proyectos · escritura.create() · .update() · .advancePhase() · .tasks.* · hitospartner:projects:write
Ticketsmet.partner.support.list() · .get() · .reasons()partner:support:read
Tickets · escritura.create() · .reply() · .updateStatus()partner:support:write
Hilo · lectura.leads.comments.list() · .projects.comments.list()el :read de su dominio
Hilo · escritura.comments.create() · .upload() · .delete()el :write de su dominio

Son 37 operaciones en total. La referencia interactiva las lista todas, generadas del mismo contrato que sirve el servidor.

Próximamente

Los dominios financieros (comisiones, payouts) se mantienen read-only por diseño: su escritura pasa por reconciliación humana.