{
  "openapi": "3.0.1",
  "info": {
    "title": "Automation Health Watchdog",
    "description": "Detect missed runs, explicit failures, empty output, and dead-letter growth in workflow observations you supply. Returns auditable verdicts and explicit unknowns instead of false green status.",
    "version": "0.1",
    "x-build-id": "xJ9MdYYs7P3bE2JWd"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mehdi_badawi~automation-health-watchdog/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mehdi_badawi-automation-health-watchdog",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/mehdi_badawi~automation-health-watchdog/runs": {
      "post": {
        "operationId": "runs-sync-mehdi_badawi-automation-health-watchdog",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/mehdi_badawi~automation-health-watchdog/run-sync": {
      "post": {
        "operationId": "run-sync-mehdi_badawi-automation-health-watchdog",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "contractVersion": {
            "title": "Contract version",
            "maxLength": 16,
            "type": "string",
            "description": "Must equal 1.0.0 when provided. The Actor stamps the current contract version when omitted.",
            "default": "1.0.0"
          },
          "evaluationTime": {
            "title": "Evaluation time",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$",
            "type": "string",
            "description": "ISO-8601 instant treated as 'now' for all comparisons, with seconds and an explicit offset (e.g. 2026-09-12T09:05:00Z). The contract requires an explicit instant; leave null in saved schedule inputs so the Actor fills in each run's own start instant. Pin this in tests and replays for deterministic output."
          },
          "workflows": {
            "title": "Workflows under watch",
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "description": "Client workflows to evaluate, in the canonical contract shape. Each entry needs platform, id, label, and a schedule.",
            "items": {
              "type": "object",
              "properties": {
                "platform": {
                  "title": "Platform",
                  "type": "string",
                  "description": "Automation platform hosting the workflow. 'manual' covers heartbeats or observations submitted by hand.",
                  "editor": "select",
                  "enum": [
                    "n8n",
                    "make",
                    "zapier",
                    "apify",
                    "manual",
                    "other"
                  ],
                  "enumTitles": [
                    "n8n",
                    "Make",
                    "Zapier",
                    "Apify",
                    "Manual / heartbeat",
                    "Other"
                  ]
                },
                "id": {
                  "title": "Workflow ID",
                  "type": "string",
                  "description": "Stable, unique identifier for this workflow. Joined to observations and hysteresis state via the canonical key '<platform>/<id>'.",
                  "minLength": 1,
                  "maxLength": 256
                },
                "label": {
                  "title": "Client-safe label",
                  "type": "string",
                  "description": "Human-readable label safe to show the client, copied verbatim into output rows.",
                  "minLength": 1,
                  "maxLength": 256
                },
                "platformDetail": {
                  "title": "Platform detail",
                  "type": "string",
                  "description": "Optional free-text platform detail (meaningful mainly when platform is 'other').",
                  "maxLength": 128,
                  "nullable": true
                },
                "tags": {
                  "title": "Tags",
                  "type": "array",
                  "description": "Optional grouping tags, echoed on the row.",
                  "editor": "json",
                  "maxItems": 16,
                  "items": {
                    "type": "string",
                    "maxLength": 64
                  }
                },
                "sourceRef": {
                  "title": "Designated source",
                  "type": "string",
                  "description": "Optional id of the sources[] entry that is authoritative for this workflow's coverage. When set, only that source may attest absence for this workflow.",
                  "maxLength": 128,
                  "nullable": true
                },
                "activatedAt": {
                  "title": "Activated at",
                  "type": "string",
                  "description": "Optional ISO-8601 instant the workflow was activated upstream. Due instants before this are not evaluated.",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$",
                  "nullable": true
                },
                "schedule": {
                  "title": "Schedule",
                  "type": "object",
                  "description": "Canonical schedule object. kind 'deadline': {expectedAt, graceSeconds?}. kind 'interval': {everySeconds, anchorAt, graceSeconds?}. kind 'adhoc': {}, optionally {trigger:{type}} to require trigger-health evidence. expression/timezone/nextExpectedAt are carried as metadata and never parsed.",
                  "editor": "json"
                },
                "pauses": {
                  "title": "Declared pauses",
                  "type": "array",
                  "description": "Optional declared maintenance windows [{from, until, reason?}] (half-open). Due instants inside a pause are excused, never stale.",
                  "editor": "json",
                  "items": {
                    "type": "object"
                  }
                },
                "outputContract": {
                  "title": "Output contract",
                  "type": "object",
                  "description": "Optional declared output invariant {minOutputItems?, requiredFields?, successSignal?{field, equals, onAbsent: 'unknown'|'fail'|'skip'}}. A claimed success violating it is empty-output or errored, never ok.",
                  "editor": "json",
                  "nullable": true
                },
                "backlog": {
                  "title": "Backlog invariant",
                  "type": "object",
                  "description": "Optional dead-letter/incomplete invariant {mode:'above'|'increase', baseline?, maxGrowth, counter:'dlqCount'|'incompleteCount'}.",
                  "editor": "json",
                  "nullable": true
                },
                "maxRunSeconds": {
                  "title": "Max run seconds",
                  "type": "integer",
                  "description": "Optional bound enabling run-incomplete detection: a claimed 'running' observation older than this without finishedAt is stale — the completed run provably never arrived.",
                  "minimum": 1,
                  "nullable": true
                },
                "maxRunsPerWindow": {
                  "title": "Max runs per window",
                  "type": "integer",
                  "description": "Optional execution-count invariant. More covering trusted observations than this for one due instant is errored (max-executions-exceeded). Undeclared means no bound.",
                  "minimum": 1,
                  "nullable": true
                },
                "hysteresis": {
                  "title": "Hysteresis override",
                  "type": "object",
                  "description": "Optional per-workflow override of config.hysteresis {enterAfter, recoverAfter} (consecutive detections required to enter a failure status / to recover to ok).",
                  "editor": "json",
                  "nullable": true
                }
              },
              "required": [
                "platform",
                "id",
                "label",
                "schedule"
              ],
              "additionalProperties": false
            }
          },
          "sources": {
            "title": "Source attestations",
            "maxItems": 100,
            "type": "array",
            "description": "Optional fetch receipts and coverage attestations in the canonical shape {id, platform, mechanism?, connector?, fetchedAt?, fetch{status, detail?, httpStatus?, retries?, uri?}, coverage?{completeThrough, coversAllWorkflows?, workflowKeys?, returnedCount?}, claims?{workflowStates, runClaims}}. fetch.status is ok|unauthorized|rate_limited|timeout|malformed|unavailable; only status 'ok' attests absence. Claims attest upstream state (scheduleEnabled, trigger subscription, identity hints, per-run claimed status).",
            "items": {
              "type": "object"
            },
            "default": []
          },
          "observations": {
            "title": "Observations",
            "maxItems": 10000,
            "type": "array",
            "description": "Normalized run records in the canonical shape {id, runId?, workflow{platform,id}, sourceRef?, observedAt, finishedAt?, claimed, signals?, output?{itemCount, byteSize?, digest?, sample?}, queue?{dlqCount, incompleteCount}, steps?, error?, outputTruncated?, provenance?{mechanism, connector?, retrievedAt?, uri?, note?, requestId?}}. claimed is success|failure|running|unknown. Order does not matter; malformed entries are quarantined as evidence, never silently healthy.",
            "items": {
              "type": "object"
            },
            "default": []
          },
          "config": {
            "title": "Evaluation config",
            "type": "object",
            "description": "Optional knobs {lookbackSeconds, defaultGraceSeconds, maxFutureSkewSeconds, hysteresis{enterAfter, recoverAfter}, limits{maxWorkflows, maxObservations, maxObservationsPerWorkflow, maxInputBytes, maxConnectorTimeoutMs, maxConnectorRetries, maxReasonsPerRow, maxStringLength, maxSignalsFields}}. Limits may only tighten the contract caps; out-of-range values fail the run."
          },
          "priorState": {
            "title": "Prior state",
            "type": "object",
            "description": "Optional hysteresis state blob {stateVersion, workflows{<key>:{stableStatus, stableSince?, pendingStatus, pendingCount, consecutiveDetections, lastDetection, lastEvaluatedAt, lastTrustedDlqCount?, lastTrustedIncompleteCount?}}} as returned by a previous run's nextState. The Actor normally supplies this from the named state store; pass it explicitly to replay or seed state."
          },
          "stateStoreName": {
            "title": "Hysteresis state store",
            "pattern": "^[a-zA-Z0-9-_.]*$",
            "minLength": 1,
            "maxLength": 128,
            "type": "string",
            "description": "Actor adapter setting (not part of the deterministic core input): name of the Apify key-value store used to persist nextState between scheduled runs. Set to null to disable persistence (each run then evaluates hysteresis from scratch, which can re-alert). Must be unique per task or schedule: two tasks sharing a store contaminate each other's hysteresis state.",
            "default": "automation-health-watchdog-state"
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}