Automations & Monitoring
Automations is Aptli's integration layer — the way your deployment reacts to what happens inside it and connects to systems outside it. It covers four things: rules that fire actions when events occur, hooks that push events to other systems, ingestion that pulls sensor and device data in, and monitoring that turns that incoming data into readings, charts, and alarms.
Automations is included in every plan. What's metered is the number of external connections you wire up — see The connection allowance below.
The pages at a glance
Automations lives in its own navigation group with four pages:
| Page | Tabs | What it's for |
|---|---|---|
| Automations | Hooks · Event Triggers · Ingestion | Build outbound hooks, event-driven rules, and inbound data connectors. |
| Credentials | Outbound credentials · Inbound ingest keys | Store the secrets outbound actions use, and mint the API keys senders use to push data in. |
| Deliveries | Outbound deliveries · Inbound runs | A read-only activity log of everything sent out and pulled in. |
| Alarms | — | The live ledger of threshold and silence alarms. |
Hooks — the quick way to push events out
A hook is a signed destination subscribed to the events you pick. It's the simplest outbound integration: give it a Name, a Destination URL, the Events to send, a Signing secret (so the receiver can verify the payload came from you), and — optionally — a Payload template. Every matching event is POSTed to that URL. No conditions, no branching; just "send these events there."
Use a hook when another system just needs to know something happened. Reach for an Event Trigger (below) when you need conditions or a non-webhook action.
Event Triggers — rules that do something
An Event Trigger is the full trigger → conditions → actions engine. When an event fires and the conditions pass, one or more actions run. Start a new one from the What should happen automatically? recipe gallery, or drop into the full editor.
Triggers
Triggers are grouped by the part of Aptli they come from. A selection:
- Work —
workOrder.created,workOrder.statusChanged,report.completed,report.validated,report.rejected,validation.statusChanged - Projects & jobs —
project.created,project.statusChanged,job.created,job.removed - Inventory —
inventory.created,stock.adjusted,stock.transferred,stock.low - Imports & versions —
geo.import.completed,geo.import.failed,version.submittedForReview,version.committed - Users, files, help requests —
user.invited,file.uploaded,file.quarantine_failed,helpRequest.created,helpRequest.statusChanged - Sensor data —
sensor.reading(fires once per ingest batch, carrying that batch's aggregates — the bridge from ingestion to automation) - Alarms —
alarm.raisedandalarm.resolved(§293). Unlikesensor.reading, these carry the full action palette, so a breach can create a work order, update a field, or notify someone — not just fire a hook - Scheduled —
schedule.daily,schedule.weekly,schedule.monthly - SLA timers —
timer.threshold,timer.expired,timer.escalated(emitted by running lifecycle timers)
Conditions
Conditions narrow when a trigger fires, evaluated against the event context and ANDed together (all must pass):
workOrder.status == 'completed'— only on completionactor.email endsWith '@myorg.com'— only internal usersjob.featureCount > 1000— only large imports
Actions
| Action | Does |
|---|---|
| Send notification / Send email | Notify a user, role, or the record's creator/assignee |
| Call webhook | POST a signed JSON payload to an external URL |
| Write to Postgres | Run a parameterised write against an external PostgreSQL database |
| Deliver artifact | Export the triggering records (JSON/CSV/GeoJSON) to a directory, S3-compatible bucket, or webhook. (SFTP is selectable but not yet functional — a delivery to it is logged as failed.) |
| Create work order / assignment / job | Spawn a fulfillment record |
| Update field | Set a field on the triggering record |
| Run calculation | Execute a configured calculation rule |
| Start SLA timer | Start a lifecycle timer on the record (which later emits the timer.* triggers) |
Every trigger has a built-in Test run panel — one button that fires the rule against a synthesised sample context for its trigger. Two things to know before you use it: it skips the conditions (it runs the actions directly), and it is not a dry run — outbound actions (webhook, Postgres, artifact delivery) execute for real against your configured destinations, just flagged with a test badge in Deliveries. Emails are checked but not sent, and record-mutating actions (create/update) are skipped. So point a test at a safe destination; it's for confirming wiring, not a no-op preview.
Ingestion — bringing sensor and device data in
An ingest connector is an external data source that feeds readings into Aptli. Each connector has a Mode:
- Pull (scheduled poll) — Aptli polls a vendor's REST API on an Interval (minimum 30 seconds). You set the URL, a Credential, and a small response mapping (Readings path, Timestamp key, Value key, Metric key) so Aptli can read the vendor's JSON.
- Push (sender posts) — the sender POSTs JSON batches to the connector's own inbound endpoint (shown once you save the connector), authenticated with an ingest API key. Nothing to poll; the device or gateway pushes on its own schedule.
Either way, each connector names a Station feature ID (the map feature the readings belong to — see Monitoring & Alarms) and a Unit, and each batch it ingests fires the sensor.reading trigger. The Ingestion tab also shows a live view of scheduled polls (how many are active, delayed, or failed).
Credentials, keys, and the connection allowance
Outbound credentials
Outbound actions that reach an external system (webhooks, Postgres, S3/SFTP artifact delivery) authenticate through a stored credential rather than inline secrets. Create one once on the Credentials page and reference it by name. Secrets are encrypted at rest and never shown again after saving; non-secret config (base URLs, hostnames, regions) stays readable. Types: bearer / basic / API-key HTTP, S3, SFTP, and Postgres.
Inbound ingest keys
Machine bearer keys that let a sender push into Aptli. Ingest-only, scoped to what they're allowed to do (push readings in, or pull portal submissions out), and the raw key is shown once at creation — copy it then.
The connection allowance
The commercial meter is the number of external connections, not the feature itself. Each ingest connector, API key, and reusable outbound hook consumes one unit from a shared pool (internal event-trigger rules are unmetered). A chip on the Automations and Credentials pages shows "{used} of {total} connectors/keys" with a breakdown of connectors, API keys, and hooks. The default allowance is 3; when you hit it, creating another prompts you to revoke an unused one or contact support to add more. Connections you already have keep running if the allowance later shrinks.
Monitoring & Alarms
Ingestion gets sensor data in; monitoring is what you see and are warned about.
Stations and readings
A station is simply a map feature that a sensor reports against. By default a connector's Station feature ID is the feature's own id, so readings key straight to it; senders that use their own station codes can be linked explicitly.
Once readings are flowing, the feature's record grows a Sensor readings section: for each metric, the latest value and unit plus a 7-day sparkline. If a station goes quiet but its source is still sending under other ids (a sensor was renamed at the source), Aptli flags it and offers a one-click Relink so you don't lose the history.
Alarms
Alarm rules live on the ingest connector. Turn on Raise alarms and set:
- Alarm when value is — above or below a threshold
- Clear margin — how far back past the threshold a reading must go before the alarm auto-clears (hysteresis, so a value hovering on the line doesn't flap)
- Silence alarm after (minutes) — raise a silence alarm if no data arrives for this long (dead-sensor detection)
- Alarm recipients — who gets notified
- Escalate if unacknowledged after (minutes) + Escalation recipients — a second tier if no one acknowledges in time
The Alarms page is the live ledger. Each alarm is Active, Acknowledged, or Resolved; you Acknowledge it to signal someone's on it and Resolve it when it's handled (alarms also auto-clear when the reading recovers past the clear margin). Threshold alarms and silence ("no data received") alarms are shown distinctly, and an alarm carries its value/threshold/peak, who acknowledged it, and — if it escalated — an "Escalated {date}" line with a delivery-status badge. A home-dashboard card surfaces active alarms so they don't sit unseen. The Alarms page is visible to any signed-in supervisor, not just automations admins, so the people who watch the work can watch the alarms.
Two-way ticket loop
A hook can carry a write-back URL with each alarm: your external ticketing system POSTs status changes back to acknowledge or resolve the alarm, and the ticket's reference shows on the alarm as a link. This closes the loop when alarms are handled in another tool.
Outcomes and share links
On a project, the Outcomes tab charts monitored metric series against completed-work milestones — see Projects. You can publish a read-only, tokenized share link of those charts for outsiders, and revoke it any time. Readings are shown for context alongside work dates; Aptli makes no causal claim and the page is explicitly not certified measurement data.
Deliveries — the activity log
The Deliveries page is read-only history, in two tabs:
- Outbound deliveries — one row per outbound attempt: date, workflow, action, destination, outcome (Success / Failed / Retrying / Dead letter), attempt count, duration, and any error. Test runs are badged.
- Inbound runs — the ingest history: source, outcome, date, duration, rows, and error.
Quick Connect
For common integrations, the Quick connect wizard walks you through a recipe instead of the raw editor — e.g. "Send new portal submissions to my system," "Alert my system when stock runs low," "Create a ticket when an alarm is raised," or "Receive readings from my sensors or gateway." It wires the connector, hook, or rule for you.
Permissions
Automations doesn't use the global admin-rights grid. The three configuration pages (Automations, Credentials, Deliveries) are gated by a viewers / modifiers allow-list in the automations settings, so you grant access explicitly. The Alarms page is intentionally open to any signed-in user — watching alarms is an operations task, not a configuration one. Holders of the application-settings right always have a recovery path if the lists are empty.