IA-SARYP API

API REST Multi-tenant de Inteligencia Artificial — Interpreta consultas en lenguaje natural y devuelve el stored procedure + parámetros para ejecutar en tu base de datos.

Descripción General

IA-SARYP es una API que usa un LLM (Bonsai 1.7B) para interpretar preguntas en lenguaje natural y traducirlas a llamadas de stored procedures. El sistema es multi-tenant: cada cliente tiene su propia configuración, schema y whitelist de SPs.

La API no conecta a la base de datos del cliente. Solo devuelve el SP y parámetros para que el sistema del cliente lo ejecute.

Flujo de uso
1. Admin crea tenant → obtiene api_token
2. Admin sube schema, whitelist y reglas
3. Admin activa tenant
4. Tenant consulta: "work orders abiertas" → SP: sp_wo_abiertas, params: [null]
5. El sistema del cliente ejecuta: CALL sp_wo_abiertas(@company_id, NULL)

Autenticación

Admin (para /admin/*)

Se autentica con admin_key — la clave maestra definida en el servidor.

Opciones de envío
// Opción 1: En el body JSON
{"admin_key": "TU_ADMIN_KEY", ...}

// Opción 2: Header HTTP
X-Admin-Key: TU_ADMIN_KEY

Tenant (para /ia/*)

Se autentica con api_token — el token único generado al crear el tenant. El tenant debe estar en estado active.

Opciones de envío
// Opción 1: En el body JSON
{"api_token": "sk_...", ...}

// Opción 2: Header HTTP
X-Api-Token: sk_...

Quick Start

bash
# 1. Health check
curl https://ia-staging.saryp.com/health

# 2. Crear tenant
curl -X POST https://ia-staging.saryp.com/admin/tenants \
  -H "Content-Type: application/json" \
  -d '{"admin_key":"MI_KEY","company_name":"MiEmpresa"}'

# 3. Subir whitelist
curl -X POST https://ia-staging.saryp.com/admin/tenants/tn_xxx/whitelist \
  -H "Content-Type: application/json" \
  -d '{"admin_key":"MI_KEY","whitelist":{"sp_datos":["nullable"]}}'

# 4. Activar
curl -X PUT https://ia-staging.saryp.com/admin/tenants/tn_xxx \
  -H "Content-Type: application/json" \
  -d '{"admin_key":"MI_KEY","status":"active"}'

# 5. Consultar
curl -X POST https://ia-staging.saryp.com/ia/consulta \
  -H "Content-Type: application/json" \
  -d '{"api_token":"sk_xxx","query":"mostrame los datos"}'

POST /admin/tenants

Crea un nuevo tenant.

CampoTipoRequeridoDescripción
company_namestringNombre de la empresa
contact_namestringNombre del contacto
contact_emailstringEmail del contacto
descriptionstringDescripción
Respuesta 201
{
  "success": true,
  "tenant_id": "tn_a1b2c3d4e5f6g7h8",
  "api_token": "sk_...",
  "status": "pending"
}

GET /admin/tenants

Lista todos los tenants. Filtro opcional: ?status=active|pending|suspended

Respuesta 200
{
  "tenants": [
    {
      "tenant_id": "tn_...",
      "company_name": "MiEmpresa",
      "status": "active",
      "rate_limit": 30,
      "has_schema": true,
      "has_whitelist": true,
      "created_at": "2026-04-17T12:00:00"
    }
  ]
}

GET /admin/tenants/{id}

Detalle completo de un tenant, incluye schema, rules, whitelist y prompt.

PUT /admin/tenants/{id}

Actualiza campos del tenant.

CampoTipoDescripción
statusstringactive, pending, suspended
rate_limitintRequests por minuto
company_namestringNombre
contact_namestringContacto
contact_emailstringEmail

POST /admin/tenants/{id}/schema

Sube el schema de la base de datos del tenant. El prompt se regenera automáticamente.

Body
{
  "admin_key": "TU_KEY",
  "schema": "work_orders(id, wo_number, status, aircraft_id)\naircraft(id, registration, model)"
}

POST /admin/tenants/{id}/rules

Sube reglas de negocio que la IA usa para interpretar consultas.

Body
{
  "admin_key": "TU_KEY",
  "rules": "- pendientes = status open\n- cerradas = status closed"
}

POST /admin/tenants/{id}/whitelist

Sube la whitelist de stored procedures con tipos de parámetros.

Body
{
  "admin_key": "TU_KEY",
  "whitelist": {
    "sp_wo_abiertas": ["nullable"],
    "sp_wo_por_avion": ["string"],
    "sp_wo_por_fecha": ["date", "date"],
    "sp_resumen_mensual": ["int"]
  }
}

Tipos válidos: int, string, date (YYYY-MM-DD), nullable (siempre NULL)

POST /admin/tenants/{id}/prompt

Sube un prompt custom (formato ChatML). Debe incluir {USER_QUERY}. Se auto-genera al subir schema/whitelist, solo usar para overrides.

POST /admin/tenants/{id}/regenerate-token

Genera un nuevo API token. El token anterior deja de funcionar inmediatamente.

POST /ia/consulta

Endpoint principal. Recibe una consulta en lenguaje natural y devuelve el SP + parámetros.

Request
{
  "api_token": "sk_...",
  "query": "mostrame las work orders abiertas"
}
Respuesta 200
{
  "success": true,
  "sp": "sp_wo_abiertas",
  "params": [null],
  "message": "Execute this SP in your database with your company_id as first parameter"
}

El cliente ejecuta en su base de datos:

SQL
CALL sp_wo_abiertas(@company_id, NULL);

POST /ia/export

Genera un archivo Excel o PDF a partir de datos JSON.

Body
{
  "api_token": "sk_...",
  "format": "excel",
  "title": "Work Orders Abiertas",
  "data": [
    {"wo_number": "WO-001", "status": "open"},
    {"wo_number": "WO-002", "status": "open"}
  ]
}

Descarga directa del archivo (.xlsx o .pdf).

GETPOST /ia/info

Devuelve información del tenant autenticado.

GET /health

Health check público. No requiere autenticación.

Respuesta
{"status": "ok", "llm": "healthy", "version": "2.0.0-multitenant"}

Códigos de Error

CódigoCuándo
200Éxito
201Tenant creado
400Input inválido (campo faltante, query > 500 chars)
401Auth fallida (key/token inválido, tenant inactivo)
404Endpoint o tenant no encontrado
422Tenant sin configurar o SP no en whitelist
429Rate limit excedido
502LLM no disponible

Tipos de Parámetros

TipoAceptaSanitización
intNúmeros positivosCast a int, o null
stringTextoMax 100 chars, sin ; ' " \
dateYYYY-MM-DDRegex exacto o null
nullableSiempre NULL

Rate Limiting

Integración PHP / CodeIgniter

PHP — Modelo de integración
<?php
class Ia_model extends CI_Model
{
    private $ia_url   = 'https://ia-staging.saryp.com';
    private $ia_token = 'sk_abc123...';

    public function consultar($pregunta)
    {
        $response = $this->_post('/ia/consulta', [
            'api_token' => $this->ia_token,
            'query'     => $pregunta
        ]);

        if (!$response->success) {
            return ['error' => $response->error];
        }

        $sp         = $response->sp;
        $params     = $response->params;
        $company_id = $this->session->userdata('company_id');

        return $this->_ejecutar_sp($sp, $company_id, $params);
    }

    private function _ejecutar_sp($sp_name, $company_id, $params)
    {
        $placeholders = '?';
        $bindings     = [$company_id];

        foreach ($params as $p) {
            $placeholders .= ', ?';
            $bindings[]    = $p;
        }

        $sql   = "CALL {$sp_name}({$placeholders})";
        $query = $this->db->query($sql, $bindings);

        return $query ? $query->result_array() : [];
    }

    private function _post($endpoint, $data)
    {
        $ch = curl_init($this->ia_url . $endpoint);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($data),
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 30,
        ]);
        $res = curl_exec($ch);
        curl_close($ch);
        return json_decode($res);
    }
}

IA-SARYP v2.0.0 Multi-tenant — SARYP © 2026