{"openapi":"3.1.0","info":{"title":"Atmos API","version":"1.0.0","description":"# API pública de Atmos\n\nREST sobre `/api/v1/*`. Autenticación M2M con un **token de API** (`at-api-…`) emitido por\nun administrador del portal.\n\n## Autenticación\n\nCada petición lleva el token en la cabecera:\n\n```\nAuthorization: Bearer at-api-XXXX.sk_YYYY\n```\n\n(También se acepta `X-Api-Key: at-api-XXXX.sk_YYYY`.) El token tiene **su propio scope**\n(acciones CRUD por objeto + alcance de datos + acceso por campo), independiente del usuario\nque lo creó. Solo un administrador crea, edita o revoca tokens.\n\n## Quickstart\n\nListar contactos:\n\n```\ncurl https://app.atmos.com.mx/api/v1/contacts \\\n  -H \"Authorization: Bearer at-api-XXXX.sk_YYYY\"\n```\n\nCrear un contacto:\n\n```\ncurl -X POST https://app.atmos.com.mx/api/v1/contacts \\\n  -H \"Authorization: Bearer at-api-XXXX.sk_YYYY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"firstName\":\"Ada\",\"email\":\"ada@example.com\"}'\n```\n\nLos identificadores en URLs y payloads son **friendlyId** (C0001, N0002, …), nunca UUID.\n\n## Paginación\n\nLas listas y las búsquedas devuelven una página y un cursor:\n\n```json\n{\n  \"results\": [ { \"friendlyId\": \"C0001\", \"email\": \"ada@example.com\" } ],\n  \"paging\": { \"next\": { \"after\": \"eyJjcmVhdGVkQXQiOiI…\", \"link\": \"https://app.atmos.com.mx/api/v1/contacts?after=eyJ…\" } }\n}\n```\n\nSe pide la siguiente con `?after={cursor}`. **Cuando ya no hay más, `paging.next` no viene** —\nesa es la condición de fin, no un `results` vacío. El cursor va firmado: no se construye a mano.\n\n## Cuota y límites\n\nCada respuesta trae `X-RateLimit-Limit`, `X-RateLimit-Remaining` y `X-RateLimit-Reset`. Para\nconsultarlo **sin gastar una llamada de negocio** —y no enterarte con el primer `429`:\n\n```\nGET https://app.atmos.com.mx/api/v1/usage\n```\n\nDevuelve el nombre del token, su **modo** (`live`/`test`), su **alcance de datos**, los\n**objetos** a los que da acceso y `usage` con lo que queda de la cubeta de ráfaga y de la\ndiaria. `usage` puede venir en `null` si el contador de límites no está disponible: en ese caso\nguíate por las cabeceras `X-RateLimit-*` de cualquier respuesta.\n\n## Reintentos e idempotencia\n\nLos lotes de **`create` y `upsert`** aceptan la cabecera **`Idempotency-Key`** (cualquier cadena\núnica que elijas, p.ej. un UUID por lote):\n\n```\nPOST https://app.atmos.com.mx/api/v1/contacts/batch/create\nIdempotency-Key: 7f1c…\n```\n\nSi se corta la red y **reintentas** con la misma clave, Atmos devuelve el resultado de la\nprimera ejecución en vez de crear todo dos veces. La clave se recuerda **24 horas**.\n\nAlcance exacto, para que no te sorprenda: protege **reintentos secuenciales**, que es el caso\nreal (falla la red, vuelves a intentar). Dos peticiones **simultáneas** con la misma clave sí\npueden ejecutarse las dos — no hay bloqueo. No la uses para paralelizar el mismo lote.\n\n## Tokens de prueba\n\nUn token puede crearse en **modo prueba** (`test`). Funciona igual, con su **propia cubeta de\nlímites**, y sus llamadas quedan marcadas como de prueba. Sirve para desarrollar la integración\nsin ensuciar las métricas del token real. El modo se elige al crear el token y se consulta en\n`/v1/usage`.\n\n## Servidor MCP (Model Context Protocol)\n\nAdemás de REST, Atmos habla **MCP**: un asistente (Claude Desktop, Cursor, Cosmos) se conecta y\nopera el CRM con las mismas reglas del token. No es una API paralela — por dentro corre el mismo\nmotor, el mismo scope, el mismo alcance de datos y los mismos límites. Una llamada MCP cuenta\ncomo una llamada de API.\n\n- **Endpoint:** `https://app.atmos.com.mx/api/v1/mcp` (Streamable HTTP, JSON-RPC 2.0).\n- **Auth:** el mismo `Authorization: Bearer at-api-…`.\n- **Métodos:** `initialize`, `ping`, `tools/list`, `tools/call`.\n\nLas herramientas se **derivan del scope del token**: verás `list_`, `search_`, `get_`, `create_`,\n`update_` y `delete_` por cada objeto que el token tenga autorizado, y nada más — un token de\nsolo lectura no expone herramientas de escritura, así que el asistente no puede ni intentarlo.\n\nConfiguración típica en un cliente MCP:\n\n```json\n{\n  \"mcpServers\": {\n    \"atmos\": {\n      \"url\": \"https://app.atmos.com.mx/api/v1/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer at-api-XXXX.sk_YYYY\" }\n    }\n  }\n}\n```\n\nLos errores usan el envelope único con `correlationId` (ver \"Códigos de error\"), útil para\nsoporte: identifica la llamada exacta.\n\n## Integración web (pixel de seguimiento + formularios)\n\nLo que casi siempre se quiere al conectar un sitio con Atmos. Nada de esto usa el token de\nAPI en el navegador.\n\n### 1. Pixel de seguimiento\n\nUna etiqueta en el `<head>` de todas las páginas del sitio:\n\n```html\n<script src=\"https://app.atmos.com.mx/api/public/track.js\"\n        data-workspace=\"XXXXXXXXX\"\n        async></script>\n```\n\n`data-workspace` es el **código de portal** (9 caracteres alfanuméricos); se ve en la URL del\nCRM. El script **no lleva token** y es seguro en el frontend: solo escribe, nunca lee datos.\n\nCaptura automáticamente: vistas de página (con `referrer` y parámetros `utm_*`), tiempo en\npágina, clicks y profundidad de scroll (mapas de calor), y un latido cada 30 s mientras la\npestaña está activa. Respeta **Do Not Track** (si el navegador lo pide, no envía nada) y\nsoporta **SPAs** (escucha `pushState`/`popstate`, no hace falta recargar). Los clicks sobre\n`input`, `textarea` y `select` se ignoran a propósito para no capturar datos personales.\n\nAPI de JavaScript disponible después de cargar:\n\n```js\n// Vincula la sesión anónima con un contacto (llamar tras un login o un envío de formulario)\nwindow.Atmos.identify({ email: 'ada@example.com' });\n\n// Evento propio\nwindow.Atmos.track('demo_solicitada', { plan: 'growth' });\n```\n\nTambién se identifica solo si la URL trae `?atmos_ct={token}` (los enlaces de campañas de\nAtmos lo añaden), lo que atribuye la visita al contacto correcto.\n\n### 2. Formularios\n\nDos caminos, en orden de preferencia:\n\n**a) Incrustar el formulario de Atmos** — una línea, sin backend propio. El formulario se\ncrea en el CRM (Formularios) y ya trae anti-bot, Turnstile, campos condicionales, deduplicado\nde contactos y disparo de automatizaciones:\n\n```html\n<div data-form=\"{slug-del-formulario}\" data-workspace=\"XXXXXXXXX\"></div>\n<script src=\"https://app.atmos.com.mx/embed.js\" async></script>\n```\n\n`data-form` es el **slug** del formulario (el mismo de su URL pública\n`app.atmos.com.mx/{portal}/forms/{slug}`). Se pueden incrustar varios en una misma página:\nel script monta todos los contenedores que tengan `data-form` + `data-workspace`.\n\n**b) Formulario propio del sitio** — cuando el diseño del formulario debe ser del sitio. El\nenvío va **a tu servidor**, y tu servidor llama a esta API:\n\n```\nPOST https://app.atmos.com.mx/api/v1/contacts\nAuthorization: Bearer at-api-XXXX.sk_YYYY\nContent-Type: application/json\n\n{\"firstName\":\"Ada\",\"lastName\":\"Lovelace\",\"email\":\"ada@example.com\",\"phone\":\"+52...\",\"source\":\"web\"}\n```\n\n⚠️ **El token `at-api-…` nunca va en el navegador.** Es un secreto M2M con el scope completo\nque le diste: publicado en el HTML o en un bundle de JavaScript, cualquiera puede leer y\nescribir en el portal. Debe vivir en una variable de entorno del servidor (route handler de\nNext.js, función serverless, backend propio) y el formulario postea a ese endpoint interno.\n\nDespués de un envío exitoso, llama a `window.Atmos.identify({ email })` en el cliente para\nque la navegación anónima previa quede atribuida al contacto recién creado.\n\n## Campos personalizados\n\nUn campo personalizado se usa **por su nombre interno**, igual que uno de fábrica. Si en\nConfiguración → Campos creaste `servicio`, en la API es `servicio`. Sin prefijos ni envoltorios.\n\nConsulta los campos de un objeto —de fábrica y personalizados— con:\n\n```\nGET /api/v1/properties/contact\n```\n\nEl `key` de cada campo es **exactamente** el nombre que se usa para escribirlo y leerlo:\n\n```\nPOST /api/v1/contacts\n{\"email\":\"ada@example.com\",\"servicio\":\"Consultoría\",\"presupuesto\":15000}\n\nGET /api/v1/contacts/C0001\n→ {\"friendlyId\":\"C0001\",\"email\":\"ada@example.com\",\"servicio\":\"Consultoría\",\"presupuesto\":15000,…}\n```\n\nFuncionan igual en `?fields=` (`?fields=email,servicio`), en la **búsqueda** y en la\n**importación**:\n\n```\nPOST /api/v1/contacts/search\n{\"filterGroups\":[{\"filters\":[{\"field\":\"servicio\",\"operator\":\"eq\",\"value\":\"Consultoría\"}]}]}\n```\n\nDetalles a tener en cuenta:\n\n- **Tipos.** Un campo numérico devuelve un número; los de fecha, texto en formato `YYYY-MM-DD`.\n- **Operadores de búsqueda.** Texto y desplegables: `eq`, `neq`, `in`, `nin`, `contains`,\n  `startsWith`. Números y fechas: además `gt`, `gte`, `lt`, `lte`, `between`. Todos aceptan\n  `isNull`/`isNotNull`, que también cubren al registro que **no tiene** ese campo lleno.\n- **Nombres reservados.** No se puede crear un campo personalizado con el nombre de uno de\n  fábrica del mismo objeto (`email`, `phone`, `status`…): un nombre identifica a un solo campo.\n- **Acceso.** Un campo restringido por permisos no se devuelve (o llega como `****` si así se\n  configuró), y **filtrar por él responde 403** en vez de ignorar el filtro en silencio."},"servers":[{"url":"https://app.atmos.com.mx"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Token de API `{keyId}.{secret}` (at-api-…)"},"apiKey":{"type":"apiKey","in":"header","name":"X-Api-Key"}},"schemas":{"ApiError":{"type":"object","required":["status","category","message"],"properties":{"status":{"type":"string","enum":["error"]},"category":{"type":"string","enum":["VALIDATION_ERROR","UNAUTHORIZED","FORBIDDEN","NOT_FOUND","CONFLICT","RATE_LIMITED","INTERNAL"]},"message":{"type":"string"},"correlationId":{"type":["string","null"]},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"paths":{"/v1/{object}":{"get":{"operationId":"listRecords","summary":"Lista registros de un objeto. Uno de: contacts, companies, deals, activities, tickets, projects, invoices, products, quotes, lists, forms, o el api_name de un objeto personalizado (#84) del portal.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}},{"name":"fields","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createRecord","summary":"Crea un registro. Los CAMPOS válidos dependen del portal: consúltalos en GET /v1/properties/{objectType} — el `key` de cada uno es el nombre que va en el body (los personalizados, por su nombre interno, sin prefijo). Objetos escribibles: contacts, companies, deals, activities, tickets, projects, invoices.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/{object}/{id}":{"get":{"operationId":"getRecord","summary":"Obtiene un registro por friendlyId.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"operationId":"updateRecord","summary":"Actualiza un registro por friendlyId (parcial: solo los campos enviados). Los campos válidos son los mismos de GET /v1/properties/{objectType}.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteRecord","summary":"Envía un registro a la papelera (soft delete).","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/{object}/search":{"post":{"operationId":"searchRecords","summary":"Búsqueda con filterGroups (OR entre grupos, AND dentro).","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"filterGroups":{"maxItems":10,"type":"array","items":{"type":"object","properties":{"filters":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1},"operator":{"type":"string","enum":["eq","neq","gt","gte","lt","lte","in","nin","contains","startsWith","isNull","isNotNull","between"]},"value":{"anyOf":[{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}]}},"required":["field","operator"],"additionalProperties":false}}},"required":["filters"],"additionalProperties":false}},"sorts":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1},"direction":{"default":"desc","type":"string","enum":["asc","desc"]}},"required":["field","direction"],"additionalProperties":false}},"fields":{"type":"array","items":{"type":"string","minLength":1}},"limit":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"after":{"type":"string"}},"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/{object}/batch/{op}":{"post":{"operationId":"batchRecords","summary":"Operación en lote (op: create|read|update|archive|upsert). 207 Multi-Status en éxito parcial.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"op","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"inputs":{"minItems":1,"maxItems":100,"type":"array","items":{}},"idProperty":{"type":"string","minLength":1}},"required":["inputs"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/{object}/{id}/permanent-delete":{"post":{"operationId":"permanentDeleteRecord","summary":"Borrado permanente / derecho al olvido (irreversible). Requiere { confirm: true }.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"confirm":{"type":"boolean","const":true}},"required":["confirm"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/{object}/{id}/associations/{toType}/{toId}":{"put":{"operationId":"associate","summary":"Vincula dos registros por su pivote nativo.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toType","in":"path","required":true,"schema":{"type":"string"}},{"name":"toId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"dissociate","summary":"Elimina el vínculo entre dos registros.","tags":["CRM"],"parameters":[{"name":"object","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toType","in":"path","required":true,"schema":{"type":"string"}},{"name":"toId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/users":{"get":{"operationId":"listUsers","summary":"Lista los miembros del portal.","tags":["Soporte"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/teams":{"get":{"operationId":"listTeams","summary":"Lista los equipos del portal.","tags":["Soporte"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/owners":{"get":{"operationId":"listOwners","summary":"Lista los usuarios asignables (owners).","tags":["Soporte"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/pipelines":{"get":{"operationId":"listPipelines","summary":"Lista los pipelines de negocios.","tags":["Soporte"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/pipelines/{id}/stages":{"get":{"operationId":"listStages","summary":"Lista las etapas de un pipeline.","tags":["Soporte"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/properties/{objectType}":{"get":{"operationId":"listProperties","summary":"Lista las definiciones de campo (default + custom) de un objeto.","tags":["Properties"],"parameters":[{"name":"objectType","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createProperty","summary":"Crea un campo personalizado.","tags":["Properties"],"parameters":[{"name":"objectType","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/properties/{objectType}/{fieldKey}":{"patch":{"operationId":"updateProperty","summary":"Edita un campo personalizado.","tags":["Properties"],"parameters":[{"name":"objectType","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldKey","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteProperty","summary":"Elimina un campo personalizado.","tags":["Properties"],"parameters":[{"name":"objectType","in":"path","required":true,"schema":{"type":"string"}},{"name":"fieldKey","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"Lista las suscripciones de webhooks.","tags":["Webhooks"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createWebhook","summary":"Crea una suscripción de webhook. Eventos válidos: contact.created, contact.updated, contact.deleted, company.created, company.updated, company.deleted, deal.created, deal.updated, deal.deleted, activity.created, activity.updated, activity.deleted, ticket.created, ticket.updated, ticket.deleted, project.created, project.updated, project.deleted, invoice.created, invoice.updated, invoice.deleted, product.created, product.updated, product.deleted, quote.created, quote.updated, quote.deleted, list.created, list.updated, list.deleted, form.created, form.updated, form.deleted.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"events":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string"}},"active":{"default":true,"type":"boolean"}},"required":["url","events","active"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/webhooks/{id}":{"get":{"operationId":"getWebhook","summary":"Obtiene una suscripción.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"operationId":"updateWebhook","summary":"Edita una suscripción.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"events":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string"}},"active":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteWebhook","summary":"Elimina una suscripción.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/webhooks/{id}/deliveries":{"get":{"operationId":"listDeliveries","summary":"Log de entregas de una suscripción.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/webhooks/{id}/deliveries/{deliveryId}/replay":{"post":{"operationId":"replayDelivery","summary":"Reintenta una entrega.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/imports":{"post":{"operationId":"startImport","summary":"Inicia una importación (JSON rows). Objetos: contacts, companies, deals, activities, tickets, projects, invoices.","tags":["Import"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"objectType":{"type":"string","enum":["contacts","companies","deals","activities","tickets","projects","invoices"]},"rows":{"maxItems":10000,"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"csv":{"type":"string","minLength":1},"mode":{"default":"create","type":"string","enum":["create","update","upsert"]},"dateFormat":{"default":"YYYY-MM-DD","type":"string","enum":["DD/MM/YYYY","MM/DD/YYYY","YYYY-MM-DD"]}},"required":["objectType","mode","dateFormat"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"get":{"operationId":"listImports","summary":"Lista las importaciones.","tags":["Import"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/imports/{id}":{"get":{"operationId":"getImport","summary":"Estado/progreso de una importación.","tags":["Import"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"cancelImport","summary":"Cancela una importación en curso.","tags":["Import"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/usage":{"get":{"operationId":"getUsage","summary":"Consumo y cuota RESTANTE del token que hace la llamada: ráfaga y diaria, modo (live/test) y objetos a los que da acceso. Sirve para anticipar un 429 en vez de descubrirlo.","tags":["Token"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/mcp":{"post":{"operationId":"mcpEndpoint","summary":"Servidor MCP (Model Context Protocol) sobre Streamable HTTP, JSON-RPC 2.0: `initialize`, `ping`, `tools/list`, `tools/call`. Mismo token, mismo scope y mismos límites que REST. Ver la sección \"Servidor MCP\" de esta doc.","tags":["Token"],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Token inválido o ausente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Sin permiso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflicto de estado (p.ej. duplicado en upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}