Skip to content
JARAI Developers

Webhook Integration

Webhooks deliver real-time event notifications to your server, eliminating the need for status polling. JARAI supports 9 event types with at-least-once delivery and HMAC-SHA256 signature verification.

Registering a Webhook

Register an HTTPS endpoint to receive events:

curl -X POST https://apim-jarai-prd.azure-api.net/v1/webhooks \
-H "X-API-Key: jarai_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
  "endpointUrl": "https://your-server.com/webhooks/jarai",
  "eventTypes": [
    "production.queued",
    "production.step.complete",
    "production.published",
    "production.failed",
    "deliverable.ready"
  ]
}'

The response includes a signingSecret (base64url-encoded). Store it securely — it is returned only on creation and cannot be retrieved again.

Registration Options

FieldRequiredTypeDescription
endpointUrlYesstringHTTPS URL to receive webhook events. HTTP is not accepted.
eventTypesYesstring[]At least one event type from the supported list.
accountIdsNoUUID[]Limit events to specific accounts (max 50). Must be a subset of your permitted accounts.
accountScopeIdNoUUIDLimit events to a single account. Mutually exclusive with accountIds.

You can register up to 100 active webhook subscriptions.

Signature Verification

Every webhook delivery includes an X-JARAI-Signature header for verifying authenticity:

X-JARAI-Signature: sha256=a1b2c3d4e5f6...

Verification Algorithm

  1. Read the raw HTTP request body as bytes (do not parse and re-serialize the JSON).
  2. Compute HMAC-SHA256 using your signingSecret (base64url-decoded) as the key and the raw body as the message.
  3. Hex-encode the resulting digest.
  4. Compare with the value after sha256= in the X-JARAI-Signature header using a constant-time comparison to prevent timing attacks.
using System.Security.Cryptography;
using System.Text;

public static bool VerifySignature(
  byte[] requestBody,
  string signatureHeader,
  string signingSecretBase64Url)
{
  // Decode the base64url signing secret
  string base64 = signingSecretBase64Url
      .Replace('-', '+')
      .Replace('_', '/');
  switch (base64.Length % 4)
  {
      case 2: base64 += "=="; break;
      case 3: base64 += "="; break;
  }
  byte[] secret = Convert.FromBase64String(base64);

  // Compute HMAC-SHA256
  using var hmac = new HMACSHA256(secret);
  byte[] hash = hmac.ComputeHash(requestBody);
  string expected = "sha256=" + Convert.ToHexString(hash).ToLowerInvariant();

  // Constant-time comparison
  return CryptographicOperations.FixedTimeEquals(
      Encoding.UTF8.GetBytes(expected),
      Encoding.UTF8.GetBytes(signatureHeader));
}

Important Notes

  • Always verify against the raw request body bytes, not a parsed-and-re-serialized version of the JSON. Re-serialization may alter whitespace or field ordering, breaking the signature.
  • Use constant-time comparison to prevent timing side-channel attacks.
  • If verification fails, return a 4xx status code and do not process the event.

Event Types

JARAI delivers 9 event types. See the Webhook Reference for complete payload schemas and field tables.

Event TypeTrigger
production.queuedProduction submitted to the pipeline.
production.step.completeA pipeline step finished processing.
production.awaiting_approvalAll pipeline steps complete; waiting for operator release.
production.distributingFirst platform publication started.
production.publishedAll platforms published successfully.
production.failedProduction failed terminally.
production.cancelledProduction cancelled by partner or operator.
deliverable.readyDeliverable files are available for download.
webhook.testPing test event (no real production data).

Retry Schedule

JARAI uses at-least-once delivery. If your endpoint does not return a 2xx response, the event is retried:

AttemptTiming
1st retryImmediate
2nd retry1 minute after first failure
3rd retry5 minutes after second failure

After all three retries fail, the delivery is counted as a failure and the subscription’s failureCount is incremented.

Auto-Suspension

  • At 3 consecutive failures: a WebhookDeliveryFailed warning alert is raised internally.
  • At 10 consecutive failures: the subscription status is set to Failed and no further events are delivered. A WebhookEndpointUnreachable alert is raised.

A successful delivery resets the failure counter to zero.

Reinstating a Suspended Subscription

If your subscription reaches Failed status, reinstate it after fixing your endpoint:

curl -X POST https://apim-jarai-prd.azure-api.net/v1/webhooks/{subscriptionId}/reinstate \
-H "X-API-Key: jarai_your_api_key_here"

Reinstatement requires SelfServeKeyRotationEnabled = true on your partner account. If disabled, contact JARAI support.

Testing Webhooks

Send a test event to verify your endpoint is reachable and correctly verifying signatures:

curl -X POST https://apim-jarai-prd.azure-api.net/v1/webhooks/{subscriptionId}/ping \
-H "X-API-Key: jarai_your_api_key_here"

Ping events deliver a webhook.test event with productionId and accountId set to nil UUIDs (00000000-0000-0000-0000-000000000000). Pings do not consume your shared RPM budget, but are limited to 1 per subscription per minute.

Idempotency

JARAI guarantees at-least-once delivery, which means you may receive the same event more than once. Use the composite key {productionId}:{sequenceNumber} to deduplicate events. The sequenceNumber is per-production (not globally unique).

Next Steps