Routines and groups
Read which routines your team of Mets can learn, which groups people work in with their Mets, and where each task came from.
Your team of Mets does not just answer: it learns routines. A routine is a business process —create and post on your social media, advertise what you sell, follow up with your customers— that the team repeats every time: three steps and, at each step, two paths to choose from. Those routines run in groups, where the business's people and their Mets talk and work together (in Met, "Conversaciones" → "Grupos"). And every time a routine runs, it leaves a task.
With the API you read all three. Starting a routine, choosing a path, creating a group or adding someone is done in Met.
Before you start
Your key needs routines:read for routines and groups:read for groups. Keys issued before they existed do not carry them: add them in Ajustes › Desarrolladores or issue a new one. They also work with a test key (met_test_), because they only read. The tasks' origin field asks for nothing new: it comes with tasks:read, like the rest of the task.
The business's routines
import { Met } from '@meteor.ia/sdk';
const met = new Met(process.env.METEOR_API_KEY!);
const { data: routines } = await met.routines.list();
for (const r of routines) {
console.log(r.id, '—', r.name);
for (const step of r.steps) {
console.log(` ${step.number}. ${step.title}:`, step.paths.map((c) => `${c.title} (${c.done_by})`).join(' / '));
}
}
Each routine carries:
id,nameandachieves(what it achieves, in one or two sentences).steps: the steps, in order, with the question the Met asks the person at each one.pathsat each step: the paths to choose from, withdone_by—metis done by a Met (met_namesays which),personis done by the person,automaticis done by Meteor with no AI—.
Why the paths say who does them. A routine spends AI only where it is needed: choosing a path is a button and calls no model, the assignment to the Met is put together from a template, each AI step is a single delegation to a single Met, its output is validated before it is shown, whatever publishes or spends ad budget waits for a person's approval, and when it closes you see the Energy of the whole run. It is the same pattern you can build with your own flows: it is explained in Architecture: when a flow, when a Met.
Only the routines available in your business come out. Some open up gradually: while one is not available to you, it does not appear in the list and met.routines.retrieve(id) answers 404.
Ids are text, not a closed list. Today the open routines are redes, anuncios and seguimiento (and there are others in pilot), but the product adds routines and paths every week. Treat an id you do not know as one more, not as an error.
Groups
for await (const g of met.groups.iterate()) {
const people = g.members.people.map((p) => `${p.name} (${p.role})`);
const mets = g.members.mets.map((m) => (m.main ? `${m.name} ★` : m.name));
console.log(g.title, '·', g.purpose ?? 'no purpose', '·', people.join(', '), '·', mets.join(', '));
}
Each group carries what it is for (purpose), the routine that runs in it (routine, the id of a routine, or null) and its members, separated:
members.people: the people, with theirrole—ownercreated it,approverapproves what the group's Mets leave waiting,membereveryone else—.members.mets: the Mets. The business's main Met comes first, withmain: true; a people-only group does not carry it.
You only see your groups. The list carries the groups you are part of —or that the person your key represents is part of—. Other people's groups are not visible, not even with an administrator key: it is the same rule as conversations.
A two-person conversation is not a group. If only two people are in it, with no purpose or routine, the app shows it as the conversation with that person, and it does not appear here: not in the list nor in the detail (404). Giving it a purpose, adding someone else or a Met is enough to make it a group.
The list is always { data, has_more, next_cursor }, from newest group to oldest: pass next_cursor in starting_after until has_more is false, or use iterate().
Where a task came from
Each task adds origin:
const task = await met.tasks.retrieve('b3e1c0d2-4f5a-4e6b-8c7d-9a0b1c2d3e4f');
if (task.origin?.type === 'routine') {
console.log('Left by routine', task.origin.routine, 'in group', task.origin.group_id);
}
origin.type | What it means |
|---|---|
routine | A routine's run (or its weekly schedule). routine says which. |
group | A Met left it while working in a group. |
conversation | A Met left it in a conversation with Mets. |
group_id and conversation_id only arrive if you can see that group or that conversation; if not, they arrive as null and the rest of the origin stays. origin: null means the task does not keep where it came from: a person, the API or an automation created it. If it could not be worked out in a response, the field does not come. type also grows: treat a value you do not know as "another origin".
From the MCP connector
The connector has met_list_routines, met_list_groups and met_get_group. Their scopes are not requested on their own when you connect Claude: an app that wants them has to ask for routines:read and groups:read when it registers.
What you cannot do (yet)
- Start a routine, choose a path or schedule it.
- Create a group, add or remove someone.
- Read a group's messages.
All of that stays in Met.