WebhooksRegistrar un webhook

Webhooks

Registrar un webhook

Registra una URL https a la que Sofia llama con un evento JSON firmado, reintentado hasta cinco veces si falla. Secreto visible una vez; máximo 10 webhooks.

POSThttps://api.sofia-post.com/api/v1/webhooks
POSThttps://api.sofia-post.com/api/v1/webhooks

Registrar un webhook

Registra una URL https a la que Sofia llama con un evento JSON firmado, reintentado hasta cinco veces si falla. Secreto visible una vez; máximo 10 webhooks.

Autorizaciones

Authorizationstringobligatorio

Tu clave personal o token de acceso OAuth, enviado como Bearer <token>.

Se guarda solo en esta pestaña y se envía únicamente a api.sofia-post.com. Obtener una clave de API

Cuerpo

Esta petición actúa sobre tu cuenta real.

Registrar un webhook

Registra una dirección https pública y los eventos deseados. El secreto de firma (whsec_…) solo se muestra en esta respuesta. Una aplicación puede tener hasta 10 webhooks.

curl -X POST https://api.sofia-post.com/api/v1/webhooks \
  -H "Authorization: Bearer $SOFIA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://app.example.com/hooks/sofia","events":["post.published","post.failed"]}'

Eventos

Eventodata
post.publishedpostId, establishmentId, platform, publishedAt, permalink
post.failedpostId, establishmentId, platform, error
webhook.testwebhookId

Sofia envía cada evento por POST en formato JSON { id, type, createdAt, data }, con las cabeceras Sofia-Event-Id, Sofia-Event-Type y Sofia-Signature. Solo se anuncian las publicaciones creadas por tu aplicación.

Verificar la firma

Sofia-Signature vale t=<unix time>,v1=<hex>, donde v1 es el HMAC-SHA256 de <t>.<raw body> con tu secreto. Verifícala sobre el cuerpo sin procesar, y rechaza una marca de tiempo antigua:

import { createHmac, timingSafeEqual } from 'node:crypto';

const isSignedBySofia = (header, rawBody, secret) => {
  const parts = Object.fromEntries(
    (header ?? '').split(',').map((part) => part.trim().split('=', 2)),
  );
  const timestamp = Number(parts.t);
  if (!Number.isInteger(timestamp) || typeof parts.v1 !== 'string') return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest();
  const received = Buffer.from(parts.v1, 'hex');
  return received.length === expected.length && timingSafeEqual(received, expected);
};

Entrega y nuevos intentos

  • Una respuesta 2xx entrega el evento. Cualquier otra respuesta, una redirección (nunca seguida) o 10 segundos sin respuesta provocan un nuevo intento tras 1 minuto, 5 minutos, 30 minutos y 2 horas, hasta 5 intentos.
  • Un mismo evento puede llegar dos veces: deduplica por Sofia-Event-Id.
  • Responde rápido y procesa el evento después.

Autorizaciones

  • Authorizationstringheaderobligatorio

    Tu clave personal o token de acceso OAuth, enviado como Bearer <token>.

Cuerpo

application/json
  • urlstringobligatorio

    La dirección https a la que llama Sofia. Se rechaza un host que resuelva a una dirección privada, loopback o link-local

  • eventsstring[]obligatorio

    Los eventos que recibir

Respuesta

El webhook y su secreto de firma, mostrado una sola vez.

  • idstringobligatorio

    Identificador del webhook.

  • urlstringobligatorio

    Dirección a la que llama Sofia

  • eventsstring[]obligatorio

    Los eventos suscritos

  • createdAtstring<date-time>obligatorio

    Cuándo se registró el webhook

  • secretstringobligatorio

    La clave HMAC-SHA256 que firma cada envío (Sofia-Signature). Se muestra solo esta vez

¿Te ha resultado útil esta página?