Ora
All documentation Overview

Getting started

IntroductionQuickstart

Concepts

StateQuestionsConfidence

Question types

yes_no (noul)choicescore

Actions & workflows

OverviewDestinationsRules and templatesWebhooks and signaturesAsk by symbolWorkflows

Limits & pricing

Rate limitsPricing

API reference

POST /v1/systemoneGET /v1/modelsErrors

Resources

Models & versions

Docs / Actions & workflows

Webhooks and signatures

A webhook action POSTs JSON to the connection's https URL, with your extra headers, X-Jev-Delivery: <run id> and X-Jev-Signature: t=<unix seconds>,v1=<hex>. v1 is HMAC-SHA256 of "<t>.<raw body>" with the connection's signing secret (shown once when you add it). Reply 2xx within 5 seconds; 429 and 5xx are retried, other 4xx are final. Redirects are not followed, and private or internal addresses are refused.

Python

import hmac, hashlib, time

def verify(secret: str, header: str, raw_body: bytes, tolerance=300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts["t"])
    if abs(time.time() - t) > tolerance:
        return False
    want = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(want, parts["v1"])

Node.js

const crypto = require('crypto');

function verify(secret, header, rawBody, tolerance = 300) {
  const p = Object.fromEntries(header.split(',').map((x) => x.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(p.t)) > tolerance) return false;
  const want = crypto.createHmac('sha256', secret).update(p.t + '.').update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(p.v1));
}
Create an account Open the Playground Everything here also lives in the console, next to your keys and usage.