Any platform over HTTP¶
There is no SDK requirement. If your tool can make an HTTP POST, it can report runs. The full field reference is in Recording runs; these are working starting points for the platforms we see most.
In every example: report failures too (wire the error path), and pass the
job id your platform already has as external_id so retries dedupe.
curl / bash¶
curl -sS -X POST "$LUMATRACK_URL/api/v1/runs" \
-H "Authorization: Bearer $LUMATRACK_KEY" \
-H "Content-Type: application/json" \
-d '{"automation": "cert-renewal", "status": "success", "source": "cron", "external_id": "'"$(date +%Y%m%d)"'-cert-renewal"}'
Ansible¶
A task at the end of the play; add a rescue block that posts
status: failure.
- name: Report run to LumaTrack
ansible.builtin.uri:
url: "{{ lumatrack_url }}/api/v1/runs"
method: POST
headers:
Authorization: "Bearer {{ lumatrack_key }}"
body_format: json
body:
automation: os-patching
status: success
source: ansible
external_id: "{{ awx_job_id | default(omit) }}"
status_code: [200, 201, 202]
GitHub Actions¶
if: always() makes the step run on failure too, and the expression maps
the job result to the right status.
- name: Report run to LumaTrack
if: always()
env:
LUMATRACK_URL: ${{ vars.LUMATRACK_URL }}
LUMATRACK_KEY: ${{ secrets.LUMATRACK_KEY }}
run: |
STATUS="${{ job.status == 'success' && 'success' || 'failure' }}"
curl -sS -X POST "$LUMATRACK_URL/api/v1/runs" \
-H "Authorization: Bearer $LUMATRACK_KEY" \
-H "Content-Type: application/json" \
-d "{\"automation\": \"deploy-pipeline\", \"status\": \"$STATUS\", \"source\": \"github-actions\", \"external_id\": \"${{ github.run_id }}-${{ github.run_attempt }}\"}"
PowerShell¶
$Body = @{
automation = "ad-user-offboarding"
status = "success"
source = "powershell"
external_id = $JobId
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/v1/runs" `
-Headers @{ Authorization = "Bearer $ApiKey" } `
-ContentType "application/json" -Body $Body
Go¶
payload, _ := json.Marshal(map[string]any{
"automation": "log-rotation",
"status": "success",
"source": "go",
"external_id": jobID,
})
req, _ := http.NewRequest("POST", baseURL+"/api/v1/runs", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
C¶
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
var payload = JsonSerializer.Serialize(new {
automation = "mailbox-provisioning",
status = "success",
source = "csharp",
external_id = jobId,
});
var response = await http.PostAsync($"{baseUrl}/api/v1/runs",
new StringContent(payload, Encoding.UTF8, "application/json"));
Java¶
String payload = """
{"automation": "vm-snapshot-cleanup", "status": "success",
"source": "java", "external_id": "%s"}""".formatted(jobId);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/api/v1/runs"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
ServiceNow, Jira, and other ITSM platforms¶
Any platform with an outbound REST step works today: in ServiceNow, a Flow Designer REST step (or an outbound REST Message fired from a Business Rule) posting the JSON above; equivalents exist in Jira Automation and Zendesk webhooks. Purpose-built ITSM connectors with deflection measurement are on the LumaTrack roadmap; until then, outbound REST is the supported path.
MSP automation platforms (Rewst, Pia, custom RMM scripts)¶
MSP platforms that can make an outbound HTTP call at the end of a workflow report runs the same way. The pattern for a multi-client book:
- One LumaTrack client workspace per managed client (MSP plan). Each client org has its own API key, so the value ledger, the QBR report, and the audit trail stay per client by construction.
- Add one HTTP step at the end of each workflow (in Rewst: an HTTP
request action as the workflow's last step; consult your platform's
docs for the exact action name). POST the JSON below with the client
org's key. Map your platform's execution id to
external_idso retried workflows dedupe instead of double-counting. - Wire the failure path too. A workflow that only reports success produces a number nobody should put in front of a client.
{
"automation": "user-onboarding",
"status": "success",
"source": "rewst",
"external_id": "<your platform's execution id>",
"duration_seconds": 42
}
Time-saved dashboards inside the platform remain useful as internal meters. What this step adds is the client-facing layer: dollars, per client, across every tool you run, with the methodology printed on the page. Setup cost, honestly: one HTTP step per workflow, then a few minutes of baseline entry per automation (the counterfactual minutes and rate the dollar figure is computed from; labeled as your assumption on every report).
If editing every workflow is impractical, two alternatives: a single "reporter" workflow your other workflows call as a sub-step, or a nightly backfill of an execution-log CSV export.