> For the complete documentation index, see [llms.txt](https://heyguest-ai.gitbook.io/heyguest/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://heyguest-ai.gitbook.io/heyguest/reference/assistants.md).

# Assistants

Manage **custom** voice assistants. This API never exposes preset hospitality assistants — reads and writes against non-custom UUIDs return `404`.

## GET /assistants/{uuid}

> Read a custom assistant

```json
{"openapi":"3.0.3","info":{"title":"HeyGuest External API","version":"1.1.0"},"tags":[{"name":"Assistants","description":"Manage **custom** voice assistants. This API never exposes preset hospitality\nassistants — reads and writes against non-custom UUIDs return `404`.\n"}],"servers":[{"url":"https://app.heyguest.ai/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Sanctum personal access token (team-scoped)"}},"schemas":{"Assistant":{"type":"object","description":"A custom voice assistant. The `prompt` field is shared between chat and\nvoice surfaces.\n","properties":{"uuid":{"type":"string","format":"uuid"},"name":{"type":"string"},"prompt":{"type":"string","nullable":true,"description":"The assistant's prompt. Applied to both chat and voice surfaces.\n"},"voice_provider":{"type":"string","enum":["cartesia","elevenlabs"],"description":"TTS provider. Defaults to `elevenlabs` when omitted on create."},"voice_id":{"type":"string","nullable":true,"description":"Provider-specific voice ID."},"stt_language":{"type":"string","nullable":true,"description":"Speech-to-text language tag (e.g. `en-GB`, `en-US`, `fr-FR`).\nDefaults to `en-GB` when omitted on create.\n"},"hangup_tool":{"type":"boolean","description":"Whether the assistant can end a call. Default `true`."},"update_slots_tool":{"type":"boolean","description":"Whether the assistant captures structured variables during the call.\nDefault `false` — opt in if you want `variables` populated on the\ncalls endpoint.\n"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"paths":{"/assistants/{uuid}":{"get":{"tags":["Assistants"],"summary":"Read a custom assistant","operationId":"getAssistant","responses":{"200":{"description":"Assistant.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Assistant"}}}}}},"404":{"description":"UUID not found, not a custom assistant, not in your team, or\nsoft-deleted.\n"}}}}}}
```

## Create or update a custom assistant

> Upserts a custom assistant under a \*\*client-supplied UUID\*\*. Use any UUID\
> you control (e.g. your tenant ID).\
> \
> \- \*\*Idempotent.\*\* Repeating the same request is safe — the second call\
> &#x20; updates instead of creating a duplicate.\
> \- \*\*Partial updates.\*\* Send only the fields you want to change. Omitted\
> &#x20; fields are left untouched.\
> \- \*\*Restores soft-deleted assistants.\*\* If a UUID was previously deleted,\
> &#x20; the next upsert restores it.\
> \- The \`prompt\` field is mirrored to both chat and voice surfaces.\
> \- UUIDs are globally unique across HeyGuest. If the UUID already exists\
> &#x20; but is not a custom assistant in your team (preset, or owned by another\
> &#x20; team), the response is \`404\`.<br>

```json
{"openapi":"3.0.3","info":{"title":"HeyGuest External API","version":"1.1.0"},"tags":[{"name":"Assistants","description":"Manage **custom** voice assistants. This API never exposes preset hospitality\nassistants — reads and writes against non-custom UUIDs return `404`.\n"}],"servers":[{"url":"https://app.heyguest.ai/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Sanctum personal access token (team-scoped)"}},"schemas":{"AssistantWritable":{"type":"object","description":"Body for `POST /assistants/{uuid}`. `prompt` is required on first create\nand optional on update. Fields not listed below are rejected with `422`.\n","properties":{"name":{"type":"string","maxLength":255,"description":"Defaults to `Assistant {first-8-chars-of-uuid}` when omitted on create.\n"},"prompt":{"type":"string","description":"Required on first create. Optional on update. Applied to both chat\nand voice surfaces.\n"},"voice_provider":{"type":"string","enum":["cartesia","elevenlabs"],"description":"Defaults to `elevenlabs` when omitted on create."},"voice_id":{"type":"string","nullable":true,"maxLength":255},"stt_language":{"type":"string","maxLength":16,"description":"e.g. `en-GB`, `en-US`, `fr-FR`. Defaults to `en-GB` when omitted on create."},"hangup_tool":{"type":"boolean"},"update_slots_tool":{"type":"boolean"}}},"Assistant":{"type":"object","description":"A custom voice assistant. The `prompt` field is shared between chat and\nvoice surfaces.\n","properties":{"uuid":{"type":"string","format":"uuid"},"name":{"type":"string"},"prompt":{"type":"string","nullable":true,"description":"The assistant's prompt. Applied to both chat and voice surfaces.\n"},"voice_provider":{"type":"string","enum":["cartesia","elevenlabs"],"description":"TTS provider. Defaults to `elevenlabs` when omitted on create."},"voice_id":{"type":"string","nullable":true,"description":"Provider-specific voice ID."},"stt_language":{"type":"string","nullable":true,"description":"Speech-to-text language tag (e.g. `en-GB`, `en-US`, `fr-FR`).\nDefaults to `en-GB` when omitted on create.\n"},"hangup_tool":{"type":"boolean","description":"Whether the assistant can end a call. Default `true`."},"update_slots_tool":{"type":"boolean","description":"Whether the assistant captures structured variables during the call.\nDefault `false` — opt in if you want `variables` populated on the\ncalls endpoint.\n"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ValidationError":{"type":"object","properties":{"errors":{"type":"object","description":"Map of field name → array of error messages.","additionalProperties":{"type":"array","items":{"type":"string"}}}}}}},"paths":{"/assistants/{uuid}":{"post":{"tags":["Assistants"],"summary":"Create or update a custom assistant","description":"Upserts a custom assistant under a **client-supplied UUID**. Use any UUID\nyou control (e.g. your tenant ID).\n\n- **Idempotent.** Repeating the same request is safe — the second call\n  updates instead of creating a duplicate.\n- **Partial updates.** Send only the fields you want to change. Omitted\n  fields are left untouched.\n- **Restores soft-deleted assistants.** If a UUID was previously deleted,\n  the next upsert restores it.\n- The `prompt` field is mirrored to both chat and voice surfaces.\n- UUIDs are globally unique across HeyGuest. If the UUID already exists\n  but is not a custom assistant in your team (preset, or owned by another\n  team), the response is `404`.\n","operationId":"upsertAssistant","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantWritable"}}}},"responses":{"200":{"description":"Existing assistant updated (or trashed assistant restored).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Assistant"}}}}}},"201":{"description":"Assistant created.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Assistant"}}}}}},"404":{"description":"The UUID exists but is not a custom assistant in your team (preset,\nor owned by another team). The existing row is not modified.\n"},"422":{"description":"Validation failed — missing `prompt` on first create, invalid\n`voice_provider`, an unknown field, etc.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}}}}
```
