Skip to content

Outbound Events

Outbound events allow you to receive notifications from ChronosHub when something happens that is relevant to your integration (e.g., a manuscript was submitted). ChronosHub delivers these events to your webhook endpoint as signed HTTP POST requests.

To receive outbound events, you need a webhook URL and a webhook secret, both configured during onboarding.

How It Works

  1. An event occurs in ChronosHub that matches one of your subscribed event types.
  2. ChronosHub signs the payload with your webhook secret and sends a POST request to your webhook URL.
  3. Your endpoint processes the event and responds with a 2xx status code to confirm receipt.
  4. If delivery fails, ChronosHub retries automatically.

Prerequisites

The following are configured by ChronosHub during onboarding:

ItemDescription
Webhook URLThe HTTPS endpoint where ChronosHub will POST events.
Webhook SecretA shared secret used to sign webhook payloads so you can verify their authenticity.
Event SubscriptionsThe event types you want to receive (e.g., manuscript.submitted).

Webhook Request Format

ChronosHub sends a POST request to your webhook URL with the following headers and body.

Headers

HeaderDescription
Content-Typeapplication/json
User-AgentChronosHub-Integration-Framework/1.0
X-Hub-Signature-256HMAC-SHA256 signature of the request, prefixed with sha256=. Used for verification.
X-Event-TypeThe type of event (e.g., manuscript.submitted).
X-Event-IdUnique identifier for this event (UUID).
X-TimestampUnix timestamp (seconds) when the request was signed.

Body

The request body is a JSON payload containing the event data. The exact shape depends on the event type agreed upon during onboarding.

Example Request

http
POST /webhook HTTP/1.1
Host: partner.example.com
Content-Type: application/json
User-Agent: ChronosHub-Integration-Framework/1.0
X-Hub-Signature-256: sha256=a1b2c3...
X-Event-Type: manuscript.submitted
X-Event-Id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
X-Timestamp: 1740000000

{
  "manuscriptId": "MS-2026-001",
  "title": "Example Manuscript",
  "submittedAt": "2026-02-26T12:00:00Z"
}

Expected Response

Your endpoint should return a 2xx status code to acknowledge receipt. The response body is ignored by ChronosHub.

StatusMeaning
200 OK / 202 AcceptedEvent received successfully.
Any non-2xxDelivery is considered failed and will be retried.

Retry Behavior

If delivery fails (non-2xx response or network error), ChronosHub retries the delivery up to 5 times. Events that still fail after all retries are marked as failed. If you experience persistent delivery failures, contact your ChronosHub onboarding contact for assistance.

Signature Verification

Every webhook request is signed using HMAC-SHA256 with your webhook secret. You should verify the signature before processing the event to confirm the request came from ChronosHub and was not tampered with.

Verification Steps

  1. Read the raw request body as a UTF-8 string.

  2. Build the signature message using the following length-prefixed format:

    {payload_length}:{payload}|{event_type}|{event_id}|{timestamp}

    Where:

    • {payload_length} — the character length of the raw payload string.
    • {payload} — the raw request body.
    • {event_type} — the value of the X-Event-Type header.
    • {event_id} — the value of the X-Event-Id header.
    • {timestamp} — the value of the X-Timestamp header.
  3. Compute the HMAC-SHA256 hash of the message using your webhook secret as the key.

  4. Compare the resulting hex digest (lowercase) with the value after the sha256= prefix in the X-Hub-Signature-256 header.

Example (Python)

python
import hmac
import hashlib

def verify_signature(payload: str, secret: str, event_type: str, event_id: str, timestamp: str, received_signature: str) -> bool:
    message = f"{len(payload)}:{payload}|{event_type}|{event_id}|{timestamp}"
    expected = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received_signature.removeprefix("sha256="))

Example (C#)

csharp
using System.Security.Cryptography;
using System.Text;

bool VerifySignature(string payload, string secret, string eventType, string eventId, string timestamp, string receivedSignature)
{
    var message = $"{payload.Length}:{payload}|{eventType}|{eventId}|{timestamp}";
    var keyBytes = Encoding.UTF8.GetBytes(secret);
    var messageBytes = Encoding.UTF8.GetBytes(message);
    var hash = HMACSHA256.HashData(keyBytes, messageBytes);
    var expected = Convert.ToHexString(hash).ToLowerInvariant();
    return CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(expected),
        Encoding.UTF8.GetBytes(receivedSignature.Replace("sha256=", "")));
}

Event Types

Event types are dot-separated identifiers that describe what happened (e.g., manuscript.submitted). You only receive events for the types you are subscribed to. Subscriptions are configured during onboarding.