Run Mets (Runs)
Run your workspace's Met from the API, with optional memory, and read the result.
A Run is one execution of your workspace's Met over an input. It is the core of agentic infrastructure as a service: the same Met that answers in the chat, now triggered by your code.
A basic run
const run = await met.runs.create({ input: 'Summarize the leads from today' });
console.log(run.status); // 'completed'
console.log(run.output); // what the Met producedrun = met.runs.create("Summarize the leads from today")
print(run["status"]) # 'completed'
print(run["output"]) # what the Met producedcurl -X POST https://api.met.meteor.com.co/api/v1/workspaces/7/runs \
-H "Authorization: Bearer $MET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Summarize the leads from today"}'The request is POST /workspaces/:id/runs. The response is a run resource with an opaque id (run_…), status, output, livemode and metadata.
Pick the Met (deterministic bind)
Pass met — the name or id of a Met in the workspace — to run that Met directly, with its Functions and tools, skipping the orchestrator:
await met.runs.create({ met: 'Valeria', input: 'How many leads did I close?' });met.runs.create("How many leads did I close?", met="Valeria")Names resolve case-insensitively: exact match first, then prefix. If you omit met, the workspace orchestrator routes to the right Met, exactly as it does in the chat.
Routing is AI work too: without met, the main Met reads the request and can delegate it to another Met, and each one is an execution with its own cost. If you already know which Met has to answer, pass it: the Run goes straight to that Met, without the orchestrator's round trip.
Memory: conversations
Without a conversation_id, the run happens in an ephemeral conversation with no prior memory. To give it continuity, pass an existing conversation:
await met.runs.create({ input: 'And last month?', conversation_id: 1234 });
With a conversation_id, the first met you send becomes the conversation default: later runs that omit met use that same Met. An explicit met always wins over the default.
Vision: images and files
Pass attachments in attachments so the Met can see an image or read a document, with automatic OCR for text inside an image:
await met.runs.create({
met: 'Valeria',
input: 'Does the installed sign match the approved design?',
attachments: [{ url: 'https://…/photo.jpg', kind: 'image' }],
});
Each attachment is { url, mime_type?, name?, kind? }, where kind is image · document · audio · video · file. A bare URL inside input is not seen — it has to go in attachments.
Isolated Run: no tools, no context
To extract or classify something from a text or a document, you do not need a Met with all its tools. With tool_policy: "none", the Run works only with the input, its attachments and the instructions of the Met you pick:
const caps = await met.runs.capabilities();
if (caps.tool_policies.includes('none')) {
const run = await met.runs.create({
met: 'Extractor',
tool_policy: 'none',
input: 'Return the tax ID and the total of this invoice as JSON: ...',
});
if (run.status === 'completed') console.log(run.output);
}caps = met.runs.capabilities()
if "none" in caps["tool_policies"]:
run = met.runs.create(
"Return the tax ID and the total of this invoice as JSON: ...",
met="Extractor",
tool_policy="none",
)
if run["status"] == "completed":
print(run["output"])curl -X POST https://api.met.meteor.com.co/api/v1/workspaces/7/runs \
-H "Authorization: Bearer $MET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"met":"Extractor","tool_policy":"none","input":"Return the tax ID and the total of this invoice as JSON: ..."}'What changes compared with a normal Run:
- It loads no skills, integrations, previous history, variables or dynamic workspace context. If the model tries to use a tool, the run stops without dispatching it.
- It requires
met. Without a valid Met in the workspace it answers400withtool_policy_requires_met: it never falls back to the orchestrator. - Attachments: PDFs and images (
native_attachment_kinds) via a signed HTTPS URL from Meteor's storage. Audio and documents that need conversion are rejected before the Run is created: paste their text as theinput. - The Run keeps
metadata.tool_policy: "none". Checkstatus: "completed"before usingoutput.
GET /workspaces/{workspaceId}/runs/capabilities (met.runs.capabilities()) tells you whether the policy is available; it needs runs:execute and spends no Energy. The isolated Run is billed like any Run, but without the context it did not need. When it beats a flow or a full Met: Architecture: when a flow, when a Met.
Read runs
const run = await met.runs.retrieve('run_01J8…'); // status + output
for await (const r of met.runs.iterate()) { // full history
console.log(r.id, r.status);
}run = met.runs.retrieve("run_01J8…") # status + output
for r in met.runs.iterate(): # full history
print(r["id"], r["status"])iterate() walks every page for you — see Errors and pagination.
If you need to wait for a run to finish, use met.runs.wait(id) (in Python, met.runs.wait(run_id)) instead of calling retrieve() in a loop: it asks less and less often, waits for whatever Retry-After says if it gets a 429, and gives up after 5 minutes with MetWaitTimeoutError. Better yet, subscribe to the run.completed and run.failed webhooks and let us tell you.
Cost
Every run debits Energy through the usual ledger, marked execution_type='api' and attributed to the key. In your dashboard, API usage is reported separately from the internal chat.
Want the result as it is generated? See the Streaming guide.