portablemind
All guides
API / Developer5 min read

Build a custom UI on the Orchestration API

Wrap agent pipelines in your own branded product — pick a path, launch a run, approve milestones, download deliverables. With a full reference app.

apiorchestrationreference app

Wrap PortableMind's agent pipelines in your own branded product. Your users pick a "path", launch a run, approve milestones, and download deliverables — never seeing PortableMind underneath. This is exactly what our Agentic Startup Accelerator portal does.

Reference app: pm-agentic-accelerator — a complete, dependency-free portal (one HTML page + a tiny Node proxy) that exercises every endpoint below. Clone it, point it at a backend, and fork it.

The model

An orchestration is a multi-stage pipeline. Your UI: lists published templates → renders a launch form from each template's input schema → starts a run → shows stages advancing live → handles approval gates → serves the artifacts. Everything is tenant-scoped and authenticated per request.

Authenticate

Send a tenant slug plus a credential on every call:

const headers = {
  'Content-Type': 'application/json',
  'API-KEY': KEY,            // service auth (tenant-locked)
  'Tenant-Id': 'your-tenant' // the slug, not the numeric id
};
// Or per-user: 'Authorization': `Bearer ${jwt}`

The core loop

GET  /api/v1/orchestration_templates              → the catalog you expose
GET  /api/v1/orchestration_templates/:id/details  → input_schema to build the form
POST /api/v1/orchestration_executions             → launch a run
GET  /api/v1/orchestration_executions/:id         → stages, gates, artifacts
GET  /api/v1/orchestration_executions/:id/status  → poll-friendly progress
POST /api/v1/orchestration_executions/:id/approve_stage   { notes?, inputs? }
POST /api/v1/orchestration_executions/:id/reject_stage
GET  /api/v1/orchestration_executions/:id/artifacts/:artifact_id/download

Launch with the inputs keyed by the template's schema:

await fetch('/api/v1/orchestration_executions', {
  method: 'POST', headers,
  body: JSON.stringify({
    orchestration_template_id: id,
    cost_limit: 25,
    context: { request: 'free-text intent', inputs: { repo: '…', branch: 'main' } }
  })
});

Live progress

Subscribe to the OrchestrationProgressChannel over ActionCable for live stage updates (WebSockets can't set headers — pass the credential as a query param: ?apikey= or ?token= + tenant_id=). Where WebSockets aren't available, poll /status every few seconds instead.

Result

A bespoke product on top of agent pipelines, with your branding and your catalog. The reference app shows the whole thing — form rendering, gate dialogs with file uploads, artifact download via authenticated fetch, and per-customer scoping — in one readable file.