# Create a genie

> The configuration's defaults are the web app's (every tool on); the description is written by Stacksync from the instructions. Send a configuration made by the genies setup wizard (genies.stacksync.com .../genies/wizard/generate-config) after filling the connection of each skill.

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

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

- Operation: `create_genie`
- Resource: Genies
- 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, PUT and PATCH requests must send Content-Type: application/json. Every authentication failure answers 403.
- `Content-Type: application/json` on every request with a body.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | integer | Yes | The workspace. List the ones your key can reach with GET /v1/workspaces. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `region` | string (besg \| usnv) | Yes | Region of the genie: besg (Europe) or usnv (United States) |

## Header parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string \| null | No | Makes the create retry-safe for 24 hours: a retry with the same key answers the resource the first call created, with the Idempotent-Replayed: true header, and creates nothing. 1 to 255 visible ASCII characters. The same key with a different request answers 422; while the first call still runs, 409. |

## Request body

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string, 1 to 255 characters | Yes | Unique among the workspace's genies of the region |
| `folder_id` | string (uuid) \| null | No | The folder to create it in; the root when absent |
| `is_shared_with_workspace` | boolean, default true | No | Whether every member of the workspace sees it |
| `genie_config` | object (GenieConfigInput) | No |  |
| `genie_config.master_prompt` | string, default "" | No | The genie's instructions |
| `genie_config.description` | string, default "" | No | Leave empty: Stacksync writes it from the instructions |
| `genie_config.model` | string, default "" | No | The LLM the genie runs on; empty for Stacksync's default |
| `genie_config.interfaces` | array of object (GenieInterfaceDocument) | No |  |
| `genie_config.interfaces[].id` | string | Yes |  |
| `genie_config.interfaces[].type` | string | Yes | slack, teams or email |
| `genie_config.interfaces[].details` | string | Yes | For email: the address '<alias>@stacksync.email' |
| `genie_config.interfaces[].connection_id` | string, default "" | No | The Slack or Teams connection of the workspace; empty for email |
| `genie_config.interfaces[].connection_resource_id` | string, default "" | No | The resource id of that connection; empty for email |
| `genie_config.skills` | array of object (GenieSkillDocument) | No |  |
| `genie_config.skills[].id` | string | Yes | The module id |
| `genie_config.skills[].name` | string | Yes |  |
| `genie_config.skills[].description` | string, default "" | No |  |
| `genie_config.skills[].type` | "Module", default "Module" | No |  |
| `genie_config.skills[].enabled` | boolean, default true | No |  |
| `genie_config.skills[].connection` | string \| null | No | The connection id the action runs with |
| `genie_config.skills[].connection_resource_id` | string \| null | No | The resource id of that connection |
| `genie_config.skills[].approval_policy` | string (always_allow \| approval_required), default "always_allow" | No | approval_required pauses the genie until a person approves the action |
| `genie_config.app_descriptions` | object | No | Per skill app type: when and how the genie uses that app |
| `genie_config.resources` | array of object (GenieResourceDocument) | No |  |
| `genie_config.resources[].name` | string | Yes |  |
| `genie_config.resources[].type` | string (connection \| variable \| secret) | Yes |  |
| `genie_config.resources[].value` | string | Yes | The connection id or the variable id |
| `genie_config.resources[].instructions` | string, default "" | No |  |
| `genie_config.teams` | array of object (GenieTeamDocument) | No |  |
| `genie_config.teams[].id` | string | Yes |  |
| `genie_config.teams[].name` | string | Yes |  |
| `genie_config.contacts` | array of object (GenieContactDocument) | No |  |
| `genie_config.contacts[].id` | string | Yes |  |
| `genie_config.contacts[].name` | string | Yes |  |
| `genie_config.contacts[].email` | string | Yes |  |
| `genie_config.tools` | object (GenieToolsDocument) | No | The built-in tools the genie may use; all on by default, as in the web app |
| `genie_config.tools.web_search` | boolean, default true | No |  |
| `genie_config.tools.execute_browser` | boolean, default true | No |  |
| `genie_config.tools.api_call` | boolean, default true | No |  |
| `genie_config.tools.code_execution` | boolean, default true | No |  |
| `genie_config.tools.stacksync_ocr` | boolean, default true | No |  |
| `genie_config.tools.modify_scheduled_task` | boolean, default true | No |  |
| `genie_config.api_key` | string \| null | No | Your own LLM API key for the model; never returned |
| `knowledge_bases` | array of object (GenieKnowledgeBaseDocument) | No |  |
| `knowledge_bases[].knowledge_base_id` | string (uuid) | Yes | As answered by the knowledge base routes |
| `knowledge_bases[].instructions` | string, default "" | No |  |
| `validate_only` | boolean, default false | No | Run every check of the write and answer 204 without writing: a refused write answers the error the write would |

## Returns

### 201 Created

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `genie_id` | string | Yes |  |
| `name` | string | Yes |  |
| `region` | string (besg \| usnv) | Yes |  |
| `folder_id` | string \| null | No |  |
| `status` | string \| null | No |  |
| `public_access_rights` | string \| null | No |  |
| `is_shared_with_workspace` | boolean \| null | No |  |
| `has_api_key` | boolean | Yes | Whether an LLM API key of yours is stored (the key itself is never returned) |
| `genie_config` | object (GenieConfigDocument) | Yes | What the genie does and how: its instructions, channels, skills, resources and tools |
| `genie_config.master_prompt` | string, default "" | No | The genie's instructions |
| `genie_config.description` | string, default "" | No | Leave empty: Stacksync writes it from the instructions |
| `genie_config.model` | string, default "" | No | The LLM the genie runs on; empty for Stacksync's default |
| `genie_config.interfaces` | array of object (GenieInterfaceDocument) | No |  |
| `genie_config.interfaces[].id` | string | Yes |  |
| `genie_config.interfaces[].type` | string | Yes | slack, teams or email |
| `genie_config.interfaces[].details` | string | Yes | For email: the address '<alias>@stacksync.email' |
| `genie_config.interfaces[].connection_id` | string, default "" | No | The Slack or Teams connection of the workspace; empty for email |
| `genie_config.interfaces[].connection_resource_id` | string, default "" | No | The resource id of that connection; empty for email |
| `genie_config.skills` | array of object (GenieSkillDocument) | No |  |
| `genie_config.skills[].id` | string | Yes | The module id |
| `genie_config.skills[].name` | string | Yes |  |
| `genie_config.skills[].description` | string, default "" | No |  |
| `genie_config.skills[].type` | "Module", default "Module" | No |  |
| `genie_config.skills[].enabled` | boolean, default true | No |  |
| `genie_config.skills[].connection` | string \| null | No | The connection id the action runs with |
| `genie_config.skills[].connection_resource_id` | string \| null | No | The resource id of that connection |
| `genie_config.skills[].approval_policy` | string (always_allow \| approval_required), default "always_allow" | No | approval_required pauses the genie until a person approves the action |
| `genie_config.app_descriptions` | object | No | Per skill app type: when and how the genie uses that app |
| `genie_config.resources` | array of object (GenieResourceDocument) | No |  |
| `genie_config.resources[].name` | string | Yes |  |
| `genie_config.resources[].type` | string (connection \| variable \| secret) | Yes |  |
| `genie_config.resources[].value` | string | Yes | The connection id or the variable id |
| `genie_config.resources[].instructions` | string, default "" | No |  |
| `genie_config.teams` | array of object (GenieTeamDocument) | No |  |
| `genie_config.teams[].id` | string | Yes |  |
| `genie_config.teams[].name` | string | Yes |  |
| `genie_config.contacts` | array of object (GenieContactDocument) | No |  |
| `genie_config.contacts[].id` | string | Yes |  |
| `genie_config.contacts[].name` | string | Yes |  |
| `genie_config.contacts[].email` | string | Yes |  |
| `genie_config.tools` | object (GenieToolsDocument) | No | The built-in tools the genie may use; all on by default, as in the web app |
| `genie_config.tools.web_search` | boolean, default true | No |  |
| `genie_config.tools.execute_browser` | boolean, default true | No |  |
| `genie_config.tools.api_call` | boolean, default true | No |  |
| `genie_config.tools.code_execution` | boolean, default true | No |  |
| `genie_config.tools.stacksync_ocr` | boolean, default true | No |  |
| `genie_config.tools.modify_scheduled_task` | boolean, default true | No |  |
| `knowledge_bases` | array of object (GenieKnowledgeBaseDocument) | Yes |  |
| `knowledge_bases[].knowledge_base_id` | string (uuid) | Yes | As answered by the knowledge base routes |
| `knowledge_bases[].instructions` | string, default "" | No |  |
| `created_time` | string (date-time) \| null | No |  |
| `last_modified_time` | string (date-time) \| null | No |  |

### 204 No Content

No body.

## Example request

```bash
curl -X POST "https://api.stacksync.com/v1/workspaces/{workspace_id}/genies?region=besg" \
  -H "Authorization: Bearer $STACKSYNC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "<name>"
}'
```

## Example response (201)

```json
{
  "genie_id": "<genie_id>",
  "name": "<name>",
  "region": "besg",
  "folder_id": "<folder_id>",
  "status": "<status>",
  "public_access_rights": "<public_access_rights>",
  "is_shared_with_workspace": false,
  "has_api_key": false,
  "genie_config": {
    "master_prompt": "",
    "description": "",
    "model": "",
    "interfaces": [
      {
        "id": "<id>",
        "type": "<type>",
        "details": "<details>",
        "connection_id": "",
        "connection_resource_id": ""
      }
    ],
    "skills": [
      {
        "id": "<id>",
        "name": "<name>",
        "description": "",
        "type": "Module",
        "enabled": true,
        "connection": "<connection>",
        "connection_resource_id": "<connection_resource_id>",
        "approval_policy": "always_allow"
      }
    ],
    "app_descriptions": {},
    "resources": [
      {
        "name": "<name>",
        "type": "connection",
        "value": "<value>",
        "instructions": ""
      }
    ],
    "teams": [
      {
        "id": "<id>",
        "name": "<name>"
      }
    ],
    "contacts": [
      {
        "id": "<id>",
        "name": "<name>",
        "email": "<email>"
      }
    ],
    "tools": {
      "web_search": true,
      "execute_browser": true,
      "api_call": true,
      "code_execution": true,
      "stacksync_ocr": true,
      "modify_scheduled_task": true
    }
  },
  "knowledge_bases": [
    {
      "knowledge_base_id": "3f6c1d2e-8a4b-4c7d-9e21-5b6f7a8c9d01",
      "instructions": ""
    }
  ],
  "created_time": "2027-01-15T09:00:00Z",
  "last_modified_time": "2027-01-15T09:00:00Z"
}
```

## Errors

| Status | Meaning | Body |
| --- | --- | --- |
| 400 | Bad Request | `{ "error": string, "msg": string, "field": string \| null }` |
| 403 | Forbidden | `{ "error": string, "msg": string, "field": string \| null }` |
| 409 | Conflict | `{ "error": string, "msg": string, "field": string \| null }` |
| 422 | Unprocessable Content | `{ "error": string, "msg": string, "field": string \| null }` |

## 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.json
- [List Genies](https://docs.stacksync.com/api-reference/genies/list_genies)
- [List Genie logs](https://docs.stacksync.com/api-reference/genies/list_genie_logs)
- [Get a Genie](https://docs.stacksync.com/api-reference/genies/get_genie)
- [Update a Genie](https://docs.stacksync.com/api-reference/genies/update_genie)
- [Delete a Genie](https://docs.stacksync.com/api-reference/genies/delete_genie)
- [Check a Genie email alias](https://docs.stacksync.com/api-reference/genies/check_genie_email_alias)