---
title: "Overview"
description: "How your application communicates with Output workflows over HTTP"
---

Your application talks to Output through a REST API. When you deploy Output, the API server exposes HTTP endpoints for running workflows, checking their status, and retrieving results. Your backend sends a request, Output orchestrates the workflow, and you get structured results back.

During development, the API server starts automatically on port 3001 when you run `output dev`.

## Two Ways to Run Workflows

Choose based on how long your workflow takes and how your application handles responses.

### Run and Wait (Synchronous)

`POST /workflow/run` blocks until the workflow completes and returns the result in the response body. Use this when workflows complete quickly (seconds) and your client can wait.

```bash
curl -X POST http://localhost:3001/workflow/run \
  -H "Content-Type: application/json" \
  -d '{"workflowName": "summarize_url", "input": {"url": "https://example.com/article"}}'
```

### Start and Poll (Asynchronous)

`POST /workflow/start` returns the workflow ID immediately. Poll for status and retrieve the result when ready. Use this for longer workflows — minutes or more — where blocking a request isn't practical.

```bash
# Start the workflow
curl -X POST http://localhost:3001/workflow/start \
  -H "Content-Type: application/json" \
  -d '{"workflowName": "company_research", "input": {"domain": "example.com"}}'

# Check status
curl http://localhost:3001/workflow/<workflow-id>/status

# Get result when completed
curl http://localhost:3001/workflow/<workflow-id>/result
```

## Workflow Result Payload

`POST /workflow/run` and `GET /workflow/:id/result` return the same structured workflow result:

```json
{
  "workflowId": "lead_enrichment-a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "runId": "b5c6d7e8-9012-3456-7890-abcdef123456",
  "status": "completed",
  "input": { "companyDomain": "acme.com" },
  "output": {
    "company": "Acme Corp",
    "summary": "Enterprise software company focused on..."
  },
  "trace": { "destinations": {} },
  "error": null
}
```

| Field | Description |
|-------|-------------|
| `workflowId` | Workflow execution ID. |
| `runId` | Specific Temporal run ID. |
| `status` | Current or final execution status. |
| `input` | Original workflow input. |
| `output` | Value returned by the workflow on success, or `null` on failure. |
| `trace` | Trace metadata for the run, or `null` when unavailable. |
| `error` | Error message on failure, otherwise `null`. |

When a workflow fails, the result includes `status: "failed"`, `output: null`, and an `error` message. Trace metadata may still be present when available.

## Interacting with Running Workflows

Output supports sending data to running workflows and reading their state via signals, queries, and updates. The workflow must define handlers for these — see [External Integration](/workflows/external-integration) for how to set them up.

| Method | What it does | Use case |
|--------|-------------|----------|
| **Signal** `POST /workflow/:id/signal/:name` | Push data into a workflow | Human approval, external events |
| **Query** `POST /workflow/:id/query/:name` | Read workflow state without changing it | Progress checks, status dashboards |
| **Update** `POST /workflow/:id/update/:name` | Change state and get confirmation | Configuration changes, priority updates |

## Stopping Workflows

- `PATCH /workflow/:id/stop` — Graceful stop. Allows cleanup handlers to run.
- `POST /workflow/:id/terminate` — Force terminate. Immediate, no cleanup.

## Workflow Discovery

`GET /workflow/catalog` returns all available workflows with their input and output schemas. Use this to build dynamic UIs or validate inputs before submitting.

## Streaming Workflow Progress

`GET /workflow/:id/history/stream` opens a persistent [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) connection that delivers Temporal history events in real time as the workflow executes. Use this to build live progress UIs without polling.

```js
const es = new EventSource(`http://localhost:3001/workflow/${workflowId}/history/stream`);

es.addEventListener('workflow', e => {
  const { status, historyLength, taskQueue } = JSON.parse(e.data);
  // initial metadata, emitted once on connect
});

es.addEventListener('history', e => {
  const events = JSON.parse(e.data);
  // array of new Temporal history events (same shape as REST endpoint)
});

es.addEventListener('done', e => {
  const { reason, newRunId } = JSON.parse(e.data);
  es.close();
});

es.addEventListener('server_error', e => {
  // server-side error after stream started
});
```

The stream emits four named events:

| Event | When | Data |
|-------|------|------|
| `workflow` | Once on connect | `{ workflowId, runId, status, startTime, closeTime, historyLength, taskQueue }` |
| `history` | Each batch of new events | Array of serialized history events |
| `done` | Workflow reaches terminal state | `{ reason, newRunId? }` |
| `server_error` | Post-connect server error | `{ error, message, workflowId, runId }` |

`reason` is the terminal Temporal event type, one of: `WORKFLOW_EXECUTION_COMPLETED`, `WORKFLOW_EXECUTION_FAILED`, `WORKFLOW_EXECUTION_TIMED_OUT`, `WORKFLOW_EXECUTION_CANCELED`, `WORKFLOW_EXECUTION_TERMINATED`, `WORKFLOW_EXECUTION_CONTINUED_AS_NEW`. `newRunId` is present only when the terminal event carries a follow-on run (continue-as-new, and the completed/failed/timed-out cases that chain a new run).

Errors raised before the stream starts (invalid `lastEventId`, unknown workflow) are returned as normal JSON HTTP responses (`400`/`404`). Once the stream is open, failures arrive as a `server_error` event instead — the connection has already committed to `200 text/event-stream`.

`EventSource` reconnects automatically after network drops. On reconnect it sends `Last-Event-ID` and the server replays only events the client hasn't seen.

To target a specific run, use `GET /workflow/:id/runs/:rid/history/stream`. Pass `?includePayloads=true` to include decoded activity input/output in the events.

## Debugging

`GET /workflow/:id/trace-log` returns the full execution trace for a completed workflow. See [Tracing](/operations/tracing) for the trace format.

<Note>
For remote traces, the API server needs AWS credentials (`OUTPUT_AWS_ACCESS_KEY_ID`, `OUTPUT_AWS_SECRET_ACCESS_KEY`, `OUTPUT_AWS_REGION`).
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/api/configuration">
    **Configuration.** Base URL, ports, and environment variables for the API server.
  </Card>
  <Card title="Authentication" icon="lock" href="/api/authentication">
    **Authentication.** How auth works in development vs production.
  </Card>
  <Card title="Error Responses" icon="circle-exclamation" href="/api/errors">
    **Error Responses.** Error codes, response format, and how to handle failures.
  </Card>
</CardGroup>
