APIs Personalizadas

Cualquier endpoint HTTP puede convertirse en una herramienta. Describes la petición estilo Postman, declaras qué variables la rellenan, y Platica deriva de ahí el esquema que ve el modelo.

El modelo mental

Una API personalizada tiene dos partes:

  • request — la petición HTTP a ejecutar. Método, URL, headers, body y autenticación. Donde quieras un valor dinámico, escribes {{nombre}}.
  • variables — quién rellena cada {{nombre}}. El campo mode decide el origen:
modeQuién aporta el valor¿La ve el modelo?
ai (default)El modelo lo escribe al llamar la herramientaSí, aparece en el esquema
constantValor fijo en constantValueNo
contextSe toma de la conversación, según contextFieldNo

El JSON Schema que recibe el modelo se deriva de las variables en modo ai al habilitar la herramienta. Nunca lo escribes a mano, y por eso la description de cada variable importa: es literalmente lo que el modelo lee para decidir qué mandar.

El ciclo de vida

draft ──enable──> enabled ──pause──> paused ──enable──> enabled

Sólo en enabled la herramienta tiene una entrada en el catálogo del workspace y se le puede conectar a un agente. En draft y paused la configuración existe pero nadie la ve.

El integrationId y el toolId del catálogo son el mismo identificador, así que al habilitarla ya puedes usarlo en POST /v1/agents/{agentId}/tools .

Listar APIs

GET https://api.platica.mx/v1/tools/apis

Respuesta

{
  "count": 1,
  "apis": [
    {
      "id": "RuzoaswTBBrhutHyKYZn",
      "name": "order_lookup",
      "toolName": "api_order_lookup",
      "description": "Consulta el estado de un pedido por su folio.",
      "status": "enabled",
      "method": "GET",
      "url": "https://api.tienda.com/orders/{{orderId}}",
      "variableCount": 1,
      "lastTestOutcome": "success",
      "lastTestAt": "2026-07-12T09:15:22.109Z",
      "createdAt": "2026-07-10T15:41:03.902Z",
      "updatedAt": "2026-07-12T09:18:44.117Z"
    }
  ]
}
CampoTipoDescripción
namestringNombre corto que definiste.
toolNamestringNombre completo que ve el modelo: siempre api_<name>.
statusstringdraft, enabled o paused.
variableCountnumberTotal de variables, incluyendo las ocultas al modelo.
lastTestOutcomestring | nullResultado de la última prueba: success, http-error, network-error, schema-error o mapping-error.

Crear API

Crea la herramienta como borrador. No queda disponible para ningún agente hasta habilitarla.

POST https://api.platica.mx/v1/tools/apis

Cuerpo de la solicitud

{
  "name": "order_lookup",
  "description": "Consulta el estado de un pedido de la tienda por su folio. Úsala cuando el cliente pregunte dónde va su pedido.",
  "request": {
    "method": "GET",
    "url": "https://api.tienda.com/orders/{{orderId}}",
    "headers": [
      { "key": "Accept", "value": "application/json" }
    ],
    "auth": {
      "type": "bearer",
      "token": "sk_live_xxx"
    }
  },
  "variables": [
    {
      "name": "orderId",
      "type": "string",
      "description": "Folio del pedido, tal como aparece en el correo de confirmación.",
      "required": true
    }
  ],
  "response": {
    "path": "data",
    "exclude": ["internal_notes"]
  }
}
ParámetroTipoDescripciónRequerido
namestringMinúsculas, empieza con letra o dígito, sólo letras, dígitos y _ (≤ 62 caracteres). El modelo la verá como api_<name>
descriptionstringEntre 10 y 1024 caracteres. Explica cuándo debe llamarla el agente
requestobjetoLa petición HTTP. Ver abajo
variablesarrayQué rellena cada {{nombre}}. Máximo 50
passContextbooleanNecesario para usar variables en modo context
contextobjeto{ "lastMessagesN": 10 } — cuántos mensajes expone {{ctx.lastMessages}}
mappingobjetobodyStrategy (merge, replace, none) y extraBody con pares fijos
responseobjetoRecorte de la respuesta antes de dársela al modelo
periodicAuthobjetoInyecta un token obtenido por un cron job
encryptPayloadobjetoFirma el body saliente como JWT
{
  "method": "POST",
  "url": "https://api.tienda.com/orders",
  "params": [
    { "key": "locale", "value": "es-MX" }
  ],
  "headers": [
    { "key": "Content-Type", "value": "application/json" }
  ],
  "body": {
    "mode": "json",
    "raw": "{ \"customer\": \"{{customerId}}\", \"note\": \"{{note}}\" }"
  },
  "auth": { "type": "bearer", "token": "sk_live_xxx" },
  "settings": { "timeoutMs": 30000 }
}
CampoTipoDescripción
methodstringGET, POST, PUT, PATCH o DELETE.
urlstringURL destino. Admite {{variable}} en cualquier parte.
paramsarrayQuery params como { key, value, enabled? }. Máximo 25.
headersarrayIgual que params. Máximo 25.
bodyobjeto{ "mode": "none" }, { "mode": "json", "raw": "..." }, { "mode": "text", "raw": "..." } o { "mode": "form-urlencoded", "pairs": [...] }.
authobjeto{ "type": "none" }, { "type": "bearer", "token" }, { "type": "basic", "username", "password" } o { "type": "apikey", "key", "value", "in": "header" \| "query" }.
settings.timeoutMsnumberEntre 1000 y 60000. Default 30000.

Cualquier value admite {{variable}}, no sólo la URL.

{
  "name": "orderId",
  "type": "string",
  "description": "Folio del pedido, tal como aparece en el correo de confirmación.",
  "required": true,
  "mode": "ai"
}
CampoTipoDescripción
namestringSe referencia como {{name}} dentro de request.
typestringstring, number, integer, boolean, array u object.
descriptionstringLo que lee el modelo. Obligatoria para variables en modo ai al habilitar.
requiredbooleanSi el modelo debe mandarla siempre.
modestringai (default), constant o context.
constantValuecualquieraSólo con mode: "constant".
contextFieldstringSólo con mode: "context". Ver abajo.
enum, format, pattern, minLength, maxLength, minimum, maximum, items, defaultvariosRefinamientos que se copian al JSON Schema del modelo.

Valores admitidos en contextField, disponibles cuando passContext es true:

contextFieldValor
phoneNumberNúmero del cliente en la conversación
workspaceIdID del workspace
conversationIdID de la conversación
agentIdID del agente que llama
agentNameNombre del agente que llama
channelIdCanal por el que llegó la conversación
lastMessagesÚltimos N mensajes, según context.lastMessagesN

Las respuestas grandes gastan contexto del modelo sin aportar nada. response permite quedarse sólo con lo útil:

CampoTipoDescripción
pathstringRuta al fragmento útil, ej. data.items.
strictPathbooleanSi true, falla cuando path no existe en lugar de devolver todo.
includestring[]Sólo estos campos.
excludestring[]Todos menos estos.
maxBytesnumberCorta la respuesta a este tamaño. Default 32000.

Respuesta

{
  "status": "success",
  "message": "API tool created successfully",
  "data": {
    "id": "RuzoaswTBBrhutHyKYZn",
    "name": "order_lookup",
    "toolName": "api_order_lookup",
    "status": "draft"
  }
}

Errores

StatusCausa
400El name no cumple el formato, la descripción es muy corta, o el request es inválido
409Ya existe otra herramienta con ese nombre en el workspace

Obtener API

GET https://api.platica.mx/v1/tools/apis/{integrationId}

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Respuesta

Devuelve la definición y el toolName derivado. Los valores write-only se sustituyen por "[REDACTED]": autenticación, headers/params sensibles, variables constantes y la llave de encryptPayload.

{
  "id": "RuzoaswTBBrhutHyKYZn",
  "toolName": "api_order_lookup",
  "name": "order_lookup",
  "description": "Consulta el estado de un pedido de la tienda por su folio.",
  "status": "enabled",
  "request": {
    "method": "GET",
    "url": "https://api.tienda.com/orders/{{orderId}}",
    "headers": [{ "key": "Accept", "value": "application/json" }],
    "auth": { "type": "bearer", "token": "[REDACTED]" }
  },
  "variables": [
    {
      "name": "orderId",
      "type": "string",
      "description": "Folio del pedido, tal como aparece en el correo de confirmación.",
      "required": true,
      "mode": "ai"
    }
  ],
  "version": 3,
  "enabledFunctionRef": "RuzoaswTBBrhutHyKYZn",
  "secretsRedacted": true,
  "createdAt": "2026-07-10T15:41:03.902Z",
  "updatedAt": "2026-07-12T09:18:44.117Z"
}

version sube con cada escritura y sirve para el control de concurrencia al actualizar.

Puedes reenviar "[REDACTED]" en un PATCH: Platica conserva el valor actual. Para reemplazar una credencial manda el valor nuevo; para conservarla también puedes omitir el campo.

Errores

StatusCausa
404La API personalizada no existe en el workspace

Actualizar API

Actualización parcial: sólo se modifican los campos que mandes, el resto se conserva.

PATCH https://api.platica.mx/v1/tools/apis/{integrationId}

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Cuerpo de la solicitud

{
  "description": "Consulta el estado y la fecha estimada de entrega de un pedido.",
  "expectedVersion": 3
}

Acepta los mismos campos que crear , todos opcionales, más:

ParámetroTipoDescripción
expectedVersionnumberSi la versión guardada no coincide, responde 409 en lugar de sobrescribir cambios de otro

Si la herramienta está enabled, los cambios de nombre, descripción y variables se propagan al catálogo de inmediato. El status no cambia aquí — para eso están habilitar y pausar .

Respuesta

{
  "status": "success",
  "message": "API tool updated successfully",
  "data": {
    "id": "RuzoaswTBBrhutHyKYZn",
    "version": 4
  }
}

Errores

StatusCausa
400Algún campo enviado es inválido, o el cuerpo viene vacío
404La API personalizada no existe
409expectedVersion no coincide, o el nombre nuevo ya está en uso

Probar API

Ejecuta la herramienta con valores de prueba, en borrador o habilitada. Cada ejecución queda registrada en los logs de la integración.

POST https://api.platica.mx/v1/tools/apis/{integrationId}/test

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Cuerpo de la solicitud

{
  "dryRun": false,
  "input": {
    "orderId": "MX-48210"
  },
  "context": {
    "phoneNumber": "+5215512345678"
  }
}
ParámetroTipoDescripciónRequeridoDefault
dryRunbooleanCon true arma la petición y la devuelve sin llamar a la APIfalse
inputobjetoValores para las variables en modo ai{}
contextobjetoValores de prueba para {{ctx.*}}: phoneNumber, workspaceId, conversationId, agentId, agentName, channelId, messages

Empieza siempre con dryRun: true para verificar cómo quedan la URL, los headers y el body con las sustituciones aplicadas, antes de golpear la API real.

Respuesta

{
  "status": "success",
  "message": "Test executed",
  "data": {
    "outcome": "success",
    "httpStatus": 200,
    "durationMs": 412,
    "request": {
      "method": "GET",
      "url": "https://api.tienda.com/orders/MX-48210"
    },
    "response": {
      "status": "in_transit",
      "eta": "2026-07-16"
    }
  }
}

Errores

StatusCausa
404La API personalizada no existe

Un fallo de la API remota no es un error de este endpoint: responde 200 con el detalle en data.outcome y data.httpStatus.

Habilitar API

Publica la herramienta en el catálogo del workspace.

POST https://api.platica.mx/v1/tools/apis/{integrationId}/enable

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Respuesta

{
  "status": "success",
  "message": "API tool enabled successfully",
  "data": {
    "id": "RuzoaswTBBrhutHyKYZn",
    "toolId": "RuzoaswTBBrhutHyKYZn",
    "status": "enabled"
  }
}

toolId es lo que se pasa a POST /v1/agents/{agentId}/tools para dársela a un agente.

Volver a habilitar una herramienta ya habilitada re-sincroniza el catálogo, lo cual es útil después de editar el esquema.

Errores

StatusCausa
400Falta una descripción en alguna variable visible para el modelo, o la definición no pasa la validación
404La API personalizada no existe
409Ya existe otra herramienta con ese nombre en el workspace

Pausar API

Retira la herramienta del catálogo. Los agentes dejan de verla de inmediato, pero la configuración se conserva íntegra.

POST https://api.platica.mx/v1/tools/apis/{integrationId}/pause

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Respuesta

{
  "status": "success",
  "message": "API tool paused successfully",
  "data": {
    "id": "RuzoaswTBBrhutHyKYZn",
    "status": "paused"
  }
}

Errores

StatusCausa
404La API personalizada no existe

Eliminar API

DELETE https://api.platica.mx/v1/tools/apis/{integrationId}

Parámetros de URL

ParámetroTipoDescripciónRequerido
integrationIdstringIdentificador de la API personalizada

Respuesta

{
  "status": "success",
  "message": "API tool deleted successfully",
  "data": {
    "id": "RuzoaswTBBrhutHyKYZn",
    "removedAgentConnections": 3
  }
}

Elimina la configuración, su entrada del catálogo y todas sus conexiones con agentes. No es reversible — si sólo quieres apagarla conservando las asignaciones, usa pausar .

Errores

StatusCausa
404La API personalizada no existe