Webhooks Planned

Know the moment something changes.

Approval and deployment events delivered to your endpoint as they happen. Signed, retried, ordered. This page documents a committed design, not a shipped feature.

Not built yet. There is no webhook delivery in untactit today. We are publishing the design because teams evaluating us ask what the integration will look like, and a fixed answer is more useful than a vague one. The specification below is settled: seven events, HMAC signing, at-least-once delivery. If you need this to adopt untactit, say so — that is how it gets prioritized.

Today's alternative

What you can do right now.

The audit log records every state change already, and it is queryable by actor, action, and time range. Polling it on a schedule gets you the same information with more latency and slightly more code on your side.

For most workflows — a nightly compliance sync, a dashboard refresh — that is genuinely sufficient. Webhooks matter when you need to react in seconds.

Audit log and export

Committed events — 7

asset.proposed
Editor submits for approval
asset.approved
Approver accepts, asset goes live
asset.rejected
Sent back with a note
deployment.completed
All targets confirmed
deployment.failed
One or more targets rejected it
drift.detected
Local copy diverged from approved
member.role_changed
Admin granted or revoked a role

Committed design

Signed, and safe to replay.

Every request will carry X-Untactit-Signature — an HMAC-SHA256 of the raw body — plus a timestamp. Verify both: signature proves it came from us, timestamp stops an old request being replayed at you.

  • Timestamps older than 5 minutes are rejected
  • Compare signatures in constant time, never with ==
  • Up to 5 endpoints per workspace
verify.py
import hmac, hashlib, time

def verify(body: bytes, sig: str, ts: str, secret: str) -> bool:
    if abs(time.time() - int(ts)) > 300:      # 5 min
        return False
    expected = hmac.new(
        secret.encode(), ts.encode() + b"." + body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, sig)

Delivery guarantees Planned

At-least-once

We retry until you return 2xx, so the same event may arrive twice. Deduplicate on id. Retries back off exponentially for up to 24 hours.

Ordered per workspace

A sequence field increases monotonically. Receiving 48213 after 48215 means it is a late retry and can be discarded.

Disabled after 48h

An endpoint failing continuously for two days is switched off and the workspace admin is emailed. Ten second timeout per attempt.

Stop guessing what your agents are running.

Connect one workspace and see every skill, rule, and memory your team has in play — in about ten minutes.

Start free Talk to us

No credit card. Works with what you already run.