# Preview using a template

**POST** `/api/templates/{id}/use/preview`

Shows what using a template would make, with the connections chosen so far. Makes nothing.

Needs [an API token](https://docs.gorunner.io/api/authentication#scopes) with the **Read** permission for workflows (`workflow:read`).

## Parameters

### Path

- `id` · Required · UUID: The template’s ID.

### Body

Optional: what the person has chosen so far.

- `connections` · Optional · object: A connection of this workspace for each slot: `{"c1": "…"}`.
- `values` · Optional · object: Fill-ins, by step name and field, as for Make a workflow from a template.

## Read it

`slots`: each slot, this workspace’s connections for its service (ones needing a new sign-in last) and `selected`, the one that would fill it.

`diagnostics`: what Check a definition would report on the workflow as made. `canPublish` and `publishBlockedBy`: whether it could go live, and the first reason not. `fill`: the values the person would be asked for, in step order.

## Responses

- 200 OK

  The preview.

- 400 `VALIDATION_ERROR`

  The body isn’t JSON, or `connections` names a slot the template lacks or a connection outside the workspace.

- 403 `FORBIDDEN`

  The token lacks the **Read** permission for workflows.

- 404 `NOT_FOUND`

  No template with this ID that this workspace may use. An ID that isn’t a UUID answers this too.

- 422 `PIECE_NOT_ALLOWED`

  A step uses an app this workspace may not use.

- 422 `CONNECTION_MISMATCH`

  A connection named for a slot is for another service (`details.slot`).

- 422 `VALIDATION_ERROR`

  The template uses an app this installation can’t run.

- 500 `INTERNAL_ERROR`

  The template or the workspace’s connections couldn’t be read.

- 503 `PIECES_UNAVAILABLE`

  GoRunner couldn’t check which apps this workspace may use.

Any call can also answer: [`401 UNAUTHORIZED`](https://docs.gorunner.io/errors#UNAUTHORIZED) · [`401 TOKEN_ENDED`](https://docs.gorunner.io/errors#TOKEN_ENDED) · [`403 TOKEN_SURFACE_OFF`](https://docs.gorunner.io/errors#TOKEN_SURFACE_OFF) · [`403 FEATURE_OFF`](https://docs.gorunner.io/errors#FEATURE_OFF) · [`403 EMBED_NOT_ALLOWED`](https://docs.gorunner.io/errors#EMBED_NOT_ALLOWED) · [`403 EMBED_NOT_AVAILABLE`](https://docs.gorunner.io/errors#EMBED_NOT_AVAILABLE) · [`403 ACCOUNT_SUSPENDED`](https://docs.gorunner.io/errors#ACCOUNT_SUSPENDED) · [`413 PAYLOAD_TOO_LARGE`](https://docs.gorunner.io/errors#PAYLOAD_TOO_LARGE) · [`415 INVALID_CONTENT_TYPE`](https://docs.gorunner.io/errors#INVALID_CONTENT_TYPE) · [`429 RATE_LIMITED`](https://docs.gorunner.io/errors#RATE_LIMITED) · [`503 BUSY`](https://docs.gorunner.io/errors#BUSY) · [`503 PAUSED`](https://docs.gorunner.io/errors#PAUSED) · [`503 SERVICE_UNAVAILABLE`](https://docs.gorunner.io/errors#SERVICE_UNAVAILABLE). See [Errors](https://docs.gorunner.io/api/errors#by-status).

Request

**curl**

```bash
GORUNNER="https://api.gorunner.io"
GORUNNER_TOKEN="grt_…"  # needs Read for workflows
TEMPLATE_ID="your-template-id"

URL="$GORUNNER/api/templates/$TEMPLATE_ID/use/"
URL="${URL}preview"
curl -X POST "$URL" \
  -H "Authorization: Bearer $GORUNNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "connections": {
      "c1": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b"
    }
  }'
```

**JavaScript**

```js
const GORUNNER = "https://api.gorunner.io";
const TOKEN = process.env.GORUNNER_TOKEN;
const TEMPLATE_ID = process.env.TEMPLATE_ID;

const res = await fetch(
  `${GORUNNER}/api/templates/${TEMPLATE_ID}/` +
    `use/preview`,
  {
    method: "POST",
    headers: {
        Authorization: `Bearer ${TOKEN}`,
        "Content-Type": "application/json",
      },
    body: JSON.stringify({
        connections: {
          c1: "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b",
        },
      }),
  },
);
const { data } = await res.json();
```

**Python**

```python
import os, requests

GORUNNER = "https://api.gorunner.io"
TOKEN = os.environ["GORUNNER_TOKEN"]
TEMPLATE_ID = os.environ["TEMPLATE_ID"]

res = requests.post(
    f"{GORUNNER}/api/templates/{TEMPLATE_ID}/use/"
    f"preview",
    headers={"Authorization": f"Bearer {TOKEN}"},
    json={
      "connections": {
        "c1": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b",
      },
    },
)
data = res.json()["data"]
```

Response · 200 OK, shortened

```json
{
  "data": {
    "slots": [
      {
        "key": "c1",
        "pieceId": "postgres",
        "candidates": [
          {
            "id": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b",
            "name": "Warehouse database",
            "status": "active"
          }
        ],
        "selected": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b"
      }
    ],
    "diagnostics": [],
    "canPublish": true,
    "publishBlockedBy": null,
    "fill": [],
    "savedHere": true,
    "savedIn": "Orders"
  }
}
```

**Every field**

### Body

- `connections` · Optional · object: Slot key → a connection of this workspace made for the slot’s service.
  - `{key}` · UUID: Each key’s value.
- `values` · Optional · object: The person’s fill-ins: step name → input key → value, written over the template’s values. A blank value (`""`, null, `[]`) leaves the field blank. A step or input the template does not have is refused 400 (`details.field: values`, `details.step`, `details.input`).
  - `{key}` · object: Each key’s value.

### Response · 200 OK

- `data` · object
  - `slots` · array of objects
    - `key` · string: The slot (`c1`, `c2`, … in the order the steps first use it).
    - `pieceId` · string: The service a connection for it must be for.
    - `pieceName` · string
    - `steps` · array of objects
      - `name` · string: `trigger` for the trigger.
      - `displayName` · string
    - `candidates` · array of objects: This workspace’s connections for the service; those needing a new sign-in (`expired`, `error`) last.
      - `id` · UUID
      - `name` · string
      - `status` · string
      - `managedBy` · string or null: One of `partner`, `null`.
    - `selected` · UUID or null: The connection that fills it now: the one chosen, else the one the template’s steps named where it is a candidate and works (never one that is `error`, `expired` or `pending`).
  - `diagnostics` · array of objects: What `POST /api/workflows/validate` would report on the workflow as it would be made, with this workspace’s apps applied. Each with `stepLabel` (the step as the canvas names it) and `fieldLabel` (the app’s title for the field; empty when it is not about an app’s field).
    - `severity` · string: One of `error`, `warning`, `info`.
    - `code` · string: Stable machine-readable identifier for the kind of problem. Switch on this, not on `message`. The Code step’s own: `code_expression_in_code` (Code 2.0.0 code holds a `{{ steps…/trigger…/$… }}`, which 2.0.0 does not replace — in live code it blocks publish, never a save; inside string or template text it is a warning, since 2.0.0 keeps that text as written), `code_empty` (2.0.0 blank code, blocks publish; 1.0.0 empty code, a warning: it fails at run time), `code_v1_expression` (Code 1.0.0 pastes `{{ }}` into the program: a warning when it reads the trigger, else info), `code_unavailable_api` (`require(`, `import`, `fetch(`, `XMLHttpRequest`, `process.env`), `code_global_not_here` (a 1.0.0 `$` name in 2.0.0 code), `code_timeout_capped` (1.0.0 stops at 30 s whatever Timeout says), `code_output_path` (`steps.<code step>.<key>` where the output is `{result, logs}`), `code_returns_result` (`return { result: … }`), `code_syntax_error` (the code does not compile as its run compiles it, so every run that reaches the step fails before a line of it runs: the message names the line of the code as written; it blocks publish, never a save, and is a warning on a step no run reaches (skipped, or in error steps its step does not route to); a 1.0.0 step whose `{{ }}` are pasted in before it runs is not checked). A step on Code 1.0.0 only ever gets warnings and info, except for code that cannot compile (`code_syntax_error`) or is over 256 KB (`code_too_large`). `step_name_too_long` (a step’s `name` or `displayName` over 255 characters: a run reaching it could not save its steps. Blocking, and refused by every write; a warning for a name the definition being replaced already holds, so a workflow stored with one can still be saved and published). `missing_required_config` blocks only at an app’s default version: a step pinned to (or, unpinned, running) an older version gets it as a warning.
    - `path` · string: Where in the definition the problem is, e.g. `trigger.nextAction.config.body_type`.
    - `step` · string: The step’s `name`, when the problem belongs to a step.
    - `field` · string: The offending config field, when there is one.
    - `message` · string: Human-readable explanation.
    - `alternatives` · array of strings: The admissible values at this position, nearest miss first.
    - `moreAlternatives` · integer: How many legal values were NOT listed — so you can tell a complete vocabulary from a sample. 0 or absent means `alternatives` is the whole set.
    - `blocking` · boolean: True when a save or publish would refuse on this. Set by the validator; the informational endpoint and the write gates cannot disagree because they run the same function.
    - `stepLabel` · string
    - `fieldLabel` · string
  - `canPublish` · boolean: It could be published as it would be made: false also when a chosen connection is `error`, `expired` or `pending` (`publishBlockedBy.code: CONNECTION_NOT_WORKING`). Whether the caller may publish is the caller’s own permissions.
  - `publishBlockedBy` · object or null: The first thing that keeps it from being turned on; null when nothing does.
    - `code` · string: The first blocking diagnostic’s code.
    - `message` · string
    - `step` · string: The step it is about, as the canvas names it.
    - `field` · string: The field it is about, as the app titles it.
  - `fill` · array of objects: What the person is asked to fill in, in step order: worked out before the request’s `values`, so it stays the same while they type.
    - `step` · string
    - `stepLabel` · string
    - `pieceId` · string
    - `actionId` · string
    - `field` · string
    - `fieldLabel` · string
    - `propertyType` · string
    - `required` · boolean
    - `why` · string: One of `bound`, `check`, `required`.
    - `slot` · string or null: The slot of the step’s connection.
    - `value`: What the workflow would get, with the request’s `values` applied.
    - `hint`: The old value of a blanked bound field; null otherwise.
  - `savedHere` · boolean: The template was saved in this workspace.
  - `savedIn` · string or null: Where it was saved (a workspace’s name; an installation template: the organization it was shared from).

Related: [Make a workflow from a template](https://docs.gorunner.io/api/templates/use-template)

Source: https://docs.gorunner.io/api/templates/preview-template-use
