[{"data":1,"prerenderedAt":910},["ShallowReactive",2],{"guide:en:automations":3},{"id":4,"title":5,"body":6,"description":902,"extension":903,"meta":904,"navigation":905,"path":906,"seo":907,"stem":908,"__hash__":909},"guide_en/en/user/automations/index.md","Automations & Monitoring",{"type":7,"value":8,"toc":875},"minimark",[9,13,39,52,57,64,114,121,125,148,159,164,167,360,364,377,381,384,404,408,525,548,552,571,575,588,595,619,622,626,647,651,654,657,672,676,679,699,702,706,719,722,732,735,742,782,803,807,816,820,836,840,853,857,864,868],[10,11,5],"h1",{"id":12},"automations-monitoring",[14,15,16,17,21,22,25,26,29,30,34,35,38],"p",{},"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: ",[18,19,20],"strong",{},"automations"," that run actions when events occur, ",[18,23,24],{},"connections"," that link Aptli to systems outside it in either direction, ",[18,27,28],{},"ingestion"," that brings sensor and event data ",[31,32,33],"em",{},"in",", and ",[18,36,37],{},"monitoring"," that turns that incoming data into readings, alarms, and outcomes.",[14,40,41,42,45,46,51],{},"Automations is ",[18,43,44],{},"included in every plan",". What's metered is the number of connections and API keys you have — see ",[47,48,50],"a",{"href":49},"#the-connection-allowance","The connection allowance"," below.",[53,54,56],"h2",{"id":55},"the-pages-at-a-glance","The pages at a glance",[14,58,59,60,63],{},"Automations lives in its own ",[18,61,62],{},"Integrations"," navigation group:",[65,66,67,80],"table",{},[68,69,70],"thead",{},[71,72,73,77],"tr",{},[74,75,76],"th",{},"Page",[74,78,79],{},"What it's for",[81,82,83,94,104],"tbody",{},[71,84,85,91],{},[86,87,88],"td",{},[18,89,90],{},"Automations",[86,92,93],{},"Your automation rules, shown as plain-language sentences and grouped by the connection they act through.",[71,95,96,101],{},[86,97,98],{},[18,99,100],{},"Connections",[86,102,103],{},"Every inbound and outbound link to the outside world — set them up, test them, and see their health. Devices and Credentials are reached from here.",[71,105,106,111],{},[86,107,108],{},[18,109,110],{},"Activity",[86,112,113],{},"A combined, filterable log of everything sent out and pulled in.",[14,115,116,117,120],{},"Alarms don't have a page of their own — they're ",[18,118,119],{},"ambient",": a bell notification, a card on your home dashboard, and pins on the map, with a direct link into the full alarm ledger when you need it.",[53,122,124],{"id":123},"automations-when-if-then-grouped-by-connection","Automations — WHEN / IF / THEN, grouped by connection",[14,126,127,128,131,132,135,136,139,140,143,144,147],{},"An automation is a rule in the full ",[18,129,130],{},"trigger → conditions → actions"," shape, shown as a plain-language sentence: ",[18,133,134],{},"WHEN"," something happens, ",[18,137,138],{},"IF"," its conditions hold, ",[18,141,142],{},"THEN"," one or more actions run. Start a new one from the ",[18,145,146],{},"What should happen automatically?"," recipe gallery, or drop into the full editor.",[14,149,150,151,154,155,158],{},"The list groups your automations by the ",[18,152,153],{},"connection"," the first outbound action in each one uses — so everything wired to a particular webhook or database sits together — plus an ",[18,156,157],{},"Internal"," group for automations whose actions never leave Aptli (set a field, create a record, send a notification). Switch between a card view and a table, bulk enable, disable, or delete, and every edit stages in the version buffer like any other change until you submit it.",[160,161,163],"h3",{"id":162},"triggers","Triggers",[14,165,166],{},"Triggers are grouped by the part of Aptli they come from. A selection:",[168,169,170,206,226,246,263,283,301,314,331,345],"ul",{},[171,172,173,176,177,181,182,181,185,181,188,181,191,181,194,181,197,181,200,181,203],"li",{},[18,174,175],{},"Work"," — ",[178,179,180],"code",{},"workOrder.created",", ",[178,183,184],{},"workOrder.statusChanged",[178,186,187],{},"workOrder.reassigned",[178,189,190],{},"report.created",[178,192,193],{},"report.submitted",[178,195,196],{},"report.completed",[178,198,199],{},"report.validated",[178,201,202],{},"report.rejected",[178,204,205],{},"validation.statusChanged",[171,207,208,176,211,181,214,181,217,181,220,181,223],{},[18,209,210],{},"Projects & jobs",[178,212,213],{},"project.created",[178,215,216],{},"project.statusChanged",[178,218,219],{},"project.deleted",[178,221,222],{},"job.created",[178,224,225],{},"job.removed",[171,227,228,176,231,181,234,181,237,181,240,181,243],{},[18,229,230],{},"Inventory",[178,232,233],{},"inventory.created",[178,235,236],{},"stock.adjusted",[178,238,239],{},"stock.consumed",[178,241,242],{},"stock.consolidated",[178,244,245],{},"stock.droppedOff",[171,247,248,176,251,181,254,181,257,181,260],{},[18,249,250],{},"Imports & versions",[178,252,253],{},"geo.import.completed",[178,255,256],{},"geo.import.failed",[178,258,259],{},"version.submittedForReview",[178,261,262],{},"version.committed",[171,264,265,176,268,181,271,181,274,181,277,181,280],{},[18,266,267],{},"Users, files, help requests",[178,269,270],{},"user.invited",[178,272,273],{},"file.uploaded",[178,275,276],{},"file.quarantine_failed",[178,278,279],{},"helpRequest.created",[178,281,282],{},"helpRequest.statusChanged",[171,284,285,176,288,291,292,296,297,51],{},[18,286,287],{},"Public submissions",[178,289,290],{},"portalSubmission.created",", fired when someone files a request through a ",[47,293,295],{"href":294},"/guide/service-portal/","Service Portal",". Outbound-only — see ",[47,298,300],{"href":299},"#public-and-sensor-triggers-are-outbound-only","Public and sensor triggers",[171,302,303,176,306,309,310,313],{},[18,304,305],{},"Sensor & event ingestion",[178,307,308],{},"sensor.reading"," (a numeric reading came in) and ",[178,311,312],{},"ingest.event"," (an external happening came in, deduplicated by its own external id) — the bridge from ingestion to automation. Both outbound-only.",[171,315,316,176,319,322,323,326,327,330],{},[18,317,318],{},"Alarms",[178,320,321],{},"alarm.raised"," and ",[178,324,325],{},"alarm.resolved",". Unlike the ingestion triggers above, these are internally raised and trusted, so they carry the ",[18,328,329],{},"full action palette"," — a breach can create a work order, update a field, or notify someone, not just call out.",[171,332,333,176,336,181,339,181,342],{},[18,334,335],{},"Scheduled",[178,337,338],{},"schedule.daily",[178,340,341],{},"schedule.weekly",[178,343,344],{},"schedule.monthly",[171,346,347,176,350,181,353,181,356,359],{},[18,348,349],{},"SLA timers",[178,351,352],{},"timer.threshold",[178,354,355],{},"timer.expired",[178,357,358],{},"timer.escalated"," (emitted by running lifecycle timers)",[160,361,363],{"id":362},"public-and-sensor-triggers-are-outbound-only","Public and sensor triggers are outbound-only",[14,365,366,181,368,34,370,372,373,376],{},[178,367,290],{},[178,369,308],{},[178,371,312],{}," all originate outside a login — a member of the public, a sensor, or a polled feed. Automations on these triggers may only ",[18,374,375],{},"notify someone or call out"," (webhook, database write, file delivery); they can never create or change an internal record directly. This keeps an unauthenticated source from ever writing to your data, even by accident.",[160,378,380],{"id":379},"conditions","Conditions",[14,382,383],{},"Conditions narrow when a trigger fires, evaluated against the event context and ANDed together (all must pass):",[168,385,386,392,398],{},[171,387,388,391],{},[178,389,390],{},"workOrder.status == 'completed'"," — only on completion",[171,393,394,397],{},[178,395,396],{},"actor.email endsWith '@myorg.com'"," — only internal users",[171,399,400,403],{},[178,401,402],{},"job.featureCount > 1000"," — only large imports",[160,405,407],{"id":406},"actions","Actions",[65,409,410,420],{},[68,411,412],{},[71,413,414,417],{},[74,415,416],{},"Action",[74,418,419],{},"Does",[81,421,422,436,446,456,466,476,490,505,515],{},[71,423,424,433],{},[86,425,426,429,430],{},[18,427,428],{},"Send notification"," / ",[18,431,432],{},"Send email",[86,434,435],{},"Notify a user, role, or the record's creator/assignee",[71,437,438,443],{},[86,439,440],{},[18,441,442],{},"Create work order",[86,444,445],{},"Spawn a work order (with an optional linked job)",[71,447,448,453],{},[86,449,450],{},[18,451,452],{},"Create job",[86,454,455],{},"Spawn a job",[71,457,458,463],{},[86,459,460],{},[18,461,462],{},"Update field",[86,464,465],{},"Set a field on the triggering record",[71,467,468,473],{},[86,469,470],{},[18,471,472],{},"Run calculation",[86,474,475],{},"Execute a configured calculation rule",[71,477,478,483],{},[86,479,480],{},[18,481,482],{},"Start SLA timer",[86,484,485,486,489],{},"Start a lifecycle timer on the record (which later emits the ",[178,487,488],{},"timer.*"," triggers)",[71,491,492,497],{},[86,493,494],{},[18,495,496],{},"Call webhook",[86,498,499,500,504],{},"POST a signed JSON payload to an external URL — can also mint a one-time write-back capability so the destination can report a result (see ",[47,501,503],{"href":502},"#two-way-ticket-loop","the two-way ticket loop",")",[71,506,507,512],{},[86,508,509],{},[18,510,511],{},"Write to Postgres",[86,513,514],{},"Run a parameterised write against an external PostgreSQL database",[71,516,517,522],{},[86,518,519],{},[18,520,521],{},"Deliver artifact",[86,523,524],{},"Export the triggering records (JSON/CSV/GeoJSON) to a directory or S3-compatible bucket",[14,526,527,528,531,532,535,536,539,540,543,544,547],{},"Every automation has a built-in ",[18,529,530],{},"Test run"," panel — one button that fires it against a ",[18,533,534],{},"synthesised sample context"," for its trigger. Two things to know before you use it: it ",[18,537,538],{},"skips the conditions"," (it runs the actions directly), and it is ",[18,541,542],{},"not a dry run"," — outbound actions (webhook, Postgres, artifact delivery) ",[18,545,546],{},"execute for real"," against your configured destinations, just flagged with a test badge in Activity. 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.",[53,549,551],{"id":550},"run-automation-right-now-for-one-record","Run automation, right now, for one record",[14,553,554,555,181,558,181,561,34,564,566,567,570],{},"Some automations can also be fired manually against a single record, from that record's own menu — a supervisor's judgment call instead of waiting for the trigger to occur naturally. It's available on ",[18,556,557],{},"work orders",[18,559,560],{},"reports",[18,562,563],{},"stock items",[47,565,295],{"href":294}," submissions, for automations whose full context can be read straight off the record as it stands. It's gated on your right to update ",[31,568,569],{},"that record",", not on automations administration, since running it is simply using a rule someone already vetted — with a short cooldown per record so the same rule can't be re-fired back to back by accident.",[53,572,574],{"id":573},"connections-every-link-to-the-outside-world","Connections — every link to the outside world",[14,576,577,578,580,581,322,584,587],{},"The ",[18,579,100],{}," page lists every link between Aptli and something outside it, split into ",[18,582,583],{},"data coming in",[18,585,586],{},"data going out",". Each one shows its direction, how it moves (a plain-language transport label), and a health line — when it last ran and whether that run succeeded.",[14,589,590,591,594],{},"Set one up with the ",[18,592,593],{},"Connect"," wizard: pick a direction, pick how it moves, then fill in the details and test it live before saving.",[168,596,597,603,613],{},[171,598,599,602],{},[18,600,601],{},"Inbound, pushed"," — the sender POSTs to Aptli. Saving mints an API key, shown once — copy it then.",[171,604,605,608,609,612],{},[18,606,607],{},"Inbound, polled"," — Aptli checks a vendor on a schedule. Pick a vendor (a generic JSON source, a traffic-events feed, or a generic RSS/Atom feed for article- or announcement-style content) and fill in its connection details; a ",[18,610,611],{},"Manage sources"," panel is where you go back and edit those settings later.",[171,614,615,618],{},[18,616,617],{},"Outbound, webhook"," — give it a destination URL and test it with a real signed request before saving.",[14,620,621],{},"Devices and Credentials are reached from this page rather than being nav destinations of their own.",[53,623,625],{"id":624},"devices","Devices",[14,627,628,629,632,633,181,636,181,639,642,643,646],{},"A ",[18,630,631],{},"device"," is a registered sensor or gateway with its own record — distinct from a map feature — showing a live map overlay and an at-a-glance fleet-health state: ",[18,634,635],{},"ok",[18,637,638],{},"stale",[18,640,641],{},"no data",", or ",[18,644,645],{},"alarm",". Readings key either to the device's own id, or to a sender-controlled code when a device reports under its own naming.",[53,648,650],{"id":649},"credentials","Credentials",[14,652,653],{},"An escape hatch for admins: the secrets outbound actions authenticate with (bearer / basic / API-key HTTP, S3, Postgres), created once and referenced by name. Secrets are encrypted at rest and never shown again after saving; non-secret configuration stays readable.",[53,655,50],{"id":656},"the-connection-allowance",[14,658,659,660,663,664,667,668,671],{},"The commercial meter is the number of ",[18,661,662],{},"connections and API keys",", not the feature itself. Each live connection (either direction) and each standalone API key consumes one ",[18,665,666],{},"unit"," from a shared pool — a key attached to a push connection rides that connection's unit; the automations themselves are unmetered. The default allowance is ",[18,669,670],{},"3","; when you hit it, creating another prompts you to remove an unused one or contact support to add more. Connections you already have keep running if the allowance later shrinks.",[53,673,675],{"id":674},"ingestion-bringing-sensor-and-event-data-in","Ingestion — bringing sensor and event data in",[14,677,678],{},"Ingested data flows through two lanes:",[168,680,681,690],{},[171,682,683,686,687,689],{},[18,684,685],{},"Readings"," — a numeric time series (a sensor's value at a point in time). Every batch fires the ",[178,688,308],{}," trigger and feeds the alarm engine described below.",[171,691,692,695,696,698],{},[18,693,694],{},"Events"," — an external happening with its own identity, and often a location and a time window (an article being published, a traffic incident). Each one fires the ",[178,697,312],{}," trigger, deduplicated by its own external id so re-polling the same source never creates duplicates.",[14,700,701],{},"Both lanes accept data pushed to Aptli or pulled from a vendor on a schedule, and both funnel through the same pipeline: store it, update the connection's health, log the activity, and check it against alarms.",[53,703,705],{"id":704},"monitoring-alarms","Monitoring & Alarms",[14,707,708,709,711,712,322,715,718],{},"Ingestion gets sensor data ",[31,710,33],{},"; monitoring is what you ",[31,713,714],{},"see",[31,716,717],{},"are warned about",".",[160,720,685],{"id":721},"readings",[14,723,724,725,728,729,718],{},"Once readings are flowing for a connection, its record — or the device's record — shows the ",[18,726,727],{},"latest value and unit"," for each metric, plus a ",[18,730,731],{},"7-day sparkline",[160,733,318],{"id":734},"alarms",[14,736,737,738,741],{},"Alarm rules live on the connection. Turn on ",[18,739,740],{},"Raise alarms"," and set:",[168,743,744,750,756,766,772],{},[171,745,746,749],{},[18,747,748],{},"Alarm when value is"," — above or below a threshold",[171,751,752,755],{},[18,753,754],{},"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)",[171,757,758,761,762,765],{},[18,759,760],{},"Silence alarm after (minutes)"," — raise a ",[31,763,764],{},"silence"," alarm if no data arrives for this long (push connections only — a poll connection's own health line already shows when a check fails)",[171,767,768,771],{},[18,769,770],{},"Alarm recipients"," — who gets notified",[171,773,774,777,778,781],{},[18,775,776],{},"Escalate if unacknowledged after (minutes)"," + ",[18,779,780],{},"Escalation recipients"," — a second tier if no one acknowledges in time",[14,783,784,785,788,789,181,792,642,795,798,799,802],{},"Every signed-in user can see the live alarm ledger — watching alarms is an operations task, not a configuration one — but ",[18,786,787],{},"acknowledging or resolving"," an alarm requires automations administration rights. Each alarm is ",[18,790,791],{},"Active",[18,793,794],{},"Acknowledged",[18,796,797],{},"Resolved"," (alarms also auto-clear when the reading recovers past the clear margin); it carries its value, threshold, and peak, who acknowledged it, and — if it escalated — an ",[18,800,801],{},"\"Escalated {date}\""," line with a delivery-status badge. A home-dashboard card and map pins surface active alarms so they don't sit unseen.",[160,804,806],{"id":805},"two-way-ticket-loop","Two-way ticket loop",[14,808,628,809,811,812,815],{},[18,810,496],{}," action can carry a ",[18,813,814],{},"write-back capability",": your external ticketing system POSTs a status change back to acknowledge or resolve the alarm using a one-time token, and the ticket's reference shows on the alarm as a link. This closes the loop when alarms are handled in another tool.",[160,817,819],{"id":818},"outcomes-and-share-links","Outcomes and share links",[14,821,822,823,826,827,831,832,835],{},"On a project, the ",[18,824,825],{},"Outcomes"," tab charts monitored metric series against completed-work milestones — see ",[47,828,830],{"href":829},"/addons/fulfillment/plan/#outcomes--did-the-work-move-the-needle","Projects",". You can publish a read-only, tokenized ",[18,833,834],{},"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.",[53,837,839],{"id":838},"activity-the-combined-log","Activity — the combined log",[14,841,577,842,844,845,848,849,852],{},[18,843,110],{}," page is a single, filterable feed of every outbound attempt and inbound pull: date, automation or connection, outcome (",[18,846,847],{},"Success / Failed / Retrying / Dead letter","), attempt count, duration, and any error. Test runs are badged. Failed items get a one-click ",[18,850,851],{},"Retry",", and you can deep-link straight into one connection's history.",[53,854,856],{"id":855},"quick-connect","Quick Connect",[14,858,859,860,863],{},"For common integrations, the ",[18,861,862],{},"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 connection and automation for you.",[53,865,867],{"id":866},"permissions","Permissions",[14,869,870,871,874],{},"Automations doesn't use the global admin-rights grid. The Automations and Connections pages — and acknowledging or resolving alarms — are gated by a ",[18,872,873],{},"viewers / modifiers"," allow-list in the automations settings, so you grant access explicitly. Viewing the alarm ledger 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.",{"title":876,"searchDepth":877,"depth":877,"links":878},"",2,[879,880,887,888,889,890,891,892,893,899,900,901],{"id":55,"depth":877,"text":56},{"id":123,"depth":877,"text":124,"children":881},[882,884,885,886],{"id":162,"depth":883,"text":163},3,{"id":362,"depth":883,"text":363},{"id":379,"depth":883,"text":380},{"id":406,"depth":883,"text":407},{"id":550,"depth":877,"text":551},{"id":573,"depth":877,"text":574},{"id":624,"depth":877,"text":625},{"id":649,"depth":877,"text":650},{"id":656,"depth":877,"text":50},{"id":674,"depth":877,"text":675},{"id":704,"depth":877,"text":705,"children":894},[895,896,897,898],{"id":721,"depth":883,"text":685},{"id":734,"depth":883,"text":318},{"id":805,"depth":883,"text":806},{"id":818,"depth":883,"text":819},{"id":838,"depth":877,"text":839},{"id":855,"depth":877,"text":856},{"id":866,"depth":877,"text":867},"Connect Aptli to the outside world: plain-language automation rules, inbound and outbound connections, sensor and event ingestion, and outcome monitoring with threshold alarms.","md",{},true,"/en/user/automations",{"title":5,"description":902},"en/user/automations/index","UVM-NK-z6YiiaisjJ_kxu3OXiml_SJ5_W7su0UlM6Sc",1786042870803]