Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sdurutr436/stay-sidekick/llms.txt

Use this file to discover all available pages before exploring further.

The Communications Vault is a centralised library of message templates scoped per company. Templates are organised by category (e.g., BIENVENIDA, CHECKIN_TARDIO, INCIDENCIA) and by language. Two AI-powered endpoints let you improve the wording of existing content or generate translated versions — using either the platform’s shared AI quota or your own API key (BYOK).
All endpoints require Authorization: Bearer <token>. POST, PUT, and DELETE requests also require the X-CSRF-Token header.

GET /api/vault/plantillas

Lists all active templates belonging to the authenticated user’s company. Supports optional filtering by category and language. Auth required: Yes | Role: any

Query Parameters

categoria
string
Filter by category. One of: BIENVENIDA, INSTRUCCIONES, RECORDATORIO, CHECKIN_TARDIO, CHECKOUT, INCIDENCIA, GENERAL.
idioma
string
Filter by language code. One of: es, en, fr, de, it, pt.

Response

ok
boolean
required
true
plantillas
array
required
Array of template objects.

Example

curl "https://api.example.com/api/vault/plantillas?categoria=BIENVENIDA&idioma=es" \
  -H "Authorization: Bearer $TOKEN"
{
  "ok": true,
  "plantillas": [
    {
      "id": "c3d4e5f6-0000-4000-a000-000000000001",
      "nombre": "Bienvenida estándar ES",
      "contenido": "Bienvenido a tu apartamento. El código de acceso es {{codigo}}.",
      "idioma": "es",
      "categoria": "BIENVENIDA",
      "activa": true
    }
  ]
}

POST /api/vault/plantillas

Creates a new communication template. HTML and script injection are stripped by the server before persisting. Auth required: Yes | Role: any

Request

nombre
string
required
Template display name. 1–200 characters.
contenido
string
required
Template body text. Must not be empty.
idioma
string
Language code. One of: es, en, fr, de, it, pt. Defaults to es.
categoria
string | null
Category slug. One of: BIENVENIDA, INSTRUCCIONES, RECORDATORIO, CHECKIN_TARDIO, CHECKOUT, INCIDENCIA, GENERAL. Pass null for uncategorised.

Response

201 Created
ok
boolean
required
true
plantilla
object
required
The newly created template object.

Example

curl -X POST https://api.example.com/api/vault/plantillas \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CSRF-Token: <csrf>" \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "Checkout reminder EN",
    "contenido": "Hi! Just a reminder that checkout is at 11:00. See you soon!",
    "idioma": "en",
    "categoria": "CHECKOUT"
  }'
{
  "ok": true,
  "plantilla": {
    "id": "d4e5f6a7-0000-4000-a000-000000000002",
    "nombre": "Checkout reminder EN",
    "contenido": "Hi! Just a reminder that checkout is at 11:00. See you soon!",
    "idioma": "en",
    "categoria": "CHECKOUT",
    "activa": true
  }
}

PUT /api/vault/plantillas/<id>

Replaces the content of an existing template. Both nombre and contenido are required — this is a full replacement, not a partial patch. Auth required: Yes | Role: any

Path Parameters

id
string
required
UUID of the template to update.

Request

nombre
string
required
New display name. 1–200 characters.
contenido
string
required
New body text. Must not be empty.
idioma
string
Language code. One of: es, en, fr, de, it, pt.
categoria
string | null
Category slug or null to remove the category.

Response

ok
boolean
required
true
plantilla
object
required
The updated template object.

Example

curl -X PUT https://api.example.com/api/vault/plantillas/d4e5f6a7-0000-4000-a000-000000000002 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CSRF-Token: <csrf>" \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "Checkout reminder EN (updated)",
    "contenido": "Hi! Checkout is at 11:00 today. Thank you for staying with us!",
    "idioma": "en",
    "categoria": "CHECKOUT"
  }'

DELETE /api/vault/plantillas/<id>

Soft-deletes a template. The record is marked as inactive and no longer appears in list responses, but it is not permanently removed. Auth required: Yes | Role: any

Path Parameters

id
string
required
UUID of the template to deactivate.

Response

200 OK{"ok": true} 404 Not Found — template not found or belongs to another company.

Example

curl -X DELETE https://api.example.com/api/vault/plantillas/d4e5f6a7-0000-4000-a000-000000000002 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CSRF-Token: <csrf>"

POST /api/vault/plantillas/<id>/mejoras

Sends the template content to the AI service and returns an improved version. The template is not automatically updated — the caller decides whether to apply the suggestion via a subsequent PUT. Auth required: Yes | Role: any
The AI service uses either the platform’s shared quota (subject to daily/weekly limits) or the company’s own API key configured in Perfil → IA. If limits are exceeded the endpoint returns 429.

Path Parameters

id
string
required
UUID of the template to improve.

Request

contenido
string
required
The text to improve. Must not be empty. Does not need to match the stored template body — you can pass a draft.
idioma
string
required
Language of the content. One of: es, en, fr, de, it, pt.
tono
string | null
Desired tone for the rewrite. One of: clasico, cercano, entusiasta, minimalista. Pass null for a neutral improvement.

Response

ok
boolean
required
true
contenido
string
required
The AI-improved version of the text.

AI Error Responses

StatusErrorMeaning
429LIMIT_DAILYDaily shared AI quota exhausted. Configure your own API key.
429LIMIT_WEEKLYWeekly shared AI quota exhausted.
429RATE_LIMIT_SYSTEMUpstream AI provider is rate-limiting the platform. Retry in a few minutes.
429RATE_LIMIT_BYOKYour own AI provider rejected the request. Retry in a few minutes.
504timeoutThe AI service took too long to respond.
502unexpectedUnexpected error contacting the AI service.

Example

curl -X POST https://api.example.com/api/vault/plantillas/c3d4e5f6-0000-4000-a000-000000000001/mejoras \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CSRF-Token: <csrf>" \
  -H "Content-Type: application/json" \
  -d '{
    "contenido": "Bienvenido. Aqui esta el codigo de acceso.",
    "idioma": "es",
    "tono": "cercano"
  }'
{
  "ok": true,
  "contenido": "¡Bienvenido! 🏠 Aquí tienes tu código de acceso: {{codigo}}. No dudes en escribirnos si necesitas cualquier cosa."
}

POST /api/vault/plantillas/<id>/traducciones

Translates the provided template content into the target language using the AI service. The original template is not modified. Auth required: Yes | Role: any

Path Parameters

id
string
required
UUID of the template to translate.

Request

contenido
string
required
The source text to translate. Must not be empty.
idioma_destino
string
required
Target language code. One of: es, en, fr, de, it, pt.

Response

ok
boolean
required
true
contenido
string
required
The translated text in the target language.

AI Error Responses

StatusErrorMeaning
429LIMIT_DAILYDaily shared AI quota exhausted. Configure your own API key.
429LIMIT_WEEKLYWeekly shared AI quota exhausted.
429RATE_LIMIT_SYSTEMUpstream AI provider is rate-limiting the platform. Retry in a few minutes.
429RATE_LIMIT_BYOKYour own AI provider rejected the request. Retry in a few minutes.
504timeoutThe AI service took too long to respond.
502unexpectedUnexpected error contacting the AI service.

Example

curl -X POST https://api.example.com/api/vault/plantillas/c3d4e5f6-0000-4000-a000-000000000001/traducciones \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CSRF-Token: <csrf>" \
  -H "Content-Type: application/json" \
  -d '{
    "contenido": "Bienvenido a tu apartamento. El código de acceso es {{codigo}}.",
    "idioma_destino": "en"
  }'
{
  "ok": true,
  "contenido": "Welcome to your apartment. The access code is {{codigo}}."
}

GET /api/ai/uso

Returns the current AI usage counters for the company — useful for displaying quota consumption in the UI. Auth required: Yes | Role: any

Response

ok
boolean
required
true
uso_diario
integer
required
Number of AI calls made today.
limite_diario
integer | null
required
Daily call limit. null if using BYOK with no limit.
uso_semanal
integer
required
Number of AI calls made this week.
limite_semanal
integer | null
required
Weekly call limit. null if using BYOK.
modo
string
required
"sistema" (shared quota) or "byok" (own API key).

Example

curl https://api.example.com/api/ai/uso \
  -H "Authorization: Bearer $TOKEN"
{
  "ok": true,
  "uso_diario": 7,
  "limite_diario": 20,
  "uso_semanal": 42,
  "limite_semanal": 100,
  "modo": "sistema"
}

GET /api/ai/config

Returns the AI integration configuration for the company. The API key is masked — only the first 4 and last 4 characters are shown. Auth required: Yes | Role: admin

Response

ok
boolean
required
true
data
object
required
AI configuration summary.

Example

curl https://api.example.com/api/ai/config \
  -H "Authorization: Bearer $TOKEN"
{
  "ok": true,
  "data": {
    "configurado": true,
    "proveedor": "openai",
    "modelo": "gpt-4o",
    "api_key_masked": "sk-l****9z3k"
  }
}

GET /api/admin/system-prompts/<nombre>

Reads a stored AI system prompt by name. Used to inspect the prompt text currently in use for a given AI operation. Auth required: No JWT — IP allowlist only (internal infrastructure endpoint)
Role: n/a

Path Parameters

nombre
string
required
Name identifier of the system prompt (e.g., mejorar, traducir).

Response

ok
boolean
required
true
nombre
string
required
Name of the system prompt.
contenido
string
required
Current system prompt text.
404 Not Found — no system prompt exists with the given name.

PUT /api/admin/system-prompts/<nombre>

Creates or replaces an AI system prompt. After saving, the in-memory cache for the affected prompt is invalidated immediately so all subsequent AI calls use the updated text. Auth required: No JWT — IP allowlist only (internal infrastructure endpoint)
Role: n/a

Path Parameters

nombre
string
required
Name identifier of the system prompt to upsert.

Request

contenido
string
required
New system prompt text. Must not be empty.

Response

200 OK{"ok": true} 422 Unprocessable Entitycontenido is missing or empty.

Build docs developers (and LLMs) love