Melso Agents is available only internally or by private invitation. Agents-specific features require existing access. For the autónomo fiscal service, see Get started.
{id} accepts a Task UUID or identifier on routes that accept identifiers. Use UUIDs for /input, conversation paging and queue routes. Task status summarizes lifecycle, execution and attention. See the Task, Run and fiscal state tables; a failed Run is an attention reason, not a Task status.
input is the opening message. description is a separately edited summary. In an Agents company, supply both input and execution to start a Run. In an autónomo or empresa company, input can start a Run using the company’s default execution. To save without running in either case, omit execution and set start: false. The top-level start flag controls default execution; it supplies no funding settings and does not cancel an explicit execution object. Read run_id from the creation response only when a Run was created; a client_request_id replay returns the same run_id. Follow-ups go to POST /api/tasks/{id}/input, which accepts its own client_request_id with the same retry contract.
Persistent Task watches
Watches resume a Melso-managed Task conversation when another accessible Task publishes an event. The subscriber is inferred from the current Run credential; the path identifies the watched Task. Parent links only organize Tasks. External OAuth clients have no durable subscribing conversation and cannot use these routes; use Webhooks for external notifications. Registration returns immediately. End the current agent turn after it succeeds. Watches persist across Runs until explicitly removed or the subscriber closes. Notifications wait while the subscriber is busy, paused, or waiting for human input; dispatch revalidates access and execution authority. No acknowledgment is required. Isolated Task Runs cannot manage watches.Direct browser uploads (up to 1 GiB)
On S3-compatible storage or a configured GCS mounted bucket, browser clients upload files directly to the object bucket. CallPOST /api/uploads/direct with JSON filename, content_type, size_bytes, and optional task_id, message_id, and run_id. Send company context as usual. The response has id, upload_url, and headers. PUT the raw file bytes to that URL with the returned headers, then call POST /api/uploads/direct/{id}/complete with the same Melso credentials and company context. Completion verifies the object size and current access before returning an AttachmentResponse. Files are invisible until completion. S3 uses a one-hour signed PUT URL; GCS uses a resumable session URL that acts as a bearer capability.
The browser sets Content-Length from the file automatically. The S3 signature binds it to the declared size; GCS receives the declared size when the resumable session starts. Temporary objects are copied to a permanent key at completion so the upload URL cannot replace a completed attachment. Expired temporary objects are reclaimed on later upload starts.
Use direct upload for larger files, up to 1 GiB, when storage supports it. For smaller files, or when direct upload is unavailable, use the multipart upload route in the Files reference, keeping the complete request under 100 MiB. The two routes have different size limits.
Isolated Tasks
Setisolated: true when creating a Task that one Melso account runs on behalf of someone else, such as an integration that turns each of its end users’ conversations into a Task. We recommend it whenever a single account creates Tasks for many end users. The flag is fixed at creation: PUT /api/tasks/{id} rejects it, and every TaskResponse reports it.
For an isolated Task, Melso guarantees:
- Other Runs cannot see it. A Run of any other Task gets 404 on every route that addresses the isolated Task, and the Task never appears in its lists, search, children or child progress.
- Its own Runs stay inside it. They can read the Task, its messages and attachments, upload attachments to it, ask the human (interactions), and use the Area’s connected apps and repository checkout. Any other Task is a 404, and lists and search return at most this Task. Everything else returns 403 with
"code": "isolated_task_scope": creating Tasks, including child Tasks; changing this Task (fields, status, metadata, outputs, messages, follow-up input); reading or changing its Task MCP servers; and changing the company (Areas, automations, Library knowledge, artifacts, skills, secrets and secret requests, memories, connected-app management, settings, MCP servers, GitHub). - No duplicate matching. The duplicate-title check never compares an isolated Task with other Tasks.
- Pull requests follow the Run’s branch. A pull request links to, and on merge completes, an isolated Task only when it comes from that Task’s own Run branch (
agent/<name>/<first 8 characters of the Task ID>) in the same repository. A pull request from that branch never links, reviews or completes another Task, and an isolated Task never gets a Melso review child Task.
isolated: true too: an ordinary child stays visible to other Runs, and its parent_task_id shows the isolated parent’s ID.
Your own API calls (company API key, personal access token or browser session) and company MCP credentials keep normal company and Area access, so the integration that creates isolated Tasks still lists, reads and manages every one of them.
Isolation keeps Tasks apart from each other, not from the company. Company-level configuration is shared input to every Run, isolated or not: company context, Area instructions and resources, company skills and plugins, plus Secrets items shared with the company or Area and connected apps allowed for the Area. Company members can change that configuration, and so can the Runs of their non-isolated Tasks, so an isolated Run cannot count on it being private or unchanged. Keep end-user data out of it. If an integration needs strict separation from everything else in a company, give it a dedicated company.
Melso recognizes a Run’s pull requests only by branch name. A Run that can push to a repository can open a pull request from another branch, and that pull request still links to, and on merge completes, any ordinary Task it names. Where isolated and ordinary Tasks share a repository, check a pull request’s linked Tasks before you merge it.
Task MCP servers
Give one Task’s Runs MCP servers of their own, such as your wiki, issue tracker or CRM authenticated with a secret you mint for that Task, or connectors your end user picked for a message. Sendmcp_servers with POST /api/tasks, replace the whole set with PUT /api/tasks/{id}/mcp-servers and read it with GET /api/tasks/{id}/mcp-servers. They work for isolated and ordinary Tasks.
McpServerInput is one of:
- Remote streamable HTTP:
{name:string, url:string, headers?:{[name:string]:string}}. - stdio:
{name:string, command:string, args?:string[], env?:{[name:string]:string}}. The command runs inside the Run’s sandbox, so it must be available there, for examplenpx.
{name:string, transport:"http"|"stdio", url?:string, header_names?:string[], command?:string, args?:string[], env_names?:string[]}. url, command and args are returned as given; header and env names are sorted. Values are never returned.
The mcp_servers field contract owns the count, transport and sealed-size limits. This example omits execution and sets start: false, saving the Task and server configuration without a Run. Replace the URL with a server you control:
POST /api/tasks
input and an execution object, and remove start: false. Put funding choices inside execution; mcp_servers remains top-level. Complete the funding setup in the API quickstart first.
An authorized GET /api/tasks/{id}/mcp-servers returns the corresponding summary:
GET /api/tasks/{id}/mcp-servers response
url and command, validation returns HTTP 400:
PUT /api/tasks/{id}/mcp-servers response 400
- At most 10 servers per Task.
namematches^[a-z0-9][a-z0-9-]{0,62}$, is unique within the Task, and cannot use a platform-reserved name. - Each server has exactly one of
urlorcommand.headersapply only to remote servers;argsandenvonly to stdio servers. Unknown fields are refused. urlis an absolutehttpsURL without whitespace or credentials. It is returned as given, so send secrets as headers, not in the URL.- Header names are HTTP field names, each at most once ignoring case, and header values contain no line breaks or other control characters except tab.
commandis not blank and contains no control characters.argsand env values contain no NUL characters. Env names use letters, digits and underscores and do not start with a digit.- The sealed set of one Task is at most 64 KiB; a larger one is refused with 413.
- When a Run of the Task is claimed, its MCP configuration holds the Task’s servers next to the Company-enabled servers and the servers granted to the Task’s Area. A Task server whose name equals a Company or Area server’s name replaces that server for this Task’s Runs.
- A replacement applies to Runs claimed after it. A Run already running keeps the servers it started with.
- Header and env values are write-only. Melso encrypts them, never returns them in a response, error, log or event, and redacts them from the Run’s output the way it redacts the Secrets values a Run receives.
- The values still reach the Run’s harness configuration, as company MCP servers’ values do, so the agent in the Run can read them. Mint each secret scoped to its Task and short-lived, have your MCP server refuse it once the Task has no live Run, and rotate it by replacing the set.
- Only company owners and admins (browser session or personal access token) and the company’s API keys set or clear them, with
mcp_serversonPOST /api/tasksor withPUT: a stdio server’s command runs, and a remote server is called, in every later Run of the Task, including Runs other members execute. Anyone else gets 403code: "task_mcp_servers_forbidden". A role change or key revocation that commits while a write is in progress refuses it. Human callers and company keys with Task read access may list the summaries withGET; Run tokens are excluded from this read permission. - Every Run token gets 403 on both routes and on
POST /api/taskswithmcp_servers, including a Run of the Task itself (isolated_task_scopefor a Run of an isolated Task). No MCP tool reads or sets them. - A
client_request_idreplay coversmcp_servers: a retry with other servers or other values under the same id returns 409. To tell them apart, Melso stores a SHA-256 of the create body, header and env values included, so use high-entropy secrets. - Deleting the Task deletes its servers.
Authentication
Use a company API key, which implies its company, or a personal access token with theX-Workspace-ID header. See Overview and authentication for credential types and token management.
Read and control work
Follow a Task withGET /api/tasks/{id}/stream: one Server-Sent Events connection pushes the Task, its Runs, their trace, the conversation and interactions as they change, and resumes without gaps after a disconnect. Prefer it to polling. Follow a Task’s Runs, not one Run: retries, Cloud lifetime rollovers and pauses add successor Runs, so one Run ending is not the Task’s outcome. GET /api/runs/{runId} reads one Run you already know in the shape GET /api/tasks/{id}/runs lists it. Read the final answer from Task conversation messages, inspect Run messages and events, and use the Run controls to pause, resume or cancel execution.
MCP
For remote MCP with OAuth, start with MCP setup.Apps built by Tasks
An ordinary Task can build a static HTML or Vite Artifact, retain its source and publish a stable company or public link. Later Tasks retrieve the source through the Artifact MCP catalog and deploy another version. Isolated Runs cannot deploy or manage Artifacts. See Artifacts through MCP. Human sessions and PATs can use the matching JSON endpointsPOST /api/artifacts/{list,get,deploy,manage,launch,renew,data} with the selected
company. Direct company API keys are not supported on this surface; Runs
use their existing MCP credentials. Public viewers use
POST /api/public/artifacts/{shareID}/{launch,renew,data} with anonymous
publication authority, including when the visitor is signed in. App table access
is restricted by explicit dataset grants and does not expose the general API.
Execution identity
Anadmin company API key may supply execution_identity_id at create time for an isolated: true Task. It must identify an active managed execution customer owned by that key’s integration in the same company. The field is immutable and is returned in Task responses. Task creation and follow-up retries remain scoped to their original API caller; all turns use the bound customer’s provider accounts and funding policy. See Managed execution customers.
Managed Tasks receive their explicitly configured Task MCP servers and repository
broker grants. They do not inherit company or Area MCP servers, connected-app
sessions, Secrets items, company repositories, Melso GitHub App credentials or the
company private network. Ordinary member Tasks retain their existing resource scope.
Atomic Task context
POST /api/tasks accepts metadata (a flat map of strings, numbers and booleans)
and instructions (immutable guidance for all Runs on the Task). The initial
metadata bag follows the metadata field contract, with at most 50 keys and the existing 8 KiB JSONB storage limit. Instructions are limited to 32768 UTF-8 bytes and cannot
contain NUL. Run credentials cannot configure Task instructions. Both fields
are committed before the first Run becomes available and included in the
client_request_id replay contract; changing either under the same request ID
returns 409 client_request_conflict. Metadata remains editable through the
existing single-key metadata routes. Neither field grants execution access;
keep credentials in authorized secret storage, never in metadata or instructions.
Customer-managed repository credentials
An admin company key registers only its own integration’s broker throughPUT /api/execution-credential-broker with { "endpoint": "https://...", "token": "..." }.
Ask Melso to enable your broker’s exact HTTPS origin before registering it. Registration
and delivery reject private DNS answers; delivery pins the public address and
never follows redirects. GET returns configuration identifiers and the endpoint,
without credentials. DELETE revokes the broker and future repository renewals.
Task create accepts repositories, each with a canonical GitHub HTTPS url,
optional ref, permission (read or write), and credential_reference.
Up to 20 grants are fixed at Task creation and override inherited repository lists.
The reference identifies the customer’s authorization grant, never a credential.
These fields require an admin key and participate in the atomic create/replay
contract. Broker execution requires an enabled integration.
Melso requests one repository token from the broker with an authenticated JSON
POST containing reference, workspace_id, task_id, run_id, repository_url,
and permission. The broker must independently authorize the external user and
repository on every call, and return { "token": "...", "expires_at": "...", "permission": "read" }.
Permission must exactly match the request. The repository credential contract requires expiry more than 30 seconds and at most 70 minutes after the exchange’s validation time. Errors and remote bodies are never forwarded to agents.
Renewal requires a live, unchanged Run attempt and its signed 24-hour grant.
The request must identify exactly one repository. The managed Git/gh helper
replaces inherited owner/host GitHub authentication so read grants receive only
read tokens. Revocation and broker rotation are rechecked after each exchange.
Execution bound to an accepted input
POST /api/tasks/{id}/input accepts optional execution using the create execution
schema and optional mcp_servers using the Task MCP schema. The selected execution
and encrypted MCP configuration belong to the accepted Run and its retries.
They do not change the Task’s next-run defaults. An explicit empty MCP array
disables Task-local MCP for that turn; omission snapshots the current Task-local
servers. Company and Area MCP access still follows their existing policies.
execution.funding_source on create or input may select account, gateway,
api_key or custom. Omission selects an authorized method at acceptance.
Cloud admission rechecks authorization, availability and budget for the bound
method; a disabled or unavailable method fails instead of switching to an
unrelated method. Account election continues to select an authorized healthy
account within the selected account method. Funding cannot be changed by the
Task’s next-run picker endpoint.
execution.provider_account_id chooses one authorized provider account for that
accepted Run. It implies funding_source: "account" and rejects another funding
source. The account must belong to the execution identity or have an explicit
share to it and match the harness. Disabled, revoked, reconnecting or exhausted
accounts fail closed; an explicit choice never falls back to another account or
the Gateway. Send the account ID on each turn that needs that choice. It does not
change the Task defaults or the member’s preferred account.
Execution, funding and MCP changes are included in the client_request_id
replay contract: an exact retry returns the original receipt, and a changed
selection returns 409 client_request_conflict. Keep one request ID per
intended input, including its full execution and MCP selection.
Settled execution usage
GET /api/runs/{run_id}/usage has the same company and Task access rules as
reading the Run, including company API keys. It returns the funding source,
selected account and execution identity, and customer_billed_ticks from actual
wallet transactions. One tick is $0.0000000001; amounts are decimal strings.
receipts contains immutable wallet receipt_id values and signed billed
amounts: charges are positive and refunds are negative. Deduplicate each
receipt_id, including adjustment receipts. usage_id groups updates to one
operation. reported_model_cost_ticks is the worker’s model-cost report; it is
separate from customer billing, especially for personal subscriptions and BYOK.
No supplier costs, credentials, request bodies or raw receipt metadata are
returned.
final stays false while the Run is active, a Gateway hold is unresolved, compute
is open, or canonical operation totals have not reached the wallet ledger.
Closed compute charged at its pinned rate can be settled with estimated supplier
evidence. estimated remains explicit on those wallet receipts. as_of identifies
the consistent snapshot. Continue periodic reconciliation after finalization to
receive later provider corrections and refunds; they produce new receipt IDs.
API reference
Request fields, response types and endpoint permissions are defined in the Tasks reference. See Pagination for list conventions, or start with the API quickstart.Creation fields
The Tasks endpoint reference owns the complete creation schema. Alongsidetitle, input, description, area_id, parent_task_id, attachment_ids, client_request_id, allow_duplicate, callback_url, start, isolated and mcp_servers, it includes metadata, instructions, repositories and execution_identity_id. The execution object includes harness, model controls, funding_source and provider_account_id; funding choices are nested inside execution, not top-level fields.
GET /api/tasks?status=done filters closed completed Tasks. Other status values do not filter the derived statuses; use the state table to interpret each result.
Optional Task response flags such as has_pending_interaction can be omitted when false. These excerpts mean false/absent and true/present respectively: