Back to home

Resources · Documentation

API Reference

Everything you need to start tracking automation reliability. One endpoint, no SDK required.

Quick Start

Leaf Loom works by receiving a webhook POST from your automation tool each time a workflow runs. Your API key is generated when you sign up. Paste the endpoint URL into Zapier, Make, n8n, or any tool that supports webhooks.

Endpoint
POST /api/webhook/log/{user_id}?key={api_key}

Your user ID and API key are both found in the Automations tab of your dashboard. The API key goes in the query string, not the request body.

Webhook API

Method Path Auth
POST /api/webhook/log/:user_id?key=:api_key API key in query string

Response Codes

Code Meaning When it happens
200 OK Webhook received and logged successfully.
401 Unauthorized API key is missing, invalid, or has been deactivated.
404 Not Found The user_id in the URL does not match any account.
422 Unprocessable Request body is malformed or missing a required field.
429 Too Many Requests Rate limit exceeded. The webhook endpoint allows 60 requests per minute per API key. Back off and retry after 60 seconds.
500 Server Error Unexpected error on our end. If this persists, contact support.

Payload Reference

Send a JSON body with each webhook call. The API key goes in the URL as a query parameter. Only workflow_name is required; everything else is optional.

JSON
POST /api/webhook/log/YOUR_USER_ID?key=YOUR_KEY

{
  "workflow_name": "Send Weekly Report",        // required
  "workflow_id":   "zapier-weekly-001",
  "status":        "success",                    // "success" | "error" — defaults to "success"
  "duration_ms":   1240,
  "platform":      "zapier",                   // defaults to "webhook"
  "error_message": null,
  "extra_data": [                              // optional — add any custom key/value pairs
    { "key": "records_processed", "value": 42 },
    { "key": "triggered_by",      "value": "schedule"  },
    { "key": "environment",      "value": "production" }
  ]
}
Field Type Required Description
workflow_name string required Name of the workflow. Each unique name creates a separate tracked automation.
status string optional "success" or "error". Defaults to "success" if omitted.
workflow_id string optional A stable ID for the workflow (e.g. a Zapier Zap ID). Auto-generated from workflow_name if omitted.
duration_ms integer optional How long the run took in milliseconds.
platform string optional The tool the automation runs on: zapier, make, n8n, etc. Defaults to "webhook".
error_message string optional Error detail when status is "error".
extra_data array optional Array of { "key": string, "value": any } objects. Add as many custom pairs as you need — e.g. records_processed, triggered_by, environment.

How Automations Work

One key, many automations

You use a single API key across all your workflows. Each automation is tracked separately based on its workflow_name field, so you get per-automation scoring without managing multiple keys.

Every unique workflow_name automatically creates a separate automation entry in your dashboard with its own reliability score, grade, and history.

Two workflows, one key
// Workflow 1
POST /api/webhook/log/YOUR_USER_ID?key=YOUR_KEY
{
  "workflow_name": "Email Welcome Sequence",
  "status":        "success",
  "duration_ms":   1240,
  "platform":      "zapier"
}

// Workflow 2 — same key, tracked separately
POST /api/webhook/log/YOUR_USER_ID?key=YOUR_KEY
{
  "workflow_name": "Lead Sync to CRM",
  "status":        "error",
  "duration_ms":   820,
  "error_message": "Field mapping failed",
  "platform":      "make"
}

Tip: Your API key and user ID are both on the Automations tab in your dashboard. The key goes in the URL query string, not the request body.

How quiet workflow detection works: Leaf Loom can only detect a workflow going silent if it has sent at least one webhook previously. A brand-new automation that has never fired will not appear — there is no record of it yet. Once a workflow has run at least once, Leaf Loom tracks its last-seen timestamp and will flag it on your dashboard if no webhook arrives for 7 or more days.

Health Alerts

Automated checks on every dashboard load

Every time you open your dashboard, Leaf Loom runs two health checks across your automations and surfaces issues at the top of the page — no configuration needed.

⏸️

Quiet Workflows

Any automation that Leaf Loom has previously seen but has not received a webhook from in 7 or more days is flagged as quiet. This catches workflows that may have been paused, broken upstream, or accidentally disconnected from the webhook.

Caveat: Only automations that have sent at least one webhook are tracked. A brand-new automation that has never fired will not appear here — Leaf Loom has no record of it yet.

🔁

Recurring Errors

Any automation with a 50% or higher error rate across at least 3 runs in the last 30 days is flagged. This distinguishes a one-off failure from a structural problem — a workflow that keeps failing the same way on every run.

Open the Reports tab and select the flagged automation to see the per-day breakdown and identify when the errors started.

Health alerts are informational only — they do not affect your reliability score or grade. They are designed to surface problems you might otherwise miss by only looking at aggregate metrics.

Responses

200

OK

Log recorded. Score updated.

400

Bad Request

Missing or invalid fields in the request body.

401

Unauthorized

Invalid or missing API key.

404

Not Found

User ID not found.

Custom Scoring Rules

Custom scoring rules let you adjust an automation's reliability score beyond the raw success rate. Rules are evaluated against every individual run in the selected period — not a merged snapshot. Up to 500 active rules are supported per automation.

How the adjusted score is calculated

The base score is the success rate (0–100). Each rule is evaluated against every individual run in the period. The average per-run adjustment is added to the base score. The final result is clamped between 0 and 100.

adjusted_score = base_score + Σ(Total Points ÷ Total Runs)
where Total Points = times_fired × points_per_hit (per rule)
result is clamped to [0, 100]

Worked example — 200 runs, 3 rules

Rule Points per Hit Times Fired Total Points Avg / Run
Low Record Count −3 11 / 200 −33 −0.17
Full Sync Completed +2 66 / 200 +132 +0.66
Sync Warnings Detected −2 67 / 200 −134 −0.67
avg_adjustment (Σ Avg/Run) −0.2
adjusted_score = 95.4 + (−33 + 132 − 134) ÷ 200 = 95.4 + (−0.2) = 95.2

The score reflects what the average run contributed — not a single worst-case or best-case evaluation.

Available context fields

Every rule condition and formula can reference these variables. Metric fields are always present. Metadata fields appear automatically as new extra_data keys are received via webhook.

Field Type Source Description
success_rate float Metric Percentage of successful runs (0–100)
avg_duration float Metric Average run duration in milliseconds
total_runs float Metric Total number of runs recorded
duration_ms float Metric Duration of the most recent run in ms
<extra_data key> any Metadata Any key sent in the extra_data array of a webhook run. Discovered automatically.

Rule structure

Each rule has an optional condition and a required action. If no condition is set, the rule fires unconditionally on every evaluation.

Rule JSON
{
  "name": "Penalise high record count",
  "if": {
    "key": "records_processed",
    "operator": ">",
    "value": "100"
  },
  "action": {
    "type": "static_penalty",
    "value": 10
  }
}

Condition operators

Operator Works with Description
= text, number Exact match (case insensitive)
!= text, number Not equal (case insensitive)
> number Greater than
< number Less than
>= number Greater than or equal
<= number Less than or equal
contains text Field value contains the given string
exists any Field is present in the run context

Action types

static_penalty

Subtract a fixed amount from the score.

{ "type": "static_penalty", "value": 10 }
static_bonus

Add a fixed amount to the score.

{ "type": "static_bonus", "value": 5 }
dynamic_formula

Compute the adjustment using a mathematical expression over context fields. Only numeric fields can be used. Supports +, -, *, /, % and parentheses.

{ "type": "dynamic_formula", "formula": "(avg_duration - 1000) / 500" }

Score clamping: The adjusted score is always kept between 0 and 100. If aggressive bonus rules push the raw result above 100, it is capped at 100.0. If aggressive penalty rules push it below 0, it is floored at 0.0. The dashboard will show the clamped value; the formula bar still shows the full calculation so you can see by how much the score was constrained.

Limits

Limit Value Notes
Active rules per automation 500 All active rules are evaluated against every run in the period. Delete unused rules to stay within the limit.
Triggered rules shown in report 20 Top 20 triggered rules are displayed. The total adjustment and formula are always computed from all rules.
Adjusted score range 0 – 100 The result is clamped. Bonuses cannot push the score above 100; penalties cannot push it below 0.
Formula operators + − × ÷ % Only numeric constants and context fields are allowed in dynamic_formula rules. No functions or string literals.

Examples

cURL

Terminal
curl -X POST "http://localhost:8000/api/webhook/log/YOUR_USER_ID?key=YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workflow_name":"My Workflow","status":"success","duration_ms":850}'

JavaScript (fetch)

JavaScript
await fetch('http://localhost:8000/api/webhook/log/YOUR_USER_ID?key=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    workflow_name: 'My Workflow',
    status: 'success',
    duration_ms: 850
  })
});

Ready to start tracking?

Sign up free and get your API key in seconds.

Get your API key