Appearance
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
- An event occurs in ChronosHub that matches one of your subscribed event types.
- ChronosHub signs the payload with your webhook secret and sends a
POSTrequest to your webhook URL. - Your endpoint processes the event and responds with a
2xxstatus code to confirm receipt. - If delivery fails, ChronosHub retries automatically.
Prerequisites
The following are configured by ChronosHub during onboarding:
| Item | Description |
|---|---|
| Webhook URL | The HTTPS endpoint where ChronosHub will POST events. |
| Webhook Secret | A shared secret used to sign webhook payloads so you can verify their authenticity. |
| Event Subscriptions | The 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
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | ChronosHub-Integration-Framework/1.0 |
X-Hub-Signature-256 | HMAC-SHA256 signature of the request, prefixed with sha256=. Used for verification. |
X-Event-Type | The type of event (e.g., manuscript.submitted). |
X-Event-Id | Unique identifier for this event (UUID). |
X-Timestamp | Unix 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.
| Status | Meaning |
|---|---|
200 OK / 202 Accepted | Event received successfully. |
| Any non-2xx | Delivery 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
Read the raw request body as a UTF-8 string.
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 theX-Event-Typeheader.{event_id}— the value of theX-Event-Idheader.{timestamp}— the value of theX-Timestampheader.
Compute the HMAC-SHA256 hash of the message using your webhook secret as the key.
Compare the resulting hex digest (lowercase) with the value after the
sha256=prefix in theX-Hub-Signature-256header.
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.