> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracecat.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflows-as-APIs

> Call Tracecat workflows as synchronous HTTP APIs: block on the /wait webhook endpoint, read the response envelope, and fetch large results by download link.

Use `POST /webhooks/{workflow_id}/{secret}/wait` to run a workflow and receive its `return` value in the response. The request blocks until the workflow finishes. The workflow must be published. The request body becomes `TRIGGER` exactly as with the default webhook.

The caller treats the workflow like a synchronous HTTP handler: send a request, get the workflow's result back.

## Response schema

The response is an envelope with a `kind` field:

```json theme={null}
{
  "kind": "value",
  "value": { "status": "ok" }
}
```

```json theme={null}
{
  "kind": "download_file",
  "download_url": "https://...",
  "expires_in_seconds": 10,
  "content_type": "application/json",
  "size_bytes": 262144
}
```

## Kinds

`kind` tells you how to read the rest of the body: each value comes with its own set of fields. Small results come back inline; large results come back as a download link.

* `value`: inline result. The body has `value` set to the workflow's `return` value.
* `download_file`: externalized result. The body has a presigned `download_url`, plus `expires_in_seconds`, `content_type`, and `size_bytes`.
* `download_export`: materialized collection result. Same fields as `download_file`; `content_type` is always `application/json`.

Results over `TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES` (default 128 KiB) are stored in object storage and returned as a short-lived presigned URL (default 10-second expiry). This keeps the webhook response small and predictable, so synchronous callers never stream megabytes of workflow state through a single HTTP response.

## Query parameters

* `unwrap=true`: return the workflow's `return` value directly as the response body, with no envelope. Requires the result to fit inline.

If the result was externalized (kind `download_file` or `download_export`), `/wait?unwrap=true` returns `413 Payload Too Large` with the download envelope under `detail`, so the caller can still fetch the data.

Example:

```bash theme={null}
curl -X POST "https://<host>/webhooks/<workflow_id>/<secret>/wait?unwrap=true" \
  -H "Content-Type: application/json" \
  -d '{"alert_id": "A-001"}'
# 200 OK
# {"status": "ok"}
```

If the workflow returns a result larger than the externalization threshold:

```json theme={null}
{
  "detail": {
    "kind": "download_file",
    "download_url": "https://...",
    "expires_in_seconds": 10,
    "content_type": "application/json",
    "size_bytes": 262144
  }
}
```
