Ir al contenido

API REST

Shara expone una API REST sobre HTTPS para integraciones programáticas. El host es https://api.sharasaas.com, las respuestas son JSON y la autenticación de servicio se hace con una API key con scopes. Está en beta privada y se abre con la disponibilidad general (GA). Esta página es la referencia técnica de autenticación, endpoints, errores, límites y SDKs.

La API es REST sobre HTTPS. El host es https://api.sharasaas.com. No todos los endpoints cuelgan de un prefijo /v1 uniforme: la invocación de agentes y el bridge MCP sí lo llevan (/v1/inference, /v1/mcp/…), mientras que la gestión de claves, los runs y el consumo viven en la raíz (/tenants/me/api-keys, /me/api-keys, /runs, /usage/current) Esta página usa siempre la ruta completa y real de cada endpoint. El cuerpo de las peticiones y las respuestas son JSON (Content-Type: application/json), salvo el modo streaming, que devuelve Server-Sent Events (text/event-stream).

Una API key solo sirve en dos superficies: POST /v1/inference y el bridge MCP. Todas las demás rutas de esta página (gestión de claves, runs, consumo) necesitan la sesión de un miembro con la sesión iniciada en la app; no aceptan API key.

Tres principios atraviesan toda la superficie pública: (1) los modelos se referencian siempre por alias musical (Prelude, Sonata, Symphony, Concerto) y nunca por su proveedor; (2) toda respuesta se pasa por un redactor antes de cruzar la red, de modo que ni los mensajes de error ni los volcados de herramientas filtran detalles internos; (3) la identidad de quien llama (tenant, usuario, agente) se deriva siempre de la credencial, nunca del cuerpo de la petición.

Propiedad Valor
Host https://api.sharasaas.com
Protocolo HTTPS obligatorio (TLS 1.2+)
Formato application/json · streaming en text/event-stream
Autenticación de servicio API key vía Authorization: Bearer <api-key> (solo POST /v1/inference y el bridge MCP)
Rate limit Ventana fija de 60 s · 60 peticiones por IP y ruta · 600 por workspace y ruta (ver cabeceras X-RateLimit-*)
Tamaño máximo del cuerpo 512 KB (413 request_too_large por encima)
Trazabilidad Cabecera X-Request-Id en toda respuesta

Versionado: la versión actual es v1. Cuando publiquemos cambios incompatibles lo haremos bajo un prefijo nuevo (/v2) y mantendremos /v1 en funcionamiento durante el periodo de deprecación anunciado.

Las integraciones de servidor se autentican con una API key de Shara. La generas en Ajustes → Seguridad (requiere rol de administración para las claves de empresa; si tu cuenta tiene verificación en dos pasos, hay que completarla en esa sesión) y se envía en cada petición con la cabecera estándar:

Authorization: Bearer shara_sk_live_TU_API_KEY

Formato de la clave: prefijo fijo shara_sk_live_ seguido de 24 caracteres base62 (38 caracteres en total). Solo se muestra el valor completo una única vez, en el momento de la creación: guárdalo en tu gestor de secretos. Después, el panel solo enseña el prefijo visible (shara_sk_live_ + 6 caracteres) para que la identifiques sin poder recuperar el secreto.

La verificación es robusta por diseño: la clave se busca por prefijo (solo se consideran claves activas, no expiradas y no revocadas) y el secreto se compara con su hash mediante una función de hashing robusta y comparación en tiempo constante. Una caché breve evita rehasheos en ráfaga sin debilitar la revocación.

Hay dos tipos de clave. Las claves de empresa son un principal de servicio del workspace y las limitan sus scopes. Las claves personales actúan como la persona que las creó, con su rol y su departamento, y nunca tienen más permisos que ella.

Cada API key lleva uno o más scopes que delimitan lo que puede hacer. Concede siempre el mínimo necesario (principio de menor privilegio). Estos son los scopes que hoy comprueba alguna ruta:

Scope Permite
amadeus:invoke Invocar cualquier agente vía POST /v1/inference, el endpoint único de invocación (dirige al orquestador Amadeus o a un agente concreto según agentSlug).
amadeus:invoke:agent:<slug> Variante granular: restringe la clave a un único agente por su slug. Puedes añadir varios.
mcp:tenant Acceso al bridge MCP por tenant (herramientas vía SSE/JSON-RPC). Tiene que aparecer literalmente en la clave; los comodines no lo conceden.
workspace:all Atajo disponible solo en claves de empresa: se expande a todo el catálogo de scopes de empresa.

El creador de claves puede listar otros nombres de scope de su catálogo, pero ninguna ruta de API key los exige hoy, así que no conceden nada. El comodín recurso:* se expande a los scopes de ese recurso en el catálogo; amadeus:* se expande a amadeus:invoke (no añade los scopes por agente). El comodín total *:* no se acepta al crear una clave. Si una clave no puede invocar en absoluto recibes 403 scope_required; si puede invocar pero no el agente pedido, 403 agent_scope_required (con agentSlug y un message que nombra el scope que falta). Las claves de empresa que invocan agentes (amadeus:*, workspace:all) solo las pueden crear o rotar owner, ceo o admin (ceo es un alias heredado de owner); si no, recibes 403 scope_forbidden.

Gestiona las claves desde estos endpoints. Requieren una sesión iniciada, no una API key.

Método Ruta Qué hace
GET /tenants/me/api-keys Lista las claves de empresa (sin secreto ni hash). Roles owner, ceo, admin y admin_it.
POST /tenants/me/api-keys Crea una clave de empresa; devuelve el secreto una sola vez.
POST /tenants/me/api-keys/{id}/rotate Emite una clave nueva con el mismo nombre y los mismos scopes y revoca la anterior.
DELETE /tenants/me/api-keys/{id} Revoca de inmediato (soft-delete).
GET /tenants/me/api-keys/scopes Catálogo de scopes de las claves de empresa.
GET / POST /me/api-keys Lista / crea claves personales (cualquier miembro con sesión, solo las suyas; máximo 20 activas).
POST / DELETE /me/api-keys/{id}/rotate · /me/api-keys/{id} Rota / revoca una clave personal.
GET /me/api-keys/scopes Catálogo de scopes de las claves personales.

/api-keys (y /api-keys/{id}/rotate, /api-keys/{id}) sigue existiendo como alias obsoleto de las rutas de empresa. Usa /tenants/me/api-keys en integraciones nuevas.

Cuerpo de creación: { "name": "...", "scopes": ["amadeus:invoke"], "expiresInDays": 90 } (name de 1 a 100 caracteres, de 1 a 100 scopes, expiresInDays entre 1 y 365). Las claves caducan a los 90 días por defecto y 365 días es el máximo. Solo las claves de empresa pueden usar "neverExpires": true (en lugar de expiresInDays); en una personal devuelve 400 never_expires_not_allowed. Otros errores de creación: 400 invalid_scope, 400 conflicting_expiry, 409 key_limit_reached.

La rotación no es sin cortes. El servidor revoca primero la clave anterior y solo después crea la nueva, así que durante un instante no vale ninguna, y la antigua deja de funcionar en el acto. La nueva conserva los mismos scopes y recibe la caducidad por defecto de 90 días (una clave de empresa que no caducaba sigue sin caducar). Para no cortar el servicio, crea la clave nueva, despliégala y después revoca la antigua.

El límite usa una ventana fija de 60 segundos con un contador por ruta: 60 peticiones por IP y ruta, y 600 peticiones por workspace y ruta una vez identificado quien llama. Cada respuesta incluye cabeceras para que tu cliente se autorregule (las del más estricto de los dos límites):

Cabecera Significado
X-RateLimit-Limit Tope de peticiones de la ventana actual.
X-RateLimit-Remaining Peticiones que te quedan en la ventana.
X-RateLimit-Reset Momento (epoch en segundos) en que se reinicia la ventana.
Retry-After Solo en 429: segundos a esperar antes de reintentar.
X-Request-Id Identificador único de la petición; se propaga en todas las respuestas.

Si superas el límite recibes 429 con { "error": "rate_limit_exceeded", "retryAfterSec": <n> } y la cabecera Retry-After. Respeta ese valor con backoff exponencial. Las sondas de salud (/livez, /healthz) están fuera de este límite y no llevan cabeceras X-RateLimit-*. Si tu integración necesita un techo mayor por workspace, escríbenos a soporte@aiginer.com. La cabecera X-Request-Id viaja en cada respuesta (si la envías tú, se reutiliza; si no, se genera): inclúyela siempre que abras una incidencia con soporte.

Resumen de la superficie que cubre esta página. Rutas completas sobre el host https://api.sharasaas.com (algunas llevan /v1, otras no; usa siempre la ruta tal cual aparece aquí).

Método Ruta Auth Qué hace
POST /v1/inference API key (o sesión de la app) Invoca un agente (Amadeus por defecto, o el que indiques en agentSlug). Síncrono: la respuesta ya trae el resultado.
GET /runs/{run_id} Solo sesión de la app (no con API key) Estado y detalle de una ejecución.
GET /runs Solo sesión de la app (no con API key) Lista paginada de ejecuciones.
GET /usage/current Solo sesión de la app (no con API key) Consumo (STU) del periodo: cuota, consumido, rollover.
GET /usage/timeseries · /usage/breakdown · /usage/by-agent · /usage/events Solo sesión de la app (no con API key) Consumo en el tiempo, por alias o herramienta, por agente, y la lista de eventos.
POST /runs/{id}/cancel Solo sesión de la app (no con API key) Cancela un run que espera aprobación.
GET /v1/mcp/tenant/sse Token MCP Transporte SSE del bridge MCP por tenant.
POST /v1/mcp/tenant/rpc Token MCP Canal JSON-RPC del bridge MCP por tenant.

El bridge MCP recibe la clave en la cabecera X-MCP-Tenant-Token o en Authorization: Bearer, y la clave debe llevar el scope mcp:tenant de forma literal. Sin un token válido responde 401 unauthorized; también puede responder 429 rate_limit_exceeded o 429 too_many_connections.

El orquestador del workspace se llama Amadeus: recibe tu petición, decide qué agente departamental la atiende y coordina el trabajo. Con agentSlug puedes dirigirte a Amadeus (por defecto, si lo omites) o a un agente concreto por su slug. No hay un catálogo público de agentes vía API todavía; consulta el catálogo de agentes de esta documentación para ver los slugs disponibles. El slug es el mismo con cualquier pack de nombres e imágenes (agentSlug: "patterson" vale con cualquier pack). Un agente elegible que tu empresa no ha elegido, o un adicional que no ha contratado, no está disponible para ella.

POST /v1/inference ejecuta el turno y responde en la misma llamada. Es el único endpoint de invocación: no hay una ruta por agente, sino un campo agentSlug en el cuerpo. Campos del cuerpo:

Campo Tipo Notas
alias string · obligatorio Uno de Prelude · Sonata · Symphony · Concerto.
messages array (1 a 100) · obligatorio { "role": "user"|"assistant"|"system", "content": "..." }; cada content de 1 a 500.000 caracteres (el cuerpo entero también está limitado a 512 KB).
agentSlug string · opcional Agente objetivo del turno (de 1 a 64 caracteres). Por defecto amadeus. Tu API key necesita el scope para ese agente.
powerMode string · opcional normal (defecto) o low.
maxTokens entero · opcional Entre 1 y 32.000.
effort string · opcional low · medium · high · x-high · max.
stream boolean · opcional Si es true, la respuesta llega por SSE.
conversationId string · opcional Agrupa varios turnos en un mismo hilo (hasta 200 caracteres).

Los alias Prelude, Sonata y Symphony son modelos en la nube de capacidad creciente: Prelude (ágil y económico), Sonata (equilibrio) y Symphony (el de más capacidad). Concerto es el modelo local del plan Concerto Local y gasta 0 STU. Elige según la complejidad de la tarea; el alias es lo único que se acepta para seleccionar modelo (nunca un nombre de proveedor). Un cuerpo que no pasa la validación devuelve 400 con error: "FST_ERR_VALIDATION".

La respuesta síncrona (200) tiene esta forma:

{
  "alias": "Sonata",
  "content": "Texto de la respuesta del agente…",
  "usage": {
    "inputTokens": 184,
    "outputTokens": 412
  },
  "status": "completed",
  "runId": "3f8a1c52-9d4e-4b7a-a1c3-5e2f7d9b0a64"
}
Campo Significado
status Cómo terminó el turno: completed, failed, blocked o canceled. Un turno failed o blocked sigue siendo HTTP 200: lee este campo, no solo el código de estado.
runId Opcional. Id del run creado para el turno (solo si quedó registrado).
toolOutcome Opcional. { "rejected": [...], "expired": [...] } con los nombres de las herramientas que una persona rechazó o que caducaron en el turno.
herramientasEjecutadas Opcional. Número de herramientas que se ejecutaron con éxito en el turno (solo si es mayor que 0).
blockedReason Opcional. Motivo, cuando el turno no se completó.
motivoDeCorte Opcional. Solo aparece cuando el run paró en un límite propio (pasos o gasto del turno) y no porque se rompiera algo: tope_de_pasos, tope_de_gasto o sin_cierre.

Dos nombres de campo están en español. herramientasEjecutadas y motivoDeCorte conservan su nombre en español en la API. Son estables: úsalos tal cual.

Con "stream": true la respuesta es text/event-stream. Recibes fragmentos incrementales como data: {"delta":"…"} y un evento de cierre end con el status final, el runId y el recuento de tokens. Cada fragmento pasa por el redactor antes de emitirse. El flujo puede traer también otros eventos con nombre (por ejemplo usage, con el avance, o error): ignora los que no uses.

data: {"delta":"Hola, "}

data: {"delta":"¿en qué "}

data: {"delta":"puedo ayudarte?"}

event: end
data: {"done":true,"status":"completed","runId":"3f8a1c52-9d4e-4b7a-a1c3-5e2f7d9b0a64","alias":"Sonata","usage":{"inputTokens":184,"outputTokens":412}}

GET /usage/current devuelve el estado del periodo en STU (la unidad de consumo de Shara). Funciona solo con la sesión de la app (no acepta API key) y es de lectura abierta para cualquier miembro del workspace. No expone cifras absolutas de dinero. Campos:

Campo Significado
plan, planName Slug del plan (first, pro, max, max_x5, max_x20, plan_local) y su nombre para mostrar.
year, month Etiqueta del periodo de facturación.
stuBase, stuRollover Cuota base (con los agentes adicionales incluidos) y rollover arrastrado.
stuConsumed, stuRemaining, pctConsumed Consumido, restante y porcentaje sobre base más rollover.
daysElapsed, daysInMonth, projectedMonthEnd, projectedPct Proyección lineal a fin de periodo.
status Semáforo: green (menos del 70 %), yellow (70 a 90 %), red (90 a 100 %), blown (100 % o más).
level Nivel de cuota: green, warning, critical, overage, grace, hardstop (ver STU, cuotas y gasto).
bannerMessage Texto para mostrar. Decide según level, no según este texto.
allowInference, forceLowSpending, overageBilling Qué implica el nivel actual.
resetAt Cuándo termina el periodo.
hasSnapshot Si el periodo ya tiene registro de uso.
activeAlerts Alertas activas del periodo.
additionalAgents, addonAgentSlugs Agentes adicionales contratados: cuántos y cuáles.
{
  "plan": "pro",
  "planName": "Pro",
  "year": 2026,
  "month": 6,
  "stuBase": 140000000,
  "stuRollover": 20000000,
  "stuConsumed": 60000000,
  "stuRemaining": 100000000,
  "pctConsumed": 37.5,
  "daysElapsed": 10,
  "daysInMonth": 30,
  "projectedMonthEnd": 180000000,
  "projectedPct": 112.5,
  "status": "green",
  "level": "green",
  "bannerMessage": "…",
  "allowInference": true,
  "forceLowSpending": false,
  "overageBilling": false,
  "resetAt": "2026-07-01T00:00:00.000Z",
  "hasSnapshot": true,
  "activeAlerts": [],
  "additionalAgents": 0,
  "addonAgentSlugs": []
}

Sin suscripción activa responde 403 no_active_subscription.

Estas rutas también piden una sesión de la app y están restringidas a las personas que pueden ver las cifras de la empresa (owner y administradores, y cuentas con Amadeus habilitado); el resto recibe 403 role_forbidden. Las fechas son AAAA-MM-DD; si las omites se usa el periodo actual. A diferencia de /usage/current, incluyen billableCents (céntimos de euro).

Ruta Parámetros Devuelve
GET /usage/timeseries from, to, groupBy: day (por defecto), alias o agent_slug { from, to, groupBy, points: [{ day, key, stuConsumed, billableCents, eventCount }] }
GET /usage/breakdown from, to, groupBy: alias o tool_name { from, to, totalStu, items: [{ key, stuConsumed, billableCents, eventCount, pctOfTotal }] }
GET /usage/by-agent from, to { from, to, totalStu, totalCents, items: [{ agentSlug, stuConsumed, billableCents, runCount, pctOfTotal }] }
GET /usage/events from, to, limit (1 a 10.000) { from, to, events: [...] }, una entrada por evento de uso (alias, tokens, STU, herramienta, modo de potencia). Pensado para exportar a CSV.

POST /v1/inference es síncrono, así que no necesitas sondear para obtener el resultado. Los runs son el historial de esas ejecuciones y se consultan solo con la sesión de la app (GET /runs y GET /runs/{run_id} no aceptan API key). El status de un run toma uno de estos valores:

status Significado
in_progress El run sigue ejecutándose.
completed Terminó con éxito.
failed Terminó con error. El detalle lleva el motivo (redactado).
canceled Cancelado antes de terminar.
suspended Aparcado, esperando que alguien apruebe una acción. Se puede cancelar con POST /runs/{id}/cancel.

GET /runs lista ejecuciones con estos filtros: status, agent_slug (≤64 caracteres), includeInternal (true muestra también los runs internos del sistema, que por defecto se ocultan), limit (1 a 100) y offset (≥0); la respuesta incluye total para paginar. GET /runs/{run_id} devuelve { run, steps[], toolCalls[] }; si el run no existe o no es visible para ti, recibes 404 run_not_found. Lo que ves depende de tu rol: los miembros que no pueden ver todo el workspace solo ven sus propios runs. Solo se devuelve contenido redactado: nunca material en bruto de los proveedores.

POST /runs/{id}/cancel cancela un run que está esperando aprobación (estado suspended) y devuelve { ok: true, run }. Un run en cualquier otro estado responde 409 run_not_cancelable; uno que no existe o no es tuyo, 404 run_not_found.

Todos los errores son JSON con un campo error (una cadena estable, pensada para tu lógica) y, opcionalmente, message (un texto legible). Los errores que pasan por el manejador global (fallos de validación, cuerpo vacío, cuerpos fragmentados demasiado grandes, fallos inesperados) llevan además requestId; la cabecera X-Request-Id está siempre presente. Nunca parsees message: decide por error. Forma canónica:

{
  "error": "cadena_en_snake_case",
  "message": "Descripción legible (opcional).",
  "requestId": "req-a1b2c3"
}

Una ruta que no existe responde con la forma del framework: { "message": "Route not found", "error": "Not Found", "statusCode": 404 }.

Catálogo de códigos públicos verificados:

error HTTP Cuándo
missing_bearer 401 Falta la cabecera Authorization: Bearer ….
invalid_token 401 Token de sesión inválido o caducado.
unknown_user 401 Token de sesión válido, pero el usuario no existe.
tenant_unresolved 401 No se pudo resolver el workspace de quien llama.
not_authenticated 401 Sin sesión/credencial válida en una ruta que la exige.
api_key_not_found 401 API key con prefijo desconocido, revocada o caducada.
api_key_not_found 404 En las rutas de gestión de claves: ese id de clave no existe o no es tuyo.
already_revoked 409 La clave que revocas o rotas ya estaba revocada.
api_key_invalid 401 API key cuyo hash no verifica.
payment_not_completed 402 El pago del checkout no se ha completado.
tenant_forbidden 403 Autenticado, pero sin pertenencia al tenant pedido.
forbidden / role_forbidden 403 La acción no está permitida para tu rol/clave.
no_active_subscription 403 El workspace no tiene suscripción activa.
scope_required 403 La API key no puede invocar (message indica el scope que falta).
agent_scope_required 403 La clave puede invocar, pero no este agente. Extra: agentSlug.
agent_disabled 403 El agente está en pausa. Extra: agentSlug, reason.
agent_unknown 403 El agentSlug no existe. Extra: agentSlug.
agent_not_in_plan 403 El agente no está disponible para tu empresa en tu plan. Extra: agentSlug.
agent_not_purchased 403 Agente adicional que no está contratado en esta cuenta. Extra: agentSlug.
agent_not_allowed 403 El agente no pertenece a tu departamento. Extra: agentSlug.
not_a_member 403 No eres miembro del tenant del agente. Extra: agentSlug.
agent_slug_required 400 Un miembro con sesión que no puede usar Amadeus debe enviar agentSlug.
FST_ERR_VALIDATION 400 El cuerpo o los parámetros no pasan la validación (por ejemplo en /v1/inference).
invalid_request / invalid_body 400 Cuerpo o parámetros que no pasan la validación en otras rutas.
empty_body 400 Petición JSON con el cuerpo vacío.
not_found 404 El recurso no existe o no es visible para ti.
expired 410 Token/enlace de un solo uso ya caducado.
request_too_large 413 El cuerpo supera el límite (512 KB). Extra: limitBytes.
alias_plan_mismatch 422 Pediste un alias de modelo por encima del techo de tu plan (por ejemplo Sonata en First o Symphony en Pro). Pide uno inferior.
run_not_cancelable 409 Solo se puede cancelar un run que espera aprobación.
quota_exceeded 429 Cuota de STU agotada (hardstop). Extra: policy, pctConsumed, resetAt.
kill_switch 429 Corte de gasto activo. Extra: kind, observedCents, thresholdCents, activeSince?.
rate_limit_exceeded 429 Límite de peticiones superado. Extra: retryAfterSec + Retry-After.
too_many_attempts 429 Demasiados intentos fallidos; espera antes de reintentar.
internal_error 500 Error inesperado del servidor. Incluye requestId.
provider_unavailable 503 El modelo que hay tras el alias no está disponible ahora. Reintenta con backoff.
kill_switch_engine_error 503 No se pudo completar la comprobación de gasto, así que la petición no se ejecutó. Reintenta en unos segundos.

Algunos 404 son más específicos del recurso (run_not_found, agent_not_found, member_not_found…), todos con la misma forma. Para la lógica de tu cliente puedes tratar cualquier *_not_found como «el recurso no existe».

Varios errores llevan campos extra para que tu cliente reaccione sin una segunda llamada. Cuota agotada (solo ocurre en el nivel hardstop, a partir del 200 % de tu cuota):

{
  "error": "quota_exceeded",
  "policy": "hardstop",
  "pctConsumed": 203.5,
  "resetAt": "2026-07-01T00:00:00.000Z"
}

Corte de gasto (kill switch). Los topes se fijan en STU: por defecto 1 M por ejecución, 10 M por hora y 80 M por día (a la tarifa de 5 € por millón, 500, 5.000 y 40.000 céntimos de euro). Un owner o administrador puede editar cada uno o desactivarlo. observedCents y thresholdCents son cadenas con el importe facturable en céntimos de euro:

{
  "error": "kill_switch",
  "kind": "day",
  "observedCents": "41250",
  "thresholdCents": "40000",
  "message": "…",
  "activeSince": "2026-06-16T08:12:00.000Z"
}

kind indica el ámbito del interruptor: run · hour · day · manual. Ante un 429, respeta Retry-After/resetAt y reintenta con backoff; ante un 5xx, reintenta con backoff e incluye el requestId si abres una incidencia.

Recetas completas sobre el host https://api.sharasaas.com. Sustituye shara_sk_live_… por tu API key.

curl -sS https://api.sharasaas.com/v1/inference \
  -H "Authorization: Bearer shara_sk_live_TU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Sonata",
    "agentSlug": "amadeus",
    "messages": [
      { "role": "user", "content": "Resume las novedades de soporte de esta semana." }
    ],
    "effort": "medium"
  }'
import requests

BASE = "https://api.sharasaas.com"
API_KEY = "shara_sk_live_TU_API_KEY"

resp = requests.post(
    f"{BASE}/v1/inference",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "alias": "Sonata",
        "agentSlug": "amadeus",
        "messages": [
            {"role": "user", "content": "Resume las novedades de soporte de esta semana."}
        ],
        "effort": "medium",
    },
)
resp.raise_for_status()
data = resp.json()
print(data["status"], data["content"])  # el resultado viene en esta misma respuesta
const BASE = 'https://api.sharasaas.com';
const API_KEY = process.env.SHARA_API_KEY; // nunca en el navegador

const res = await fetch(`${BASE}/v1/inference`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    alias: 'Sonata',
    agentSlug: 'amadeus',
    messages: [
      { role: 'user', content: 'Resume las novedades de soporte de esta semana.' },
    ],
    effort: 'medium',
  }),
});

if (!res.ok) throw new Error(`HTTP ${res.status}: ${(await res.json()).error}`);
const data = await res.json();
console.log(data.status, data.content);

Shara tiene su propio servidor MCP, en https://mcp.sharasaas.com, para que uses la información de tu empresa desde Cursor, Windsurf o cualquier otro cliente MCP. Expone tres cosas: los indicadores de tu empresa, la memoria de la empresa y escalar un asunto a un agente. Lo que escribe espera tu aprobación, como cualquier otra acción en Shara.

El propietario, un administrador o TI crea el token en Ajustes → MCP. Nadie más puede. Después añades Shara a tu cliente con la dirección del servidor y el token en una cabecera Authorization (el fichero exacto depende del cliente; en Cursor es mcp.json):

{
  "mcpServers": {
    "shara": {
      "url": "https://mcp.sharasaas.com",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

Trata el token como una contraseña: no lo pegues en un repositorio ni lo compartas.

Con la disponibilidad general (GA) publicaremos SDKs oficiales para Node.js / TypeScript y Python, además de los ejemplos con curl de esta página. Hasta entonces sirve cualquier cliente HTTP estándar: la API es REST plana, con cabeceras estándar y JSON. Consulta SDK y ejemplos.

¿Quieres acceso anticipado a la API? Escribe a api@aiginer.com con tu caso de uso, o a soporte@aiginer.com para subir tu límite de peticiones por workspace.