{
 "openapi": "3.1.0",
 "info": {
  "title": "Account Intel API",
  "version": "1.2.0",
  "description": "Account research, evidence-gated buying signals, buying centers, outreach drafts, market analyses, plans (the fit check, outreach and call prep), company lists, ICP screening, plays and the workspace's positioning over REST. Keys are created in the app under Settings \u2192 API & MCP. A signal only exists in a response if it passed the evidence gate (quote + source + date). Nothing spends more than $0.05 without confirm:true: such calls answer 402 with an itemized estimate and spent: 0. Every call that can spend also accepts dryRun:true, which returns the estimate (200) and spends nothing. Long work (research, analyses, plans, plays, screens over 20 rows) runs as a job: it answers 202 with a job id (job_...), is polled, can be stopped with POST /jobs/{id}/stop, and shows in the app's Activity. Jobs are capped per workspace (fit checks 3, research 4, analyses 6, plays 2, qualify screens 2); past a cap a job is queued, not refused. The same operations are available as MCP tools (streamable HTTP) at https://app.aiseoworkflows.com/mcp with the same Bearer key; see https://aiseoworkflows.com/developers.html#mcp."
 },
 "servers": [
  {
   "url": "https://app.aiseoworkflows.com/api/v1"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "ai_live_\u2026"
   }
  },
  "schemas": {
   "AccountSummary": {
    "type": "object",
    "properties": {
     "slug": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "domain": {
      "type": "string"
     },
     "segment": {
      "type": "string"
     },
     "verdict": {
      "$ref": "#/components/schemas/Verdict"
     },
     "flags": {
      "$ref": "#/components/schemas/Flags"
     },
     "researchedAt": {
      "type": "string",
      "format": "date-time"
     },
     "status": {
      "type": "string",
      "enum": [
       "ready",
       "refreshing"
      ]
     }
    }
   },
   "Verdict": {
    "type": "object",
    "properties": {
     "label": {
      "type": "string"
     },
     "reason": {
      "type": "string"
     }
    }
   },
   "Signal": {
    "type": "object",
    "properties": {
     "headline": {
      "type": "string"
     },
     "strength": {
      "type": "string",
      "enum": [
       "strong",
       "moderate",
       "weak"
      ]
     },
     "quote": {
      "type": "string"
     },
     "source_id": {
      "type": "string"
     },
     "source_url": {
      "type": "string"
     },
     "date": {
      "type": "string"
     },
     "person": {
      "type": [
       "string",
       "null"
      ]
     },
     "maps_to": {
      "type": "string"
     },
     "how_to_use": {
      "type": "string"
     }
    }
   },
   "Person": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "role": {
      "type": "string"
     },
     "confidence": {
      "type": "string"
     },
     "why": {
      "type": "string"
     },
     "profile_url": {
      "type": [
       "string",
       "null"
      ]
     },
     "email": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Message": {
    "type": "object",
    "properties": {
     "contact": {
      "type": "string"
     },
     "call_opener": {
      "type": "string"
     },
     "email": {
      "type": "object",
      "properties": {
       "subject": {
        "type": "string"
       },
       "body": {
        "type": "string"
       }
      }
     },
     "followup": {
      "type": "string"
     },
     "linkedin_note": {
      "type": "string"
     },
     "linkedin_dm": {
      "type": "string"
     },
     "signal_used": {
      "type": [
       "string",
       "null"
      ]
     },
     "proof_used": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Source": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "kind": {
      "type": "string"
     },
     "date": {
      "type": [
       "string",
       "null"
      ]
     },
     "excerpt": {
      "type": "string"
     }
    }
   },
   "Brief": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string"
     },
     "account": {
      "type": "object"
     },
     "verdict": {
      "$ref": "#/components/schemas/Verdict"
     },
     "flags": {
      "$ref": "#/components/schemas/Flags"
     },
     "researchedAt": {
      "type": "string"
     },
     "research": {
      "type": "object"
     },
     "people": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Person"
      }
     },
     "signals": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Signal"
      }
     },
     "rejectedSignals": {
      "type": "array"
     },
     "messages": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Message"
      }
     },
     "sources": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Source"
      }
     }
    }
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string"
     }
    }
   },
   "EstimateLine": {
    "type": "object",
    "properties": {
     "label": {
      "type": "string"
     },
     "usd": {
      "type": "number"
     },
     "step": {
      "type": "string"
     }
    }
   },
   "Estimate": {
    "type": "object",
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/EstimateLine"
      }
     },
     "totalUsd": {
      "type": "number"
     }
    }
   },
   "NeedsConfirm": {
    "type": "object",
    "description": "Nothing was spent. Repeat the call with confirm: true after the spend is approved.",
    "properties": {
     "error": {
      "type": "string"
     },
     "needsConfirm": {
      "type": "boolean",
      "const": true
     },
     "spent": {
      "type": "number",
      "const": 0
     },
     "estimate": {
      "$ref": "#/components/schemas/Estimate"
     }
    }
   },
   "DryRun": {
    "type": "object",
    "properties": {
     "dryRun": {
      "type": "boolean",
      "const": true
     },
     "spent": {
      "type": "number",
      "const": 0
     },
     "estimate": {
      "$ref": "#/components/schemas/Estimate"
     }
    }
   },
   "Job": {
    "type": "object",
    "description": "A background job. Statuses: queued (waiting for a free slot; position is its place in line), running, done, failed, stopped (nothing else runs or spends; what finished is kept), stalled (no update for 12 minutes).",
    "properties": {
     "id": {
      "type": "string",
      "pattern": "^job_[a-z0-9]{8,40}$"
     },
     "kind": {
      "type": "string",
      "enum": [
       "research",
       "analysis",
       "plan",
       "batch",
       "play",
       "qualify"
      ]
     },
     "status": {
      "type": "string",
      "enum": [
       "queued",
       "running",
       "done",
       "failed",
       "stopped",
       "stalled"
      ]
     },
     "position": {
      "type": "integer",
      "description": "Place in the queue while queued"
     },
     "title": {
      "type": "string"
     },
     "step": {
      "type": "integer"
     },
     "steps": {
      "type": "integer"
     },
     "current": {
      "type": [
       "string",
       "null"
      ],
      "description": "The stage running now"
     },
     "stages": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string"
        },
        "status": {
         "type": "string"
        },
        "label": {
         "type": "string"
        }
       }
      }
     },
     "costUsd": {
      "type": [
       "number",
       "null"
      ]
     },
     "summary": {
      "type": [
       "string",
       "null"
      ]
     },
     "input": {
      "type": [
       "object",
       "null"
      ]
     },
     "progress": {
      "type": "object"
     },
     "result": {
      "type": [
       "object",
       "null"
      ],
      "description": "Plays and qualify screens; research, analyses and plans save their output on the account"
     },
     "error": {
      "type": [
       "string",
       "null"
      ]
     },
     "startedAt": {
      "type": "string"
     },
     "finishedAt": {
      "type": [
       "string",
       "null"
      ]
     },
     "endedAt": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Accepted": {
    "type": "object",
    "properties": {
     "job": {
      "type": "string",
      "description": "Job id (job_...): poll GET /jobs/{id}, stop POST /jobs/{id}/stop"
     },
     "slug": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "enum": [
       "running",
       "queued"
      ]
     },
     "poll": {
      "type": "string"
     },
     "estimatedUsd": {
      "type": "number"
     }
    }
   },
   "List": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "createdAt": {
      "type": "string"
     },
     "domains": {
      "type": "array",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "ScreenResult": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "verdict": {
      "type": "string",
      "enum": [
       "fit",
       "maybe",
       "not_a_fit",
       "customer"
      ]
     },
     "flags": {
      "$ref": "#/components/schemas/Flags"
     },
     "reason": {
      "type": "string"
     },
     "lookalike": {
      "type": [
       "string",
       "null"
      ]
     },
     "cached": {
      "type": "boolean"
     }
    }
   },
   "Costs": {
    "type": "object",
    "properties": {
     "totalUsd": {
      "type": "number"
     },
     "calls": {
      "type": "integer"
     },
     "byStage": {
      "type": "object",
      "additionalProperties": {
       "type": "object",
       "properties": {
        "usd": {
         "type": "number"
        },
        "calls": {
         "type": "integer"
        }
       }
      }
     },
     "unpricedCalls": {
      "type": "integer"
     }
    }
   },
   "Flags": {
    "type": "object",
    "nullable": true,
    "description": "Advisory flags. competesWith: the account competes with one of your customers (still a target; outreach never names that customer). sizeNote: larger than your core band.",
    "properties": {
     "competesWith": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "customer": {
         "type": "string"
        },
        "domain": {
         "type": "string"
        },
        "why": {
         "type": "string"
        },
        "by": {
         "type": "string",
         "enum": [
          "list",
          "model"
         ]
        }
       }
      }
     },
     "sizeNote": {
      "type": "string",
      "nullable": true
     }
    }
   },
   "PlanRequest": {
    "type": "object",
    "required": [
     "plan"
    ],
    "description": "Pass one target: slug, domains or listId.",
    "properties": {
     "plan": {
      "type": "string",
      "enum": [
       "fit",
       "outreach",
       "call"
      ]
     },
     "slug": {
      "type": "string",
      "description": "One account (slug or domain)"
     },
     "domains": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "maxItems": 300,
      "description": "Up to 300 for fit; outreach runs on up to 50 the fit check passed; call on one account"
     },
     "listId": {
      "type": "string",
      "description": "A list id (alias: list)"
     },
     "then": {
      "type": "string",
      "enum": [
       "outreach"
      ],
      "description": "With fit on several companies: then prepare outreach for the top 20 by fit score, priced in the same quote"
     },
     "top": {
      "type": "integer",
      "maximum": 20,
      "description": "With then: outreach for fewer than 20"
     },
     "continue": {
      "type": "boolean",
      "description": "Resume past a stop on this account (only when the user chose to)"
     },
     "include": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "ai_visibility"
       ]
      },
      "description": "call only: tick in AI visibility"
     },
     "force": {
      "type": "boolean",
      "description": "Re-buy steps cached in the last 7 days"
     },
     "confirm": {
      "type": "boolean",
      "description": "Required when the estimate exceeds $0.05"
     },
     "dryRun": {
      "type": "boolean",
      "description": "Return the itemized estimate (200) and spend nothing"
     }
    }
   },
   "PlanAccepted": {
    "type": "object",
    "properties": {
     "plan": {
      "type": "string"
     },
     "job": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "enum": [
       "running",
       "queued"
      ]
     },
     "position": {
      "type": "integer"
     },
     "targets": {
      "type": "integer"
     },
     "estimate": {
      "$ref": "#/components/schemas/Estimate"
     },
     "poll": {
      "type": "object",
      "properties": {
       "job": {
        "type": "string"
       },
       "plan": {
        "type": "string"
       },
       "plans": {
        "type": "string"
       }
      }
     }
    }
   },
   "FitCheck": {
    "type": "object",
    "description": "The fit waterfall: rules, who they are, demand, investment, why now. Only an existing customer, a hard no on who they are, or no search demand stops; already winning parks as Nurture.",
    "properties": {
     "status": {
      "type": "string"
     },
     "outcome": {
      "type": "string",
      "enum": [
       "passed",
       "stopped",
       "parked"
      ]
     },
     "verdict": {
      "type": "string",
      "enum": [
       "fit",
       "nurture",
       "not_a_fit",
       "customer"
      ]
     },
     "score": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 100
     },
     "partial": {
      "type": "boolean",
      "description": "Some score lines could not be checked yet"
     },
     "stoppedAt": {
      "type": [
       "string",
       "null"
      ]
     },
     "reason": {
      "type": [
       "string",
       "null"
      ]
     },
     "stages": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string"
        },
        "label": {
         "type": "string"
        },
        "status": {
         "type": "string",
         "enum": [
          "done",
          "stopped",
          "parked",
          "skipped",
          "pending"
         ]
        },
        "usd": {
         "type": "number"
        },
        "cached": {
         "type": "boolean"
        },
        "gate": {
         "type": [
          "object",
          "null"
         ]
        }
       }
      }
     },
     "spentUsd": {
      "type": "number"
     },
     "overrides": {
      "type": "array",
      "items": {
       "type": "object"
      }
     }
    }
   },
   "PlanState": {
    "type": "object",
    "properties": {
     "slug": {
      "type": "string"
     },
     "domain": {
      "type": [
       "string",
       "null"
      ]
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "live": {
      "type": [
       "object",
       "null"
      ],
      "description": "A run in flight"
     },
     "fit": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/FitCheck"
       },
       {
        "type": "null"
       }
      ]
     },
     "outreach": {
      "type": [
       "object",
       "null"
      ]
     },
     "call": {
      "type": [
       "object",
       "null"
      ]
     }
    }
   }
  }
 },
 "paths": {
  "/accounts": {
   "get": {
    "summary": "List researched accounts",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "accounts": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/AccountSummary"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}": {
   "get": {
    "summary": "The full brief for one account",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The brief, or {status: running} while research is in flight",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Brief"
        }
       }
      }
     },
     "404": {
      "description": "Unknown account",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "delete": {
    "summary": "Delete an account and everything saved with it",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "deleted": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "A run on this account is in flight",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/analyses": {
   "get": {
    "summary": "Every analysis that has run, with data and cost",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/accounts/{slug}/analyses/{analysis}": {
   "get": {
    "summary": "One analysis result with its status (ready, running, not_run, failed)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     },
     {
      "name": "analysis",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "ready",
            "running",
            "not_run",
            "failed"
           ]
          },
          "ranAt": {
           "type": "string"
          },
          "costUsd": {
           "type": "number"
          },
          "data": {
           "type": "object"
          },
          "summary": {
           "type": [
            "string",
            "null"
           ]
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/ask": {
   "post": {
    "summary": "Ask a question about the account, answered from its saved research",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "question": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        },
        "required": [
         "question"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "answer": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/chat": {
   "get": {
    "summary": "The account's stored conversation",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/competitors": {
   "get": {
    "summary": "The account's saved competitors (analysis input)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "competitors": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "put": {
    "summary": "Replace the competitors set (bare domains, up to 10)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "competitors": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        },
        "required": [
         "competitors"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "competitors": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/competitors/suggest": {
   "post": {
    "summary": "Suggest competitors (never saved; PUT what you accept)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "instruction": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/costs": {
   "get": {
    "summary": "What this account has cost, in dollars, by stage",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "allOf": [
          {
           "$ref": "#/components/schemas/Costs"
          },
          {
           "type": "object",
           "properties": {
            "slug": {
             "type": "string"
            },
            "entries": {
             "type": "array",
             "items": {
              "type": "object"
             }
            }
           }
          }
         ]
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/messages": {
   "get": {
    "summary": "Outreach-drafts slice",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/accounts/{slug}/messages/feedback": {
   "post": {
    "summary": "Reject a contact's draft with a reason (read by the next drafts)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "contact": {
          "type": "string"
         },
         "reason": {
          "type": "string"
         }
        },
        "required": [
         "contact",
         "reason"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/messages/revise": {
   "post": {
    "summary": "Rewrite the outreach drafts from an instruction (optionally one contact)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "instruction": {
          "type": "string"
         },
         "contact": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        },
        "required": [
         "instruction"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "summary": {
           "type": "string"
          },
          "messages": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Message"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/people": {
   "get": {
    "summary": "Buying-center slice",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/accounts/{slug}/people/search": {
   "post": {
    "summary": "Find more contacts at the account in the people database",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "contacts": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "502": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/people/{index}/email": {
   "post": {
    "summary": "Look up one buying-center person's validated email",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     },
     {
      "name": "index",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Position in GET /accounts/{slug}/people"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "email": {
           "type": [
            "string",
            "null"
           ]
          },
          "checked": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/prompts": {
   "get": {
    "summary": "The account's saved prompts (analysis input)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "prompts": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "put": {
    "summary": "Replace the prompts set (buyer prompts, up to 25)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "prompts": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        },
        "required": [
         "prompts"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "prompts": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/prompts/suggest": {
   "post": {
    "summary": "Suggest prompts (never saved; PUT what you accept)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "instruction": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/research": {
   "get": {
    "summary": "Fact base slice: account, verdict, bottom line, research, notes",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/signals": {
   "get": {
    "summary": "Signals slice (passed + rejected + every check)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/accounts/{slug}/sources": {
   "get": {
    "summary": "Every source behind the brief (400-character excerpts)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/accounts/{slug}/touches": {
   "get": {
    "summary": "Outreach touches logged on the account",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "summary": "Log an outreach touch (nothing is sent)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, e.g. acme-com"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "contact": {
          "type": "string"
         },
         "channel": {
          "type": "string",
          "description": "email (default), linkedin, call, other"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "touches": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/analyses": {
   "get": {
    "summary": "Analysis definitions and whether each is set up in this workspace",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "analyses": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "id": {
              "type": "string"
             },
             "name": {
              "type": "string"
             },
             "question": {
              "type": "string"
             },
             "detail": {
              "type": "string"
             },
             "setUp": {
              "type": "boolean"
             },
             "needs": {
              "type": "string"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/analyses/estimate": {
   "post": {
    "summary": "Itemized estimate for one analysis (free)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slug": {
          "type": "string"
         },
         "analysis": {
          "type": "string",
          "enum": [
           "market_demand",
           "traffic_history",
           "competitor_landscape",
           "content_velocity",
           "seo_audit",
           "ai_visibility",
           "ads_intel",
           "quick_wins",
           "keyword_gap"
          ]
         },
         "params": {
          "type": "object"
         }
        },
        "required": [
         "slug",
         "analysis"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "spent": {
           "type": "number"
          },
          "needsConfirm": {
           "type": "boolean"
          },
          "estimate": {
           "$ref": "#/components/schemas/Estimate"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/analyses/run": {
   "post": {
    "summary": "Run one analysis on a researched account (async)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "slug",
         "analysis"
        ],
        "properties": {
         "slug": {
          "type": "string"
         },
         "analysis": {
          "type": "string",
          "enum": [
           "market_demand",
           "traffic_history",
           "competitor_landscape",
           "content_velocity",
           "seo_audit",
           "ai_visibility",
           "ads_intel",
           "quick_wins",
           "keyword_gap"
          ]
         },
         "params": {
          "type": "object",
          "description": "e.g. {\"competitors\": [\"a.com\"]} or {\"prompts\": [...]}"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "{slug, analysis, status: running, job, estimatedUsd, poll: /accounts/{slug}/analyses/{analysis}}",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Accepted"
        }
       }
      }
     },
     "400": {
      "description": "Unknown analysis, or the analysis is not set up in this workspace"
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Unknown account; research it first"
     },
     "200": {
      "description": "dryRun: the estimate, nothing spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DryRun"
        }
       }
      }
     }
    }
   }
  },
  "/companies/find": {
   "post": {
    "summary": "Find real companies matching a description, against the workspace ICP",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "description": {
          "type": "string"
         },
         "refine": {
          "type": "string"
         },
         "prior": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        },
        "required": [
         "description"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "companies": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "domain": {
              "type": "string"
             },
             "name": {
              "type": "string"
             },
             "reason": {
              "type": "string"
             },
             "slug": {
              "type": [
               "string",
               "null"
              ]
             },
             "verdict": {
              "type": [
               "string",
               "null"
              ]
             },
             "flags": {
              "$ref": "#/components/schemas/Flags"
             }
            }
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     }
    }
   }
  },
  "/context": {
   "get": {
    "summary": "The workspace's positioning (Context Engine)",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   },
   "patch": {
    "summary": "Update parts of the positioning (previous version kept in history)",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "oneLiner": {
          "type": "string"
         },
         "offerings": {
          "type": "array"
         },
         "claims": {
          "type": "array"
         },
         "stories": {
          "type": "array"
         },
         "segments": {
          "type": "array"
         },
         "why": {
          "type": "array"
         },
         "section": {
          "type": "object"
         },
         "customers": {
          "type": "array",
          "description": "The full customer list (customers.json shape: name, domain, segment, results, competitors, story). Replaces the list; the previous file is kept in history."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/context/suggest": {
   "post": {
    "summary": "Suggest positioning items (never saved)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "what": {
          "type": "string",
          "enum": [
           "why",
           "segments"
          ]
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        },
        "required": [
         "what"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "items": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     }
    }
   }
  },
  "/costs": {
   "get": {
    "summary": "What the workspace has spent, in dollars",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "allOf": [
          {
           "$ref": "#/components/schemas/Costs"
          },
          {
           "type": "object",
           "properties": {
            "accounts": {
             "type": "array",
             "items": {
              "type": "object"
             }
            }
           }
          }
         ]
        }
       }
      }
     }
    }
   }
  },
  "/jobs/{id}": {
   "get": {
    "summary": "Poll a background job (research, analysis, plan, play, qualify screen)",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Job"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/jobs/{id}/stop": {
   "post": {
    "summary": "Stop a job now, with anything it started. Nothing else runs or spends; what finished is kept",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^job_[a-z0-9]{8,40}$"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "{ok, job: {id, kind, status: stopped}, stoppedChildren, note}"
     },
     "404": {
      "description": "Unknown job",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "The job already ended",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/lists": {
   "get": {
    "summary": "Company lists",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "lists": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/List"
           }
          }
         }
        }
       }
      }
     }
    }
   },
   "post": {
    "summary": "Create a list (domains are normalized and deduped, up to 200)",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "domains": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "list": {
           "$ref": "#/components/schemas/List"
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/lists/{id}": {
   "get": {
    "summary": "One list with members joined to their research",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "list": {
           "$ref": "#/components/schemas/List"
          },
          "members": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "domain": {
              "type": "string"
             },
             "slug": {
              "type": [
               "string",
               "null"
              ]
             },
             "verdict": {
              "type": [
               "object",
               "null"
              ]
             },
             "flags": {
              "$ref": "#/components/schemas/Flags"
             }
            }
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "delete": {
    "summary": "Delete a list",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/lists/{id}/members": {
   "post": {
    "summary": "Add domains to a list",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domains": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        },
        "required": [
         "domains"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "list": {
           "$ref": "#/components/schemas/List"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/lists/{id}/members/{domain}": {
   "delete": {
    "summary": "Remove one domain from a list",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/lists/{id}/suggest": {
   "post": {
    "summary": "Propose more real companies like the list's members",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "description": {
          "type": "string"
         },
         "refine": {
          "type": "string"
         },
         "prior": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "candidates": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans": {
   "get": {
    "summary": "The fit row of every company on a list, or of some domains",
    "parameters": [
     {
      "name": "list",
      "in": "query",
      "schema": {
       "type": "string"
      },
      "description": "List id"
     },
     {
      "name": "domains",
      "in": "query",
      "schema": {
       "type": "string"
      },
      "description": "Comma-separated domains (up to 300)"
     },
     {
      "name": "full",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "1"
       ]
      },
      "description": "Return the full state per company"
     }
    ],
    "responses": {
     "200": {
      "description": "{states: {slug: row}}"
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans/estimate": {
   "post": {
    "summary": "Quote a plan (free)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PlanRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "{plan, spent: 0, estimate}"
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans/run": {
   "post": {
    "summary": "Run a plan as a job: fit (the fit waterfall), outreach (fit + brief, drafts, one proof analysis) or call (outreach + the call's analyses)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PlanRequest"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Job started (or queued); poll /plans/{slug} or /jobs/{id}",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PlanAccepted"
        }
       }
      }
     },
     "200": {
      "description": "dryRun: the estimate, nothing spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DryRun"
        }
       }
      }
     },
     "400": {
      "description": "Unknown plan, no target, or a call on more than one account",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true (nothing was spent), or the included research runs are used up (outreach, call)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Unknown list",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "A plan already runs on that account, it is being researched, or none of the companies passed the fit check",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans/{slug}": {
   "get": {
    "summary": "One account's fit check and its outreach and call runs",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, or a domain"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "slug": {
           "type": "string"
          },
          "plans": {
           "$ref": "#/components/schemas/PlanState"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "No plan has run on this account yet",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans/{slug}/continue": {
   "post": {
    "summary": "Continue anyway past a stop (the cost gate applies)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, or a domain"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "plan": {
          "type": "string",
          "enum": [
           "fit",
           "outreach",
           "call"
          ],
          "default": "fit"
         },
         "confirm": {
          "type": "boolean"
         },
         "dryRun": {
          "type": "boolean"
         }
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Job started",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PlanAccepted"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "409": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plans/{slug}/mark": {
   "post": {
    "summary": "Mark as fit: overrides a stop or a park, so outreach can run",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account slug, or a domain"
     }
    ],
    "responses": {
     "200": {
      "description": "{ok, fit}"
     },
     "404": {
      "description": "No finished fit check to mark",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays": {
   "get": {
    "summary": "The packaged plays",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "plays": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "customers": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}": {
   "get": {
    "summary": "One play with its recent runs",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}/angle": {
   "post": {
    "summary": "Step 4 only: write the play's opening line for one researched account",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slug": {
          "type": "string"
         },
         "input": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        },
        "required": [
         "slug"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "line": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}/estimate": {
   "post": {
    "summary": "Itemized estimate for the whole play (free)",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "estimate": {
           "$ref": "#/components/schemas/Estimate"
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}/run": {
   "post": {
    "summary": "Run the whole play as a job: source, screen, list, research the top fits, openers",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "input": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "dryRun",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DryRun"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "202": {
      "description": "Job started; poll /jobs/{id}",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Accepted"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}/runs": {
   "get": {
    "summary": "A play's run history (last 5)",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "runs": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/plays/{id}/source": {
   "post": {
    "summary": "Step 1 only: where the play's companies come from",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "input": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "companies": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "note": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "404": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/qualify": {
   "post": {
    "summary": "Screen up to 300 companies against the ICP (over 20 rows: async job)",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "rows": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "domain": {
             "type": "string"
            },
            "name": {
             "type": "string"
            },
            "extra": {
             "type": "string"
            }
           }
          }
         },
         "domains": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "csv": {
          "type": "string",
          "description": "CSV text with a header row"
         },
         "domainColumn": {
          "type": "string"
         },
         "nameColumn": {
          "type": "string"
         },
         "confirm": {
          "type": "boolean",
          "description": "Required when the estimate exceeds $0.05"
         },
         "dryRun": {
          "type": "boolean",
          "description": "Return the itemized estimate (200) and spend nothing"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "results": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/ScreenResult"
           }
          },
          "counts": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Needs confirm: true; nothing was spent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NeedsConfirm"
        }
       }
      }
     },
     "202": {
      "description": "Large screen started as a job; poll /jobs/{id}",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Accepted"
        }
       }
      }
     }
    }
   }
  },
  "/qualify/estimate": {
   "post": {
    "summary": "Estimate an ICP fit screen (free)",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "rows": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "domain": {
             "type": "string"
            },
            "name": {
             "type": "string"
            },
            "extra": {
             "type": "string"
            }
           }
          }
         },
         "domains": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "csv": {
          "type": "string",
          "description": "CSV text with a header row"
         },
         "domainColumn": {
          "type": "string"
         },
         "nameColumn": {
          "type": "string"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "estimate": {
           "$ref": "#/components/schemas/Estimate"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/research": {
   "post": {
    "summary": "Research a company (async, ~3 minutes)",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "company"
        ],
        "properties": {
         "company": {
          "type": "string",
          "description": "Domain or company name (alias: domain)"
         },
         "force": {
          "type": "boolean",
          "description": "Re-run even when a brief younger than 7 days exists"
         }
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "{slug, status: running, job, poll, note}: a job, stoppable with POST /jobs/{id}/stop",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Accepted"
        }
       }
      }
     },
     "200": {
      "description": "A fresh brief already existed; returned inline"
     },
     "402": {
      "description": "Included runs used up; add a model key in the app"
     },
     "409": {
      "description": "Ambiguous name (candidates listed), or the company is already being researched"
     }
    }
   }
  },
  "/research/estimate": {
   "get": {
    "summary": "What one research run costs in this workspace",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "perRunUsd": {
           "type": "number"
          },
          "note": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/signals": {
   "get": {
    "summary": "Built-in signals, the signal library, and this workspace's selection",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "builtin": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "catalog": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "config": {
           "type": "object",
           "properties": {
            "builtin": {
             "type": "array",
             "items": {
              "type": "string"
             }
            },
            "library": {
             "type": "array",
             "items": {
              "type": "string"
             }
            }
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/signals/config": {
   "put": {
    "summary": "Change the signal selection (a key you leave out keeps its value)",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "builtin": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "library": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/workspace": {
   "get": {
    "summary": "The workspace, its capabilities and the key's limits",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  }
 }
}