Saltar al contenido principal

Webhooks

Los webhooks permiten que ContractorScope AI avise a tu sistema en el momento en que se aprueba un presupuesto, sin consultas repetidas ni esperas. Hacemos una peticion HTTPS a la direccion que elijas, con los detalles en el cuerpo.

Esta es una funcion para desarrolladores. Si no tienes software propio, puedes saltarte esta pagina: todo lo que aparece aqui ocurre automaticamente dentro de la aplicacion.

De que se te avisa

EventoSe dispara cuando
estimate.approvedUn presupuesto pasa a un estado aprobado

Esa es la lista completa hoy. Se dispara cuando un presupuesto entra en un estado aprobado: porque un cliente aprueba el enlace de la propuesta, porque alguien de tu equipo lo marca como aceptado o aprobado, o porque una sincronizacion de QuickBooks devuelve ese estado. Los tres envian el mismo evento.

Solo se dispara en la transicion. Un presupuesto que pasa de accepted a approved ya estaba aprobado, asi que no se dispara otra vez.

Si te suscribes a un nombre que no reconocemos, el registro se rechaza con un mensaje que lista los eventos validos: lo sabras de inmediato, en lugar de descubrirlo al no recibir nada nunca.

Registrar una direccion

POST /api/v1/webhooks/endpoints
Content-Type: application/json

{
"url": "https://tu-sitio.com/hooks/contractorscope",
"events": ["estimate.approved"],
"secret": "una-cadena-aleatoria-larga-que-tu-generas"
}

Requiere una sesion autenticada con contexto de empresa: cualquier miembro de la empresa puede hacerlo, no hay un permiso aparte que conceder. Tiene limite de peticiones y acepta una cabecera opcional Idempotency-Key si quieres reintentar el registro de forma segura.

Una llamada correcta devuelve 201:

{
"status": "success",
"data": {
"endpoint_id": "…",
"url": "https://tu-sitio.com/hooks/contractorscope",
"events": ["estimate.approved"]
}
}

Guarda el endpoint_id: es como eliminaras el endpoint mas adelante.

Elige tu mismo el secret y guardalo. Nosotros no generamos ninguno, y no te lo devolvemos: se elimina de todas las respuestas, incluida la de listado. Si lo omites, enviaremos tus webhooks sin firma, y no tendras forma de distinguir nuestras peticiones de las de cualquier otro.

Gestionar endpoints

ListarGET /api/v1/webhooks/endpoints
EliminarDELETE /api/v1/webhooks/endpoints/{endpoint_id}

Eliminar devuelve 404 si el id no existe o pertenece a otra empresa.

Puedes registrar hasta 10 endpoints por empresa. A partir de ahi, el registro se rechaza: elimina primero alguno que ya no uses.

Requisitos de la direccion

Debe usar https://. No enviamos los datos de tus clientes por una conexion sin cifrar.

Usa el puerto 443, o ningun puerto. Los puertos 80 y 587 tambien se aceptan al registrar, pero solo el 443 sirve: siempre hablamos TLS, asi que una direccion en :80 o :587 se registra sin problema y luego falla al conectar. Lo que se rechaza de plano es el esquema http://, no el numero de puerto.

  • https://tu-sitio.com/hooks/contractorscope
  • https://tu-sitio.com:443/hooks/contractorscope
  • https://tu-sitio.com:8443/hooks/contractorscope

El esquema y el puerto se comprueban al registrar, asi que una direccion en :8443 se rechaza de inmediato con una explicacion. Es intencionado: nuestros sistemas solo pueden alcanzar esos puertos, y un webhook aceptado que nunca se dispara es mucho peor que un error sobre el que puedes actuar.

Si tu endpoint escucha en un puerto no estandar, ponlo detras de un proxy inverso en el 443 y registra esa direccion.

Debe ser accesible publicamente. localhost y las direcciones privadas literales (192.168.x.x, 10.x.x.x, loopback, link-local) se rechazan al registrar, asi que lo sabras de inmediato.

El caso a vigilar: un nombre de host publico de apariencia normal que resuelva a una direccion privada pasa el registro y luego se descarta en silencio en la entrega. Si nos apuntas a algo como hooks.internal.example.com, confirma que resuelve publicamente: nada te avisara de lo contrario.

Verificar que la peticion viene de nosotros

Cada peticion incluye una cabecera X-Hub-Signature, pero lee esto con atencion, porque el nombre de la cabecera confunde. GitHub usa ese mismo nombre para SHA-1. Nosotros usamos SHA-256.

X-Hub-Signature: sha256=<64 caracteres hexadecimales en minuscula>

Para verificar:

  1. Toma los bytes originales del cuerpo de la peticion, tal y como llegaron, antes de interpretar el JSON o darle otro formato.
  2. Calcula HMAC-SHA256(secret, bytes_del_cuerpo) y codificalo en hexadecimal, en minuscula.
  3. Anade el prefijo sha256=.
  4. Comparalo con la cabecera usando una comparacion de tiempo constante.

Si no coinciden, descarta la peticion. Cualquiera puede enviar un POST a tu direccion: la firma es lo que demuestra que esta es nuestra.

Que enviamos

{
"event": "estimate.approved",
"company_id": "…",
"payload": {
"submission_id": "…",
"status": "approved",
"canonical_estimate_status": "approved",
"updated_at": "…"
}
}
payload es el registro completo del presupuesto

No es un resumen. payload contiene el presupuesto almacenado entero: todas las partidas, precios y margenes, los datos de alcance y los datos del cliente. Los campos anteriores son los estables en los que puedes confiar; todo lo demas del registro viaja con ellos.

Trata el endpoint receptor en consecuencia: esta recibiendo informacion personal de tu cliente y tus propios datos de coste, asi que protegelo como cualquier sistema que guarde eso.

La firma se calcula sobre todo este sobre, no sobre el payload interior.

Comportamiento de la entrega

Intentamos la entrega una vez. No hay reintentos. Si tu endpoint esta caido o devuelve un error, ese aviso se pierde: lo registramos por nuestra parte, pero nada lo reenvia. Si estos avisos son importantes para tu negocio, concilia periodicamente con la API en lugar de tratar los webhooks como un flujo garantizado.

Devuelve un 2xx rapido y haz el trabajo real despues. Damos 10 segundos para conectar y 10 segundos para la respuesta, por endpoint, y los endpoints se contactan uno tras otro, asi que registrar varios lentos multiplica el retraso que se describe abajo.

La velocidad importa mas de lo que parece. La entrega ocurre de forma sincrona mientras se actualiza el estado del presupuesto, incluso cuando es un cliente quien pulsa Aprobar en una propuesta. Un endpoint lento hara que ese clic tarde mas para el. Nunca hara fallar su aprobacion ni tu presupuesto, pero puede retrasar la pagina que esta viendo.

No seguimos redirecciones: un 301 o 302 no es una entrega correcta. Indicanos la direccion final.

Si algo no llega

  1. Revisa el nombre del evento: estimate.approved es el unico. Un nombre incorrecto ahora se rechaza al registrar, asi que si registraste antes de ese cambio, vuelve a registrarlo.
  2. Revisa la regla del puerto que aparece arriba.
  3. Confirma que el nombre de host resuelve publicamente, no solo dentro de tu red.
  4. Asegurate de que tu servidor devuelve 2xx y no redirige.
  5. Confirma que el endpoint sigue registrado: GET /api/v1/webhooks/endpoints.

Si sigues con dudas, contacta con soporte indicando la direccion de tu endpoint y cuando esperabas el aviso, y revisaremos que ocurrio por nuestra parte.