{
  "openapi": "3.1.0",
  "info": {
    "title": "AgentScore API",
    "version": "1.0.0",
    "description": "The AgentScore platform surface. Everything the dashboard does goes\nthrough these same endpoints — there is no private backend.\n\n**Auth**: per-company API keys (`ask_…`) as `Authorization: Bearer`.\nKeys carry scopes (`read`, `write`, `admin`) and a company binding\nenforced centrally. Keys are hashed at rest and shown once at mint.\n\n**Ingestion contract**: KPI names are validated against the registry\nat write time, units are required and canonicalized (percent→fraction,\nms→s), dates must be real calendar dates, and batches are atomic —\nall-valid or rejected whole. Idempotency is per\n(agent, source, sourceRecordId): retries and re-syncs never duplicate.\n\n**Raw-first retention**: connectors land the complete upstream payload\nin an append-only, versioned vault before any KPI derivation.\n\nScoring model: asam_v2.1 · registry: 1.0.0."
  },
  "servers": [
    {
      "url": "https://api.agentscore.dev",
      "description": "Production"
    },
    {
      "url": "http://localhost:8787",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "Platform",
      "description": "Liveness and identity."
    },
    {
      "name": "Companies",
      "description": "Companies and their agent fleets."
    },
    {
      "name": "Ingestion",
      "description": "The validated KPI write path — the universal escape hatch for any agent no connector covers."
    },
    {
      "name": "Raw vault",
      "description": "Append-only, versioned retention of complete upstream payloads."
    },
    {
      "name": "Integrations",
      "description": "Credentialed connectors (HubSpot, Jobber): connect, sync, revoke."
    },
    {
      "name": "Scoring",
      "description": "Recompute and read scorecards."
    },
    {
      "name": "Webhooks",
      "description": "Outbound push: score drops, tier changes, governance caps — HMAC-signed to your endpoint."
    },
    {
      "name": "Admin",
      "description": "Key minting and the audit trail. Admin-scoped keys only."
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/healthz": {
      "get": {
        "tags": [
          "Platform"
        ],
        "operationId": "healthz",
        "security": [],
        "summary": "Liveness probe",
        "description": "The only unauthenticated route besides this spec. Touches no data.",
        "responses": {
          "200": {
            "description": "Service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    },
                    "model": {
                      "type": "string",
                      "examples": [
                        "asam_v2.1"
                      ]
                    },
                    "registry": {
                      "type": "string",
                      "examples": [
                        "1.0.0"
                      ]
                    },
                    "environment": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "tags": [
          "Platform"
        ],
        "operationId": "openapi",
        "security": [],
        "summary": "This document",
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1 spec."
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "tags": [
          "Platform"
        ],
        "operationId": "me",
        "summary": "Identify the calling key",
        "description": "Returns the key's scope class and bound company (null for platform admin keys).",
        "responses": {
          "200": {
            "description": "Caller identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scope": {
                      "type": "string",
                      "enum": [
                        "platform",
                        "company"
                      ]
                    },
                    "company": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/Company"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies": {
      "post": {
        "tags": [
          "Companies"
        ],
        "operationId": "createCompany",
        "summary": "Create a company",
        "description": "Admin scope. Vertical determines the sector used for coarse peer cells.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "vertical"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "vertical": {
                    "type": "string",
                    "examples": [
                      "field_services",
                      "multifamily"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}": {
      "get": {
        "tags": [
          "Companies"
        ],
        "operationId": "getCompany",
        "summary": "Read a company",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "The company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown or deleted company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Companies"
        ],
        "operationId": "deleteCompany",
        "summary": "Soft-delete a company",
        "description": "Admin scope. Marks the company deleted; the erasure path cascades from here.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "Soft-deleted."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/agents": {
      "post": {
        "tags": [
          "Companies"
        ],
        "operationId": "createAgent",
        "summary": "Register an agent",
        "description": "agentType keys the peer cell — it describes what the agent DOES (dispatch, sdr, support…), never its vendor.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "agentType",
                  "industry"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "agentType": {
                    "type": "string",
                    "examples": [
                      "dispatch",
                      "sdr",
                      "support"
                    ]
                  },
                  "industry": {
                    "type": "string"
                  },
                  "vendor": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Companies"
        ],
        "operationId": "listAgents",
        "summary": "List a company's agents",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "The fleet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Agent"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/agents/{agentId}/events": {
      "get": {
        "tags": [
          "Ingestion"
        ],
        "operationId": "listAgentEvents",
        "summary": "Read the events behind a score (the receipts)",
        "description": "Paged per-agent event history, newest first, each event tagged with its registry factor. This is the evidence trail: a capped agent's policy violations, a slow agent's response times — with dates. Filter by kpiName to drill into one metric.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "$ref": "#/components/parameters/agentId"
          },
          {
            "name": "kpiName",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "audit_failure_count",
                "cost_per_unit_impact",
                "customer_engagement_quality",
                "customer_satisfaction",
                "data_volume_confidence",
                "defect_detection_accuracy",
                "downtime_reduction",
                "explainability_completeness",
                "feedback_ingestion_lag_days",
                "human_override_rate",
                "integration_depth_score",
                "lead_conversion_rate",
                "meeting_book_rate",
                "period_over_period_quality_delta",
                "pipeline_revenue_attribution",
                "policy_violation_rate",
                "production_throughput_impact",
                "recurrence_rate_of_known_errors",
                "response_time",
                "response_time_to_lead",
                "revenue_attribution",
                "safety_incident_correlation",
                "task_ai_fit_score",
                "task_success_rate",
                "tenure_in_production",
                "throughput_vs_benchmark",
                "uptime_reliability"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "kpiName": {
                            "type": "string"
                          },
                          "factor": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "value": {
                            "type": "number"
                          },
                          "unit": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "recordedAt": {
                            "type": "string",
                            "format": "date"
                          },
                          "source": {
                            "type": "string"
                          },
                          "ingestedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unknown kpiName filter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in this company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Ingestion"
        ],
        "operationId": "ingestEvents",
        "summary": "Ingest KPI events (validated write path)",
        "description": "THE write path — connectors, CSV import, and direct API calls all land here. Batches are atomic: every row is validated before any row is written; one bad row rejects the whole batch with per-index problems. Duplicate (agent, source, sourceRecordId) tuples are skipped and reported, never double-ingested. Rate KPIs must land in [0, 1] after unit canonicalization.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "$ref": "#/components/parameters/agentId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "events"
                ],
                "properties": {
                  "source": {
                    "type": "string",
                    "default": "api",
                    "description": "Data-source label for idempotency scoping and provenance."
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1000,
                    "items": {
                      "$ref": "#/components/schemas/EventInput"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Batch accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed — `problems` lists every bad row by index. Nothing was written.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found in this company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/raw": {
      "post": {
        "tags": [
          "Raw vault"
        ],
        "operationId": "ingestRaw",
        "summary": "Vault raw upstream records",
        "description": "Append-only and versioned: an unchanged (objectType, objectId, payloadHash) re-sync is skipped; a changed object appends a new version. Payloads land verbatim — re-derivation from history is always possible. 128KB per payload; reference R2 blobs beyond that.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source",
                  "records"
                ],
                "properties": {
                  "source": {
                    "type": "string",
                    "examples": [
                      "hubspot",
                      "jobber",
                      "csv-upload"
                    ]
                  },
                  "records": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 200,
                    "items": {
                      "$ref": "#/components/schemas/RawRecordInput"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Vaulted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed; nothing written.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Raw vault"
        ],
        "operationId": "listRaw",
        "summary": "Read vaulted records",
        "description": "Bulk raw reads are exports and are audited.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "objectType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Vault page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "records": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RawRecord"
                      }
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/integrations": {
      "post": {
        "tags": [
          "Integrations"
        ],
        "operationId": "connectIntegration",
        "summary": "Connect a provider",
        "description": "Live tokens are verified with an upstream ping BEFORE storage, then AES-GCM encrypted at rest — only the last four characters are ever returned again. One active integration per provider per company. Jobber is sandbox-only until its OAuth flow ships. No agent is selected here: syncing DISCOVERS the actors doing the work, and each is classified (AI agent vs human) before anything is scored.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "provider"
                ],
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "hubspot",
                      "jobber"
                    ]
                  },
                  "token": {
                    "type": "string",
                    "description": "Private-app / service-key token. Required for live mode."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "live",
                      "sandbox"
                    ],
                    "default": "live"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Connected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Integration"
                }
              }
            }
          },
          "400": {
            "description": "Invalid provider, foreign agent, or invalid_credentials (one generic envelope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "An active integration for this provider already exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "integration_encryption_unavailable — encryption key not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Integrations"
        ],
        "operationId": "listIntegrations",
        "summary": "List integrations",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "All integrations, ciphertext never included.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "integrations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Integration"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/integrations/{integrationId}/sync": {
      "post": {
        "tags": [
          "Integrations"
        ],
        "operationId": "syncIntegration",
        "summary": "Run a sync",
        "description": "Pulls from the provider (live) or fixtures (sandbox), lands every payload in the raw vault FIRST, then derives KPI events per upstream actor. Every actor lands in the discovery queue; ONLY actors classified as AI agents get events ingested — pending actors' events are held (re-sync after classifying ingests the full history), humans' are excluded permanently. Fully idempotent: unchanged upstream data writes nothing. Failures mark the integration `error` and return one generic envelope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "$ref": "#/components/parameters/integrationId"
          }
        ],
        "responses": {
          "200": {
            "description": "Sync report.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "syncedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "stats": {
                      "$ref": "#/components/schemas/SyncStats"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Integration is revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "upstream_sync_failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "integration_encryption_unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/integrations/{integrationId}": {
      "delete": {
        "tags": [
          "Integrations"
        ],
        "operationId": "revokeIntegration",
        "summary": "Revoke an integration",
        "description": "Revocation is permanent for the row; reconnecting creates a new integration. Already-vaulted data is retained.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "$ref": "#/components/parameters/integrationId"
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/recompute": {
      "post": {
        "tags": [
          "Scoring"
        ],
        "operationId": "recompute",
        "summary": "Recompute scores",
        "description": "Runs the scoring engine (asam model, frozen anchors) over the company's event history. Score records are append-only — every recompute adds a new versioned record; history is never rewritten. Agents below the event floor publish no numeric score (cold start → collecting_data).",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "Scored.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scored": {
                      "type": "integer"
                    },
                    "model": {
                      "type": "string",
                      "examples": [
                        "asam_v2.1"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/scorecard": {
      "get": {
        "tags": [
          "Scoring"
        ],
        "operationId": "companyScorecard",
        "summary": "Company scorecard",
        "description": "Latest ImplementationScore + every agent's latest score, enriched with identity and event counts.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "The scorecard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyScorecard"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/agents/{agentId}/scorecard": {
      "get": {
        "tags": [
          "Scoring"
        ],
        "operationId": "agentScorecard",
        "summary": "Agent scorecard",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "$ref": "#/components/parameters/agentId"
          }
        ],
        "responses": {
          "200": {
            "description": "Latest score + event count.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agent": {
                      "$ref": "#/components/schemas/Agent"
                    },
                    "score": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/ScoreRecord"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "nEvents": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown agent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/actors": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "operationId": "listActors",
        "summary": "List discovered actors",
        "description": "Every upstream actor (HubSpot owner, Jobber assignee) a sync has seen, with classification status. `pending` actors are scored for NOTHING until classified; `human` actors are never scored.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "The discovery queue.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "actors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiscoveredActor"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/actors/{actorId}/classify": {
      "post": {
        "tags": [
          "Integrations"
        ],
        "operationId": "classifyActor",
        "summary": "Classify a discovered actor",
        "description": "kind=agent creates the agent record + source alias (the next idempotent sync ingests the actor's full history). kind=human permanently excludes the actor from scoring — people are never scored. Audited.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "name": "actorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "agent",
                      "human"
                    ]
                  },
                  "name": {
                    "type": "string",
                    "description": "Override the discovered display name."
                  },
                  "agentType": {
                    "type": "string",
                    "description": "What the agent DOES (peer-cell key). Defaults to unclassified."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Classified."
          },
          "400": {
            "description": "Invalid kind.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown actor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Actor is already classified.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/webhooks": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhook",
        "summary": "Register a webhook endpoint",
        "description": "The signing secret (whsec_…) is generated server-side, returned ONCE in this response, and stored encrypted. Verify x-agentscore-signature (HMAC-SHA256 over the exact body) before trusting any delivery. Omitting `events` subscribes to all types.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "score.tier_changed",
                        "governance.cap_applied",
                        "score.dropped"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — save the secret now.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Webhook"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "secret": {
                          "type": "string",
                          "description": "Shown exactly once."
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or unknown event type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "integration_encryption_unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhooks",
        "summary": "List webhooks",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          }
        ],
        "responses": {
          "200": {
            "description": "All webhooks — secrets never included.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/webhooks/{webhookId}/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "webhookDeliveries",
        "summary": "Delivery log",
        "description": "Append-only record of every delivery attempt — 'did the webhook fire' is never a mystery.",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Attempts, newest first."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}/webhooks/{webhookId}": {
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "disableWebhook",
        "summary": "Disable a webhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/companyId"
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Disabled."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/keys": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "mintKey",
        "summary": "Mint an API key",
        "description": "The plaintext key appears ONCE in this response and is stored only as a SHA-256 hash.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "scopes"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "read",
                        "write",
                        "admin"
                      ]
                    }
                  },
                  "companyId": {
                    "type": "string",
                    "description": "Bind the key to one company. Omit for platform keys."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Minted — save the key now.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "key": {
                      "type": "string",
                      "description": "Shown exactly once."
                    },
                    "name": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "companyId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "listKeys",
        "summary": "List keys (hashes never included)",
        "responses": {
          "200": {
            "description": "All keys' metadata."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/keys/{keyId}": {
      "delete": {
        "tags": [
          "Admin"
        ],
        "operationId": "revokeKey",
        "summary": "Revoke a key",
        "description": "Revocation fails closed: a revoked key is indistinguishable from an unknown one.",
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/audit": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "audit",
        "summary": "Read the audit trail",
        "description": "Append-only: who did what, when, to which resource — every auth denial, mutation, connect/revoke, and export. Request-id correlated. No PII.",
        "responses": {
          "200": {
            "description": "Audit rows, newest first."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/companies": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminCompanies",
        "summary": "List all companies",
        "responses": {
          "200": {
            "description": "Every company, including soft-deleted."
          },
          "401": {
            "description": "Missing, malformed, unknown, or revoked API key — one uniform envelope, no oracle.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key is valid but lacks the required scope or is bound to a different company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "scoreEvent": {
      "post": {
        "summary": "Score event delivery",
        "description": "Sent on recompute when an agent's tier changes, a governance cap is applied, or a score drops by 50+ points. Headers: x-agentscore-signature (sha256=<hex>, HMAC-SHA256 of the exact body with your whsec_ secret), x-agentscore-event (type), x-agentscore-delivery (attempt id). Dedupe on body `id` — delivery attempts are recorded and visible via the deliveries endpoint. Respond 2xx to acknowledge.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id — dedupe key."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "score.tier_changed",
                      "governance.cap_applied",
                      "score.dropped"
                    ]
                  },
                  "companyId": {
                    "type": "string"
                  },
                  "agentId": {
                    "type": "string"
                  },
                  "agentName": {
                    "type": "string"
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "description": "Type-specific: from/to tiers, scores, drop size."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Per-company API key (`ask_…`). Scopes: read, write, admin. Hashed at rest; company binding enforced centrally."
      }
    },
    "parameters": {
      "companyId": {
        "name": "companyId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "agentId": {
        "name": "agentId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "integrationId": {
        "name": "integrationId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "requestId": {
            "type": "string",
            "description": "Correlates with the audit trail and the x-request-id header."
          },
          "problems": {
            "type": "array",
            "description": "Present on validation_failed: every bad row by index.",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "error": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Company": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "vertical": {
            "type": "string"
          },
          "sector": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "deletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Agent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "agentType": {
            "type": "string"
          },
          "industry": {
            "type": "string"
          },
          "vendor": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EventInput": {
        "type": "object",
        "required": [
          "kpiName",
          "value",
          "unit",
          "recordedAt"
        ],
        "properties": {
          "kpiName": {
            "type": "string",
            "enum": [
              "audit_failure_count",
              "cost_per_unit_impact",
              "customer_engagement_quality",
              "customer_satisfaction",
              "data_volume_confidence",
              "defect_detection_accuracy",
              "downtime_reduction",
              "explainability_completeness",
              "feedback_ingestion_lag_days",
              "human_override_rate",
              "integration_depth_score",
              "lead_conversion_rate",
              "meeting_book_rate",
              "period_over_period_quality_delta",
              "pipeline_revenue_attribution",
              "policy_violation_rate",
              "production_throughput_impact",
              "recurrence_rate_of_known_errors",
              "response_time",
              "response_time_to_lead",
              "revenue_attribution",
              "safety_incident_correlation",
              "task_ai_fit_score",
              "task_success_rate",
              "tenure_in_production",
              "throughput_vs_benchmark",
              "uptime_reliability"
            ],
            "description": "Must exist in the KPI registry — unknown names reject the batch."
          },
          "value": {
            "type": "number"
          },
          "unit": {
            "type": "string",
            "description": "REQUIRED. Canonicalized at write time. Accepted per canonical unit: %: [fraction, %, percent, pct, bps]; s: [s, sec, seconds, ms, milliseconds, min, minutes, h, hours]; $: [$, usd, dollars, cents]; x: [x, ratio, multiple]; days: [days, day, hours, weeks]; count: [count, n]; score: [score]; ratio: [ratio, x]; delta_z: [delta_z]."
          },
          "recordedAt": {
            "type": "string",
            "format": "date",
            "description": "Real calendar date (round-trip checked). Scoring buckets by month."
          },
          "sourceRecordId": {
            "type": "string",
            "description": "Idempotency key within (agent, source). Strongly recommended."
          }
        }
      },
      "IngestResult": {
        "type": "object",
        "properties": {
          "written": {
            "type": "integer"
          },
          "skipped": {
            "type": "integer",
            "description": "Idempotent duplicates (events) or unchanged versions (raw)."
          }
        }
      },
      "RawRecordInput": {
        "type": "object",
        "required": [
          "objectType",
          "objectId",
          "payload"
        ],
        "properties": {
          "objectType": {
            "type": "string",
            "examples": [
              "deal",
              "ticket",
              "invoice"
            ]
          },
          "objectId": {
            "type": "string",
            "description": "Upstream identifier."
          },
          "agentId": {
            "type": "string"
          },
          "fetchedAt": {
            "type": "string",
            "format": "date-time"
          },
          "payload": {
            "description": "The COMPLETE upstream object, verbatim. ≤128KB."
          }
        }
      },
      "RawRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "agentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": "string"
          },
          "objectType": {
            "type": "string"
          },
          "objectId": {
            "type": "string"
          },
          "payload": {},
          "payloadHash": {
            "type": "string",
            "description": "SHA-256 — the version discriminator."
          },
          "fetchedAt": {
            "type": "string",
            "format": "date-time"
          },
          "ingestedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DiscoveredActor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "externalId": {
            "type": "string",
            "description": "Upstream actor id."
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "agent",
              "human"
            ]
          },
          "agentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "eventsSeen": {
            "type": "integer",
            "description": "KPI events derivable for this actor per sync."
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "classifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Integration": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "enum": [
              "hubspot",
              "jobber"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ]
          },
          "credentialTail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last 4 characters of the token — all that is ever shown."
          },
          "status": {
            "type": "string",
            "enum": [
              "connected",
              "revoked",
              "error"
            ]
          },
          "lastSyncAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastSyncStats": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SyncStats"
              },
              {
                "type": "null"
              }
            ]
          },
          "eventsContributed": {
            "type": "integer",
            "description": "KPI events this source has contributed company-wide (list responses only). Connected ≠ contributing — an empty upstream reads 0 here."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "SyncStats": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "objects": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Objects pulled, by type."
          },
          "raw": {
            "$ref": "#/components/schemas/IngestResult"
          },
          "events": {
            "$ref": "#/components/schemas/IngestResult"
          },
          "actorsSeen": {
            "type": "integer"
          },
          "actorsPending": {
            "type": "integer",
            "description": "Actors awaiting human/AI classification."
          },
          "eventsHeld": {
            "type": "integer",
            "description": "Events held pending classification — not lost."
          },
          "eventsExcludedHuman": {
            "type": "integer",
            "description": "Events belonging to humans — never scored."
          },
          "matchRate": {
            "type": [
              "number",
              "null"
            ],
            "description": "Fraction of pulled objects attributable to the agent. Surfaced, never silent."
          },
          "kpiCounts": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "unavailable": {
            "type": "array",
            "description": "KPIs that could not be derived, each with the reason.",
            "items": {
              "type": "object",
              "properties": {
                "kpi": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          },
          "truncated": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Object types that hit the page cap this sync."
          },
          "derivationProblems": {
            "type": "integer"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "secretTail": {
            "type": "string",
            "description": "Last 4 characters of the signing secret."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "disabledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ScoreRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "agentScore": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000,
            "description": "Null while cold-starting (below the event floor)."
          },
          "tier": {
            "type": "string",
            "enum": [
              "prime",
              "near_prime",
              "subprime",
              "deep_subprime",
              "collecting_data"
            ]
          },
          "provisional": {
            "type": "boolean"
          },
          "governanceCapped": {
            "type": "boolean"
          },
          "coldStart": {
            "type": "boolean"
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "factorScores": {
            "type": "object",
            "additionalProperties": {
              "type": [
                "number",
                "null"
              ]
            }
          },
          "scoringModelVersion": {
            "type": "string"
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CompanyScorecard": {
        "type": "object",
        "properties": {
          "company": {
            "$ref": "#/components/schemas/Company"
          },
          "implementation": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "implementationScore": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 100
                  },
                  "tier": {
                    "type": "string"
                  },
                  "coldStart": {
                    "type": "boolean"
                  },
                  "monthsObserved": {
                    "type": "integer"
                  },
                  "factorScores": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "number"
                    }
                  },
                  "scoringModelVersion": {
                    "type": "string"
                  },
                  "computedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "agents": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ScoreRecord"
                },
                {
                  "type": "object",
                  "properties": {
                    "agentName": {
                      "type": "string"
                    },
                    "agentType": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "vendor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "nEvents": {
                      "type": "integer"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}
