# Run a Genie and wait for the result

> Sends a message to a Genie and answers once the Genie has finished with it, so the reply is in the same response. A Genie that calls several tools can take minutes; keep the connection open or use Run a Genie and poll instead. Omit genie_id to let the workspace's Genie dispatcher pick the Genie; pass conversation_id to continue an earlier conversation. The answer has the same shape as Get a Genie run.

Source: https://docs.stacksync.com/api-reference/genies/runs/run_genie_and_wait

`POST https://genies.stacksync.com/v1/workspaces/{workspace_id}/genies/run_wait_result`

- Operation: `run_genie_and_wait`
- Resource: Genie runs
- Access: writes data

## Authentication

- `Authorization: Bearer <key>`: A workspace API key (workspace_…, created by a workspace owner under Workspace settings > Stacksync API) acts with editor rights on that workspace only; a user API key (user_…, created under Profile > Stacksync API) acts as that user in every workspace they belong to. POST requests must send Content-Type: application/json. Every authentication failure answers 403. Running a Genie needs the editor role in the workspace.
- `Content-Type: application/json` on every request with a body.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | integer | Yes | The workspace whose Genie runs. A workspace API key works only on its own workspace; a user API key on any workspace the user belongs to. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `genie_id` | string | No | The Genie to run (its id from the Genies list). Omitted, the workspace's Genie dispatcher selects the Genie that best fits the message; a follow-up without genie_id goes through the dispatcher again and may reach another Genie. A named Genie must exist in the region and be active. |
| `region` | string (besg \| usnv) | No | Data region of the resources: the region of the Genie, where the conversation is stored. Allowed values: besg, usnv. Defaults to the region of the server that answers, so always pass the Genie's region. A value in the request body wins over the query parameter. |

## Request body

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `input` | string \| object | Yes | The message handed to the Genie. A string is used as is; a JSON object is encoded as text so nothing is lost. |
| `conversation_id` | string (uuid) | No | The conversation to continue, from an earlier run answer: the earlier messages are the Genie's context, and a failed conversation reopens. Omitted, a new conversation starts. |
| `region` | string (besg \| usnv) | No | Data region of the Genie, where the conversation is stored. Allowed values: besg, usnv. Same meaning as the region query parameter; this value wins. |
| `options` | object (RunGenieOptions) | No | Options of the run. |
| `options.dispatch_external_message` | object (ApprovalDispatch) | No | Where an approval request is delivered when the Genie pauses on an action that needs one. Both interface_type and interface_id are needed; the destination inside that interface (a channel, an address) is taken from the Genie's master prompt. Without it the approval is only returned in options.approval of the reply. |
| `options.dispatch_external_message.interface_type` | string (slack \| teams \| email) | Yes | The type of the Genie's configured interface that delivers the approval request. Allowed values: slack, teams, email. |
| `options.dispatch_external_message.interface_id` | string | Yes | The id of that configured interface of the Genie. |
| `options.dispatch_external_message.attachement_file_ids` | array of string | No | Ids of stored files to deliver with the approval request. The files must belong to this request or conversation. |
| `source` | string | No | A label of your own for where the message came from, stored on it. Omitted or blank, api. The values slack, email, teams and public_api are reserved and refused. |
| `validate_only` | boolean, default false | No | true runs only the checks of the run (the Genie exists and is active) and answers 204 without asking the Genie or storing anything. |

## Returns

### 200 The run finished, or could not: status says which. completed carries the reply in result; failed carries the reason in error when the run stopped before the Genie answered; processing means the message steered a run that is still going, so poll Get a Genie run.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string (processing \| completed \| failed) | Yes | processing: the Genie is still working (or the message steered a run in progress). completed: the Genie answered; result holds the reply. failed: the run could not finish. |
| `conversation_id` | string (uuid) \| null | Yes | The conversation of the run. Send it back to continue the conversation. |
| `region` | string (besg \| usnv \| null) | Yes | Data region the conversation is stored in. Null only on a failure answered before the region was resolved. |
| `message_id` | string (uuid) \| null | Yes | Id of the Genie's latest reply in the conversation; null while there is none. |
| `result` | string | No | The text of the Genie's latest reply. Present once the conversation holds a reply. |
| `widget` | object | No | The structured action the reply proposes, when the Genie attached one to its reply. |
| `options` | object (GenieReplyOptions) | No | Details attached to the reply. Carries approval when the Genie paused on an action that needs an approval; decide it with the approval decision operation using the same API key. |
| `options.approval` | object (GenieApproval) | No | An action the Genie is waiting to have approved before it runs it. |
| `options.approval.approval_id` | string (uuid) | Yes | Id of the approval, used to decide it. |
| `options.approval.type` | string (execute_module) | Yes | What kind of action waits: execute_module, a connector action. |
| `options.approval.region` | string (besg \| usnv) | Yes | Data region the approval is stored in. Allowed values: besg, usnv. |
| `options.approval.instructions` | string | Yes | What the Genie intends to do with the action. |
| `options.approval.status` | string (awaiting_approval \| rejected \| approved_once \| approved_always \| unknown_outcome) | Yes | State of the approval. awaiting_approval until it is decided. |
| `options.approval.decision_at` | string (date-time) \| null | Yes | When the approval was decided, ISO 8601 UTC without offset; null while it waits. |
| `options.approval.module_id` | string | No | Id of the connector action waiting for approval. |
| `options.approval.module_name` | string | No | Name of the connector action waiting for approval. |
| `options.approval.connection_id` | string \| null | No | Id of the connection the action would use. |
| `options.approval.connection_name` | string \| null | No | Name of the connection the action would use. |
| `options.approval_delivery` | object | No | Where the approval request was delivered when the run asked for an external delivery. |
| `attachments` | array of object (GenieReplyAttachment) | No | The files the reply produced, as stored file references. Present once the conversation holds a reply; empty when the reply has no file. |
| `attachments[].file_id` | string | Yes | Id of the stored file. |
| `attachments[].filename` | string | Yes | Name of the file. |
| `attachments[].content_type` | string | Yes | Media type of the file, such as application/pdf. |
| `error` | string | No | Why the run failed, when it stopped before the Genie answered or the region is unknown. |

### 204 validate_only was true and every check of the run passed (the Genie, the conversation). Nothing was asked and nothing was stored.

No body.

## Example request

```bash
curl -X POST "https://genies.stacksync.com/v1/workspaces/{workspace_id}/genies/run_wait_result" \
  -H "Authorization: Bearer $STACKSYNC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "input": "Repeat the first thing I said to you.",
  "conversation_id": "d10c810f-1187-4a6e-9df9-ac2e87d02f2d",
  "region": "usnv"
}'
```

## Example response (200)

```json
{
  "status": "completed",
  "conversation_id": "d10c810f-1187-4a6e-9df9-ac2e87d02f2d",
  "region": "usnv",
  "message_id": "aef1f941-d148-4833-9118-86f59c358d5a",
  "result": "Hello, world! I am the Hello World API Demo genie.",
  "attachments": [],
  "options": {}
}
```

## Errors

| Status | Meaning | Body |
| --- | --- | --- |
| 400 | The request could not be read: the body is not a JSON object, input is missing, source is a reserved value, validate_only is not true or false, or workspace_id is not a number. | `{ "error": string, "msg": string, "field": string }` |
| 403 | The caller is not allowed: Authorization Error (header missing or not Bearer), Invalid API Key (unknown key, key of another workspace, or a user who is not a member of the workspace), Content-Type Error (POST without application/json), Insufficient Scope (a read-only sign-in on a request that changes data) or Authentication Error (your role in the workspace is below editor). | `{ "error": string, "msg": string, "field": string }` |
| 404 | genie_id names no Genie in this region. | `{ "error": string (genie_not_found \| genie_inactive), "message": string }` |
| 409 | genie_id names a Genie that is switched off. Switch it on before asking it. | `{ "error": string (genie_not_found \| genie_inactive), "message": string }` |

## Related

- [API Reference overview](https://docs.stacksync.com/api-reference): base URLs, regions, pagination, idempotency and errors
- [Authentication](https://docs.stacksync.com/api-reference/authentication): API keys and the 403 answers
- OpenAPI document: https://docs.stacksync.com/openapi-genies.json
- [Get a Genie run](https://docs.stacksync.com/api-reference/genies/runs/get_genie_run)
- [Run a Genie](https://docs.stacksync.com/api-reference/genies/runs/run_genie)