Power Automate¶
A custom connector records one run event per flow execution. Import it once per environment, add the Record a run action at the end of a flow, and the value report builds itself.
The connector's definition is derived from the LumaTrack OpenAPI spec, so its fields are the API's fields. Power Platform accepts Swagger 2.0 only, which is what the file you import is.
Import the connector¶
Download apiDefinition.swagger.json from the
integrations directory,
then:
- Open make.powerautomate.com and pick your environment.
- In the left rail: More, then Discover all, then Custom connectors under Data.
- New custom connector, then Import an OpenAPI file.
- Name it
LumaTrackand choose the file. - On General, the host is prefilled as
lumatrack.io. Change it if you self-host. - On Security, confirm the API key parameter: in
header, namedAuthorization. - Create connector.
Create the connection¶
On the Test tab, create a connection and paste your key with the Bearer
prefix:
Bearer lmt_your_key_here
The Bearer prefix is required
Swagger 2.0 has no bearer scheme, so the key is modeled as an API key in the
Authorization header, and that header has to carry the whole value the API
expects. A key pasted on its own returns 401.
An ingest-only key is enough to record runs and is the one to use here: if it leaks, an attacker can post junk runs, and they cannot read or restate your ledger.
Record a run¶
Two fields show by default, and the rest are under show advanced options.
| Field | Notes |
|---|---|
| Automation slug | Required. Create it in the app or over the API |
| Status | success, failure, skipped or cancelled; defaults to success |
| Units processed | Records this run handled; drives per-unit valuation. Defaults to 1 |
| Duration (seconds) | Wall-clock runtime. Omit it rather than sending a guess |
| External ID | Idempotency key. Set it to workflow()['run']['name'], the flow run's own id, so a resubmitted flow never double-counts |
| Failure reason | Root cause, e.g. graph/throttled. Powers the failure-reason Pareto |
| Executed at | ISO 8601, for evidence that genuinely happened earlier. Frozen months are refused |
| Metadata | Arbitrary JSON kept with the run |
The action returns the run id, whether the request was a replay
(deduplicated), and whether the run was held over the
plan's monthly cap. All three are available as dynamic content in later steps. A
held run is stored and earns nothing, so a flow that cares can branch on it.
Report failures too¶
One action on the happy path is half the integration. Failed flows cost money and save nothing, and reporting them is what makes the reliability chart and the net numbers credible.
Two ways to wire it. Add a parallel branch whose Configure run after is set to
has failed, is skipped and has timed out, holding a second Record a run with
Status failure. Or wrap the real work in a Scope, put the reporting action after
it, and read result('Scope_name') to pick the status.
skipped and cancelled each book as themselves. A flow branch that a condition
gated out did no work, and a cancelled run did not finish. Neither earns value and
neither inflates your failure count; whether they carry the automation's per-run
cost is set per automation in LumaTrack.
Loops and volume¶
A flow that processes 240 rows should report one run with Units processed set to 240, rather than a Record a run inside an Apply to each. The ledger prices per-unit work as fixed setup plus marginal minutes per record, which is the number that survives a CFO's review. Two hundred and forty separate runs would each consume an event against your plan's monthly cap and tell you the same thing.
If each iteration genuinely is its own run, with its own success or failure, then
report per item and give each a unique External ID, e.g.
concat(workflow()['run']['name'], '-', string(iterationIndexes('Apply_to_each'))).
Child flows¶
A child flow gets its own run id, so a Record a run inside it reports that child's own execution and the External ID default stays unique. Give the child its own automation slug with its own baseline and it becomes a first-class automation.
Rate limits¶
Requests are counted per organization across every key. A 429 with Retry-After
is a rate limit; Power Automate's own retry policy handles it if you leave the
action's default retry on. A monthly event-cap 429 carries no Retry-After and
means the plan's ingestion ceiling was reached, so retrying will not help.
Anything else in Power Platform¶
Logic Apps and Power Apps consume the same custom connector definition, since all three read Swagger 2.0. For a one-off, an HTTP action pointed at the plain HTTP endpoint works without importing anything.