Said Chat · API para negociosIr al panel →

Conecta tu sistema con Said Chat

Con una llave, tu CRM, tienda en línea, n8n, Zapier o un script de 20 líneas manda mensajes a tus clientes y recibe por webhook lo que te escriben. Sin plantillas, sin aprobaciones de mensajes, sin bloqueos.

1. Consigue tu llave

  1. Entra al panel con tu número (o en la app: Ajustes → Cuenta → Mi negocio).
  2. En Perfil → Conectar mi sistema pide la llave. Said Chat la aprueba y aparece como ga_live_....
  3. Pega la URL de tu webhook para recibir los mensajes de tus clientes.

Servidor: http://inference.chateacontuempresa.com

2. Enviar un mensaje

POST http://inference.chateacontuempresa.com/api/v1/messages con Authorization: Bearer ga_live_TU_LLAVE.

curl -X POST http://inference.chateacontuempresa.com/api/v1/messages \
  -H "Authorization: Bearer ga_live_TU_LLAVE" \
  -H "Content-Type: application/json" \
  -d '{"to": "+50255551234", "text": "Hola Ana, tu pedido #120 va en camino 🛵"}'
const r = await fetch("http://inference.chateacontuempresa.com/api/v1/messages", {
  method: "POST",
  headers: { Authorization: "Bearer ga_live_TU_LLAVE", "Content-Type": "application/json" },
  body: JSON.stringify({ to: "+50255551234", text: "Hola Ana, tu pedido #120 va en camino 🛵" }),
});
console.log(await r.json()); // { ok: true, id: "...", delivered: "online" | "queued" }
import requests
r = requests.post("http://inference.chateacontuempresa.com/api/v1/messages",
    headers={"Authorization": "Bearer ga_live_TU_LLAVE"},
    json={"to": "+50255551234", "text": "Hola Ana, tu pedido #120 va en camino 🛵"})
print(r.json())
$ch = curl_init("http://inference.chateacontuempresa.com/api/v1/messages");
curl_setopt_array($ch, [
  CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer ga_live_TU_LLAVE", "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["to" => "+50255551234", "text" => "Hola Ana, tu pedido #120 va en camino 🛵"]),
]);
echo curl_exec($ch);

Campos

CampoTipoDescripción
tostringNúmero con código de país (+502...). Si escribes 8 dígitos se asume Guatemala.
textstringTexto del mensaje (hasta 4000 caracteres).
type"text" | "image"Opcional. Si mandas media se asume imagen.
mediastring base64Imagen en base64 (JPEG o PNG, máx. 4 MB).

Respuestas

CódigoSignificado
200{ ok, id, to, delivered: "online" | "queued" }. "queued" = el cliente está sin conexión; lo recibe (con push) en cuanto abra.
401 / 403Llave inválida, no aprobada, cuenta suspendida o cliente que bloqueó al negocio.
404Ese número no usa Said Chat.
409El cliente instaló la app pero todavía no la abrió (no tiene llave de cifrado).
429Más de 60 mensajes por minuto.

3. Recibir mensajes (webhook)

Cada vez que un cliente le escribe a tu negocio, Said Chat hace POST a tu URL con este JSON:

{
  "event": "message",
  "id": "5f1c...",
  "at": 1757350000000,
  "from": { "id": "06ac...", "phone": "+50255551234", "name": "Ana" },
  "type": "text",           // text | image | audio | location | order | appointment
  "text": "Hola, ¿tienen envío a zona 10?",
  "media": "...base64...",  // solo en image / audio
  "data": { ... }           // en order / appointment: items, total, when, note
}

Responde 200 en menos de 10 segundos. Si no, reintentamos 3 veces. Firma: la cabecera X-SaidChat-Signature: sha256=HMAC_SHA256(secreto, cuerpo). Verifícala así:

// Node.js (Express)
import crypto from "node:crypto";
app.post("/saidchat", express.raw({ type: "*/*" }), (req, res) => {
  const sig = "sha256=" + crypto.createHmac("sha256", process.env.SAIDCHAT_SECRET).update(req.body).digest("hex");
  if (sig !== req.get("x-saidchat-signature")) return res.sendStatus(401);
  const event = JSON.parse(req.body);
  console.log(event.from.phone, event.text);
  res.sendStatus(200);
});
# Python (Flask)
import hmac, hashlib
@app.post("/saidchat")
def hook():
    sig = "sha256=" + hmac.new(SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(sig, request.headers.get("X-SaidChat-Signature", "")): abort(401)
    event = request.get_json(); print(event["from"]["phone"], event["text"]); return "", 200

Prueba tu webhook con POST /api/v1/webhook/test (con tu llave) o con el botón Probar webhook del panel.

4. Otros endpoints

Método y rutaPara qué
GET /api/v1/meDatos del negocio, webhook configurado, contadores y si está en línea.
POST /api/v1/webhook/testManda un evento de prueba a tu webhook.

5. Catálogo por URL

Si ya tienes tus productos en tu sistema, publica un JSON y pega la URL en el panel (Productos → Sincronizar desde URL). Se actualiza cada 6 horas o cuando toques "Sincronizar ahora". Formato aceptado: una lista, o un objeto con products, items o catalog.

[
  { "id": "SKU-1", "name": "Capuchino", "price": 25, "description": "Con leche entera o de avena", "category": "Cafe", "image": "https://tu-sitio.com/img/capuchino.jpg" },
  { "id": "SKU-2", "name": "Croissant", "price": 22, "category": "Panaderia" }
]

Las imágenes pueden ser URL (https) o base64. En Excel/CSV, las columnas son nombre, precio, descripcion, categoria, imagen.

6. Ejemplos de automatización

Referencia rápida (texto plano)


Said Chat API para negocios

Conecta tu sistema (CRM, tienda, n8n, Zapier, un PHP) para mandar mensajes a tus clientes y recibir lo que te escriben. Sin plantillas que aprobar, sin ventanas de 24 horas, sin bloqueos por “spam”.

1. Consigue tu llave

  1. En la app: Ajustes → Cuenta → Mi negocio → Conectar mi sistema → Solicitar.
  2. Said Chat revisa y aprueba tu negocio. En la app aparece tu API key y tu secreto.
  3. Ahí mismo pones la URL de tu webhook (adónde te mandamos los mensajes que recibes).

2. Mandar un mensaje

curl -X POST http://TU-SERVIDOR:3000/api/v1/messages \
  -H "Authorization: Bearer ga_live_TU_LLAVE" \
  -H "Content-Type: application/json" \
  -d '{"to": "+50255551234", "text": "Hola Juan, tu pedido #123 ya salio"}'

Respuesta: {"ok":true,"id":"...","to":{...},"delivered":"online"|"queued"}. Si el cliente no usa Said Chat: 404 not_found. Si te bloqueo: 403 blocked.

Imagen: {"to":"+502...","type":"image","media":"<base64 del jpg>","text":"Tu factura"}

3. Recibir mensajes (webhook)

Cada mensaje que un cliente te escribe llega como POST a tu URL:

{
  "event": "message",
  "id": "uuid",
  "at": 1757300000000,
  "from": { "id": "uuid", "phone": "+50255551234", "name": "Juan" },
  "type": "text",
  "text": "Quiero 2 pizzas"
}

Cabecera X-SaidChat-Signature: sha256=HMAC_SHA256(secreto, cuerpo). Responde 200 en menos de 10 s; si no, reintentamos 3 veces.

Probar tu webhook: POST /api/v1/webhook/test con tu llave.

4. Ejemplos

Node.js (Express)

app.post("/guatapp", express.json(), async (req, res) => {
  const { from, text } = req.body;              // lo que escribio el cliente
  res.sendStatus(200);
  if (/precio/i.test(text)) {
    await fetch("http://TU-SERVIDOR:3000/api/v1/messages", {
      method: "POST",
      headers: { Authorization: "Bearer ga_live_TU_LLAVE", "Content-Type": "application/json" },
      body: JSON.stringify({ to: from.phone, text: "La pizza grande cuesta Q80. Te mando una?" }),
    });
  }
});

PHP

$data = json_decode(file_get_contents("php://input"), true);
$ch = curl_init("http://TU-SERVIDOR:3000/api/v1/messages");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer ga_live_TU_LLAVE", "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["to" => $data["from"]["phone"], "text" => "Gracias, ya lo vimos"])]);
curl_exec($ch);

n8n / Zapier / Make: nodo Webhook (recibe) → tu logica → nodo HTTP Request (POST a /api/v1/messages con la cabecera Authorization).

5. Limites y reglas

ReglaValor
Mensajes por minuto por llave60
Tamano de imagen3 MB en base64
Quien puede recibirCualquier usuario de Said Chat que no te haya bloqueado
PrivacidadLos chats con un negocio conectado tambien se cifran para el sistema del negocio; el cliente ve un aviso en el chat.

6. Errores

CodigoSignificado
401 invalid_keyLlave mal escrita o revocada
403 not_approvedSaid Chat aun no aprobo tu negocio
404 not_foundEse numero no usa Said Chat
409 no_keyEl cliente instalo pero no ha abierto la app
429 rate_limitedPasaste de 60 por minuto