Your devices send pings. OpenFence detects when they enter, exit, or dwell within geofences you define. Authenticated webhooks deliver those events to your platform with a Stripe-style signed payload — so you stay the system of record for your domain, and OpenFence stays the source of truth for spatial signal.
Multi-tenant by design. Per-tenant signing secrets. Symmetric replay defense. Cross-repo test fixtures.
Three moving pieces. OpenFence is the middle one. The other two stay yours.
Vehicles, mobile clients, IoT trackers — anything with a tenant API key — POST location pings to
/api/v1/pings.
Single-ping or batched up to 100 per request.
Geofence enter / exit / dwell, plus a rules engine for temporal predicates (only-during-business-hours), cooldown suppression, and multi-step sequence rules. All evaluation is explainable end-to-end through trace.
Authenticated HMAC-SHA256 deliveries with timestamp + replay defense. Retry / backoff / dead-letter built in. Your receiver verifies, dedupes by event_id, and persists raw — then your domain logic decides what to do.
OpenFence stays domain-agnostic on purpose. The events it emits are generic primitives —
geofence.enter,
exit,
dwell,
rule.triggered.
Your platform interprets them in your language.
Dispatch knows when crews arrive, depart, or dwell at origin / destination / terminal stops. Tariff-relevant time-on-site flows automatically into BOL evidence.
Technicians arrive on-site → time clock starts. Departure → invoice line closes. No "did you remember to clock in" friction.
Containers leave the yard, trailers enter the port, equipment arrives at the jobsite — your inventory system sees it within seconds.
Kid arrives at school zone → parent gets a push notification. Late arrival or absence flagged before homeroom takes attendance.
Restricted-area entry, court-ordered geofence violations, regulated-zone dwell — auditable spatial-event trail your case management consumes.
Patient leaves safe zone, wanderer crosses risk threshold — caregiver alerted before it becomes an incident.
OpenFence ships a generator-backed test-vectors fixture with every release. Your receiver pins against the same JSON file. If our signing helper drifts, your tests break loud — no silent contract creep.
docs/integration/consumer-integration.md — wire format, tenant mapping,
auth, webhooks, operational concerns, open questions.
docs/integration/openfence-webhook-test-vectors.json — 11 byte-exact cases:
valid, stale, future, tampered, malformed, non-UTF-8.
X-OpenFence-Signature: t=<unix_seconds>,v1=<hex_hmac_sha256>
X-OpenFence-Timestamp: <unix_seconds>
X-OpenFence-Webhook-Id: <subscription_uuid>
X-OpenFence-Delivery-Id: <delivery_uuid> # stable across retries
X-OpenFence-Request-ID: <correlation_uuid> # when set
Content-Type: application/json
# signed_input = f"{timestamp}.".encode("ascii") + body_bytes
# Verify: HMAC-SHA256(signing_secret, signed_input).hexdigest()
# Reject: outside ±5 min freshness window, malformed/duplicate keys, hex-shape mismatch
OpenFence is in early access. The first consumer (a moving-operations platform) shipped its receiver this week. If your domain involves "did this thing arrive at this place" or "is it still there" — we'd like to hear about it.
Email usOr read the docs and the test-vectors fixture above first — most technical questions are answered there.