{
  "openapi": "3.1.0",
  "info": {
    "title": "Keply Ingest API",
    "version": "1.0.0",
    "description": "Push accounts, usage, and customer-success signals into Keply from any CRM, billing tool, or product. Authenticated by a per-organization Keply API key (starts with kep_), the same key that authenticates the Keply MCP server. Mint it in Settings, Connections. Full docs: https://keply.ai/agents/",
    "contact": { "name": "Keply", "email": "ori@keply.ai", "url": "https://keply.ai/agents/" }
  },
  "servers": [
    { "url": "https://kzqlzstchvmuenukcejb.supabase.co/functions/v1", "description": "Production" }
  ],
  "security": [{ "keplyApiKey": [] }],
  "paths": {
    "/ingest": {
      "post": {
        "operationId": "ingestEvents",
        "summary": "Ingest a batch of account, usage, and signal events",
        "description": "Routes each event into the same pipeline the agent scores from. Accounts are created by domain on the fly; generic mail domains (gmail.com, etc.) are rejected. Every touched account is re-scored inline.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/IngestBatch" },
              "examples": {
                "mixed": {
                  "summary": "Account, usage, and signal in one batch",
                  "value": {
                    "events": [
                      { "type": "account", "accountDomain": "acme.com", "arrCents": 1200000, "renewalDate": "2026-01-31", "seatsContracted": 25, "plan": "enterprise", "contacts": [{ "name": "Dana Lee", "email": "dana@acme.com", "title": "CFO" }] },
                      { "type": "usage", "accountDomain": "acme.com", "event": "weekly_active", "trend": -0.4 },
                      { "type": "signal", "accountDomain": "acme.com", "signalType": "ticket", "summary": "P1 outage", "sentiment": -0.6 }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch processed. Per-event failures are returned in errors without failing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean" },
                    "ingested": { "type": "integer", "description": "Events accepted." },
                    "errors": { "type": "array", "items": { "type": "string" } },
                    "rescored": { "type": "integer", "description": "Distinct accounts re-scored." }
                  }
                }
              }
            }
          },
          "401": { "description": "Invalid or missing API key." }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "keplyApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Per-organization Keply API key, format: Bearer kep_…"
      }
    },
    "schemas": {
      "IngestBatch": {
        "type": "object",
        "required": ["events"],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "oneOf": [
                { "$ref": "#/components/schemas/AccountEvent" },
                { "$ref": "#/components/schemas/UsageEvent" },
                { "$ref": "#/components/schemas/SignalEvent" }
              ]
            }
          }
        }
      },
      "AccountEvent": {
        "type": "object",
        "required": ["type"],
        "description": "Create or update an account and its commercial truth. Matched by accountId, accountDomain, or accountName. Hand-set fields are never overwritten.",
        "properties": {
          "type": { "const": "account" },
          "accountId": { "type": "string", "description": "Account UUID (optional)." },
          "accountDomain": { "type": "string", "description": "Company domain, created on the fly if unknown." },
          "accountName": { "type": "string" },
          "arrCents": { "type": "integer", "description": "Annual recurring revenue, in cents." },
          "mrrCents": { "type": "integer", "description": "Monthly recurring revenue, in cents." },
          "renewalDate": { "type": "string", "format": "date", "description": "ISO date, YYYY-MM-DD." },
          "seatsContracted": { "type": "integer" },
          "plan": { "type": "string" },
          "contractAmountCents": { "type": "integer", "description": "Total contract value, in cents." },
          "closeDate": { "type": "string", "format": "date", "description": "Deal close / signature date." },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string" },
                "email": { "type": "string" },
                "title": { "type": "string" },
                "role": { "type": "string", "description": "Inferred from title if omitted." }
              }
            }
          }
        }
      },
      "UsageEvent": {
        "type": "object",
        "required": ["type"],
        "description": "A product-usage data point. Optionally tied to a contact by email or an external user id.",
        "properties": {
          "type": { "const": "usage" },
          "accountId": { "type": "string" },
          "accountDomain": { "type": "string" },
          "accountName": { "type": "string" },
          "event": { "type": "string", "description": "e.g. weekly_active, login, feature_x." },
          "trend": { "type": "number", "description": "Fractional change vs baseline, e.g. -0.4 for down 40%." },
          "value": { "type": "number" },
          "occurredAt": { "type": "string", "format": "date-time" },
          "email": { "type": "string" },
          "userId": { "type": "string" },
          "externalId": { "type": "string" }
        }
      },
      "SignalEvent": {
        "type": "object",
        "required": ["type", "signalType", "summary"],
        "description": "A customer-success signal (ticket, call, NPS, payment, champion change, note).",
        "properties": {
          "type": { "const": "signal" },
          "accountId": { "type": "string" },
          "accountDomain": { "type": "string" },
          "accountName": { "type": "string" },
          "signalType": { "type": "string", "description": "e.g. ticket, call, nps, payment, champion_left, note." },
          "summary": { "type": "string" },
          "sentiment": { "type": "number", "minimum": -1, "maximum": 1 },
          "value": { "type": "number" },
          "occurredAt": { "type": "string", "format": "date-time" }
        }
      }
    }
  }
}
