{
  "openapi": "3.1.0",
  "info": {
    "title": "ProspectAPIs",
    "summary": "Funding signals and cited prospect research over one REST API.",
    "description": "The REST contract for ProspectAPIs: funding rounds you can filter and page, cited prospect research briefs, and funding watchlists that push new matches to a webhook. Built for sales teams and the AI agents that work for them.\n\nAuthentication is a bearer API key (`Authorization: Bearer pa_live_<48 hex>`), created in the dashboard. `GET /pricing`, `GET /health` and `GET /v1/version` need no key.\n\nBilling is per returned record: `GET /v1/funding` costs per record after a monthly free allowance, a no-match is free, and every response carries `X-Credits-Remaining` and `X-Free-Records-Remaining`. The live price list is `GET /pricing`; a key's balance is `GET /v1/account`. This document describes shapes, not prices.",
    "version": "0.1.0",
    "contact": {
      "name": "ProspectAPIs",
      "url": "https://prospectapis.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://prospectapis.com/terms"
    },
    "termsOfService": "https://prospectapis.com/terms"
  },
  "externalDocs": {
    "description": "API reference and quickstart",
    "url": "https://prospectapis.com/docs"
  },
  "servers": [
    {
      "url": "https://api.prospectapis.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Funding",
      "description": "Search and read funding rounds."
    },
    {
      "name": "Research",
      "description": "Start and poll cited prospect research briefs."
    },
    {
      "name": "Watchlists",
      "description": "Saved funding filters that push new matches to a webhook."
    },
    {
      "name": "Account",
      "description": "Your balance, feedback and the API version."
    },
    {
      "name": "Meta",
      "description": "Keyless endpoints: the price list and liveness."
    }
  ],
  "paths": {
    "/v1/funding": {
      "get": {
        "tags": [
          "Funding"
        ],
        "summary": "Search funding rounds",
        "description": "Keyset-paginated funding rounds, newest first. Costs one record per record returned, after the monthly free allowance; a search that matches nothing is free. Pass `next_cursor` back as `cursor` for the next page. If the balance ends a page early the response carries `X-Result-Capped: balance` and `next_cursor` still continues exactly after the last record served.",
        "operationId": "searchFunding",
        "parameters": [
          {
            "$ref": "#/components/parameters/since"
          },
          {
            "$ref": "#/components/parameters/until"
          },
          {
            "$ref": "#/components/parameters/round"
          },
          {
            "$ref": "#/components/parameters/min_amount_usd"
          },
          {
            "$ref": "#/components/parameters/max_amount_usd"
          },
          {
            "$ref": "#/components/parameters/company"
          },
          {
            "$ref": "#/components/parameters/domain"
          },
          {
            "$ref": "#/components/parameters/investor"
          },
          {
            "$ref": "#/components/parameters/country"
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "$ref": "#/components/parameters/cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of funding rounds.",
            "headers": {
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/X-Credits-Remaining"
              },
              "X-Free-Records-Remaining": {
                "$ref": "#/components/headers/X-Free-Records-Remaining"
              },
              "X-Result-Capped": {
                "description": "Present and set to `balance` when the page was shortened to what the balance pays for. The data has more rows; pass `next_cursor` to continue.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "balance"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FundingList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/funding/{id}": {
      "get": {
        "tags": [
          "Funding"
        ],
        "summary": "Read one funding round",
        "description": "One funding round by id. Costs one record when found; a 404 is free.",
        "operationId": "getFunding",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "The funding round.",
            "headers": {
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/X-Credits-Remaining"
              },
              "X-Free-Records-Remaining": {
                "$ref": "#/components/headers/X-Free-Records-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FundingRecord"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/research": {
      "post": {
        "tags": [
          "Research"
        ],
        "summary": "Start a research brief",
        "description": "Start a cited research brief on one prospect. Accepts exactly one identifier (`domain`, `website_url`, `company_name`, `company_linkedin_url`, a work `email` or `linkedin_url`), or `person_name` with `company_name`. Returns `202` with a `research_id` at once; poll `GET /v1/research/{id}` until `status` is `completed` or `failed`. Charged at the research price only when the brief completes, and refunded if it fails. Answers `503` while research is not priced.",
        "operationId": "submitResearch",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResearchRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The brief was accepted and is running.",
            "headers": {
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/X-Credits-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResearchAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ResearchNotPriced"
          }
        }
      }
    },
    "/v1/research/{id}": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Poll a research brief",
        "description": "One research job, for its owner only (another account's id reads as not found). Free. Poll until `status` is `completed` (the brief is in `result`) or `failed` (the reason is in `error`, and the charge was refunded).",
        "operationId": "getResearch",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "The research job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResearchJob"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/watchlists": {
      "post": {
        "tags": [
          "Watchlists"
        ],
        "summary": "Create a watchlist",
        "description": "Save a set of funding filters plus an https webhook. New matches are pushed as signed `funding_event.matched` events. Free to create; each delivered record costs one record, charged only when your webhook answers 2xx. The signing `secret` is in this response and nowhere else. At most 20 active watchlists per account.",
        "operationId": "createWatchlist",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WatchlistRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The watchlist, including its signing secret (shown only here).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WatchlistWithSecret"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/WatchlistLimit"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "tags": [
          "Watchlists"
        ],
        "summary": "List watchlists",
        "description": "This account's watchlists, newest first, without their signing secrets. Free.",
        "operationId": "listWatchlists",
        "responses": {
          "200": {
            "description": "The account's watchlists.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Watchlist"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/watchlists/{id}": {
      "get": {
        "tags": [
          "Watchlists"
        ],
        "summary": "Read a watchlist",
        "description": "One watchlist, without its signing secret. Free.",
        "operationId": "getWatchlist",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "The watchlist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Watchlist"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "tags": [
          "Watchlists"
        ],
        "summary": "Delete a watchlist",
        "description": "Delete a watchlist and its delivery history. Free.",
        "operationId": "deleteWatchlist",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted"
                  ],
                  "properties": {
                    "deleted": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/watchlists/{id}/test": {
      "post": {
        "tags": [
          "Watchlists"
        ],
        "summary": "Send a test delivery",
        "description": "Send a signed sample `funding_event.matched` event (with `test: true`) to the watchlist's webhook now, so the receiver can be built and verified. Free. At most 5 a minute per account.",
        "operationId": "testWatchlist",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "The outcome of the test delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WatchlistTestResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/watchlists/{id}/deliveries": {
      "get": {
        "tags": [
          "Watchlists"
        ],
        "summary": "List recent deliveries",
        "description": "The last 50 deliveries for a watchlist and their outcome. Free.",
        "operationId": "listWatchlistDeliveries",
        "parameters": [
          {
            "$ref": "#/components/parameters/id"
          }
        ],
        "responses": {
          "200": {
            "description": "Recent deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Delivery"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Account balance",
        "description": "The calling key's balance, this month's free records left and the current prices. Free, so an agent can check before a costed run instead of discovering the balance through a 402.",
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "The account's balance and prices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/feedback": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Send feedback",
        "description": "Report a bug, a wrong or empty field, or a missing capability to the team. Free; at most 10 an hour per account.",
        "operationId": "sendFeedback",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeedbackRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The report was sent to the team.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/FeedbackUndelivered"
          },
          "503": {
            "$ref": "#/components/responses/FeedbackUnavailable"
          }
        }
      }
    },
    "/v1/version": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "API version",
        "description": "The API version and the deployed git sha. Free, no key.",
        "operationId": "getVersion",
        "security": [],
        "responses": {
          "200": {
            "description": "The API version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Version"
                }
              }
            }
          }
        }
      }
    },
    "/pricing": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "Live price list",
        "description": "The live price list the whole product renders from, so no page can advertise a price the API is not charging. Free, no key.",
        "operationId": "getPricing",
        "security": [],
        "responses": {
          "200": {
            "description": "The current prices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pricing"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "Liveness",
        "description": "Liveness for uptime monitors. Never fails on the database. Free, no key.",
        "operationId": "getHealth",
        "security": [],
        "responses": {
          "200": {
            "description": "The service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "funding_event.matched": {
      "post": {
        "summary": "A funding round matched a watchlist",
        "description": "Posted to a watchlist's `webhook_url` when a new funding round matches its filters. Signed with `Prospect-Signature: t=<unix>,v1=<hex>`, an HMAC-SHA256 of `\"<t>.<body>\"` keyed with the watchlist's signing secret. Deduplicate on `Prospect-Delivery-Id`. Answer 2xx to accept it (that is what costs one record); a non-2xx is retried.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The event was accepted."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key as a bearer token: `Authorization: Bearer pa_live_<48 hex>`. Create and manage keys in the dashboard at https://prospectapis.com."
      }
    },
    "parameters": {
      "id": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "A UUID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "3f6c1d2e-8b4a-4f7e-9c21-5a0d7e9b4c13"
      },
      "since": {
        "name": "since",
        "in": "query",
        "description": "Only rounds announced on or after this date (inclusive), YYYY-MM-DD.",
        "schema": {
          "type": "string",
          "format": "date"
        },
        "example": "2026-10-01"
      },
      "until": {
        "name": "until",
        "in": "query",
        "description": "Only rounds announced on or before this date (inclusive), YYYY-MM-DD.",
        "schema": {
          "type": "string",
          "format": "date"
        }
      },
      "round": {
        "name": "round",
        "in": "query",
        "description": "One or more round stages, comma-separated (1 to 20), such as `seed,series_a`.",
        "schema": {
          "type": "string"
        },
        "example": "seed,series_a"
      },
      "min_amount_usd": {
        "name": "min_amount_usd",
        "in": "query",
        "description": "Only rounds of at least this USD amount.",
        "schema": {
          "type": "number",
          "minimum": 0
        }
      },
      "max_amount_usd": {
        "name": "max_amount_usd",
        "in": "query",
        "description": "Only rounds of at most this USD amount.",
        "schema": {
          "type": "number",
          "minimum": 0
        }
      },
      "company": {
        "name": "company",
        "in": "query",
        "description": "Case-insensitive substring match on the company name (1 to 100 characters).",
        "schema": {
          "type": "string",
          "maxLength": 100
        }
      },
      "domain": {
        "name": "domain",
        "in": "query",
        "description": "Exact company domain, a bare domain such as `example.com`.",
        "schema": {
          "type": "string"
        },
        "example": "example.com"
      },
      "investor": {
        "name": "investor",
        "in": "query",
        "description": "Rounds that include this investor (exact, case-insensitive).",
        "schema": {
          "type": "string",
          "maxLength": 100
        }
      },
      "country": {
        "name": "country",
        "in": "query",
        "description": "Headquarters country. A country name or any two-letter ISO 3166-1 code (United States, US, Germany, DE) matches country_code exactly; any other text, such as a city, matches the stated location (country), case-insensitive.",
        "schema": {
          "type": "string",
          "maxLength": 60
        }
      },
      "limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size, 1 to 100 (default 25).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        },
        "example": 10
      },
      "cursor": {
        "name": "cursor",
        "in": "query",
        "description": "The previous page's `next_cursor`, passed back unchanged.",
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "X-Credits-Remaining": {
        "description": "USD credits left after this call settles.",
        "schema": {
          "type": "string"
        }
      },
      "X-Free-Records-Remaining": {
        "description": "Free records left this month after this call settles.",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "Every error answers with this shape. `error` is a human-readable message; `code` is a stable machine code when present.",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "A stable error code, e.g. INVALID_FILTER, INVALID_INPUT, INVALID_ID, NOT_FOUND, INSUFFICIENT_CREDITS, WATCHLIST_LIMIT, RATE_LIMITED."
          },
          "message": {
            "type": "string",
            "description": "Extra guidance on some errors (401, 402)."
          },
          "field": {
            "type": "string",
            "description": "The offending field, on some 400s."
          },
          "top_up_url": {
            "type": "string",
            "format": "uri",
            "description": "Where to add credits, on a 402."
          }
        },
        "additionalProperties": true
      },
      "FundingRecord": {
        "type": "object",
        "description": "A single funding round. Fields that are unknown for a round are null.",
        "required": [
          "id",
          "company_name",
          "announced_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "company_name": {
            "type": "string"
          },
          "company_domain": {
            "type": [
              "string",
              "null"
            ]
          },
          "event_class": {
            "type": [
              "string",
              "null"
            ],
            "description": "The kind of event, e.g. a funding round."
          },
          "round_label": {
            "type": [
              "string",
              "null"
            ],
            "description": "The human round label, e.g. \"Series A\"."
          },
          "round_stage": {
            "type": [
              "string",
              "null"
            ],
            "description": "The normalised round stage, e.g. \"series_a\" (the value `round` filters on)."
          },
          "amount_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "The round size in USD, when known."
          },
          "amount_original": {
            "type": [
              "number",
              "null"
            ],
            "description": "The round size in its original currency, when it was not USD."
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "description": "The original currency code for amount_original."
          },
          "announced_at": {
            "type": "string",
            "format": "date",
            "description": "The announcement date (the sort key)."
          },
          "investors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "lead_investors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "description": "The headquarters location as the source states it, often a city or a state."
          },
          "country_code": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$",
            "description": "The headquarters country as an ISO 3166-1 alpha-2 code, such as US. Null when the location is unknown, ambiguous or names two countries."
          },
          "source_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "The public announcement a buyer verifies against."
          },
          "attributes": {
            "type": [
              "object",
              "null"
            ],
            "description": "Extra, source-dependent fields.",
            "additionalProperties": true
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "FundingList": {
        "type": "object",
        "required": [
          "data",
          "count",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FundingRecord"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass back as `cursor` for the next page; null on the last page."
          },
          "count": {
            "type": "integer",
            "description": "How many records this page holds."
          }
        }
      },
      "ResearchRequest": {
        "type": "object",
        "example": {
          "domain": "acme.com",
          "purpose": "pre_call",
          "context": "We sell route planning software for 3PLs"
        },
        "description": "Exactly one prospect identifier, or `person_name` with `company_name`. Unknown fields are refused. An `email` must be a work address (a free-mail domain is refused); URLs must be http(s) on a public host.",
        "properties": {
          "domain": {
            "type": "string",
            "description": "A bare company domain such as acme.com.",
            "example": "acme.com"
          },
          "website_url": {
            "type": "string",
            "format": "uri"
          },
          "company_name": {
            "type": "string",
            "maxLength": 200
          },
          "company_linkedin_url": {
            "type": "string",
            "format": "uri",
            "description": "A linkedin.com/company/... URL."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "A work email such as jane@acme.com."
          },
          "linkedin_url": {
            "type": "string",
            "format": "uri",
            "description": "A linkedin.com/in/... URL."
          },
          "person_name": {
            "type": "string",
            "maxLength": 200,
            "description": "Only together with company_name."
          },
          "context": {
            "type": "string",
            "maxLength": 1000,
            "description": "Your own product or angle, to tailor the Fit section."
          },
          "purpose": {
            "type": "string",
            "enum": [
              "account_research",
              "pre_call",
              "outreach"
            ],
            "default": "account_research"
          }
        },
        "additionalProperties": false
      },
      "ResearchAccepted": {
        "type": "object",
        "required": [
          "research_id",
          "status",
          "estimated_seconds"
        ],
        "properties": {
          "research_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "The job status at acceptance (queued)."
          },
          "estimated_seconds": {
            "type": "integer",
            "description": "Roughly how long the brief takes."
          }
        }
      },
      "ResearchJob": {
        "type": "object",
        "required": [
          "research_id",
          "status",
          "input",
          "result",
          "error",
          "created_at",
          "completed_at"
        ],
        "properties": {
          "research_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "queued while it runs, then completed or failed."
          },
          "input": {
            "type": "object",
            "description": "The normalised input, echoed back.",
            "additionalProperties": true
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "description": "The cited brief when status is completed, else null.",
            "additionalProperties": true
          },
          "error": {
            "type": [
              "object",
              "string",
              "null"
            ],
            "description": "Why it failed when status is failed, else null."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "WatchlistFilters": {
        "type": "object",
        "description": "The GET /v1/funding filters a watchlist may hold (date windows and paging belong to the API call, not to an alert). At least one is required. Values may be strings or numbers.",
        "properties": {
          "round": {
            "type": "string",
            "example": "series_a,series_b"
          },
          "min_amount_usd": {
            "type": [
              "number",
              "string"
            ]
          },
          "max_amount_usd": {
            "type": [
              "number",
              "string"
            ]
          },
          "company": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "investor": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "description": "As the country filter of GET /v1/funding: a country name or ISO code matches country_code."
          }
        },
        "additionalProperties": false
      },
      "WatchlistRequest": {
        "type": "object",
        "example": {
          "name": "Seed rounds in Germany",
          "filters": {
            "round": "seed",
            "country": "Germany"
          },
          "webhook_url": "https://hooks.example.com/funding"
        },
        "required": [
          "name",
          "filters",
          "webhook_url"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "filters": {
            "$ref": "#/components/schemas/WatchlistFilters"
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "An https URL on a public host that receives signed match events."
          }
        },
        "additionalProperties": false
      },
      "Watchlist": {
        "type": "object",
        "required": [
          "id",
          "name",
          "filters",
          "webhook_url",
          "active",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "filters": {
            "$ref": "#/components/schemas/WatchlistFilters"
          },
          "webhook_url": {
            "type": "string",
            "format": "uri"
          },
          "active": {
            "type": "boolean"
          },
          "paused_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it was paused, if it was (revoked key, repeated webhook failures, filters no longer valid)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WatchlistWithSecret": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Watchlist"
          },
          {
            "type": "object",
            "required": [
              "secret"
            ],
            "properties": {
              "secret": {
                "type": "string",
                "description": "The webhook signing secret (whsec_...). Shown only in this create response."
              }
            }
          }
        ]
      },
      "WatchlistTestResult": {
        "type": "object",
        "required": [
          "delivered"
        ],
        "properties": {
          "delivered": {
            "type": "boolean"
          },
          "http_status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The status your webhook answered, if it responded."
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Delivery": {
        "type": "object",
        "required": [
          "id",
          "event_id",
          "status",
          "attempts",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "The funding round that matched."
          },
          "status": {
            "type": "string",
            "description": "pending, sending, delivered, retry, no_credit or failed."
          },
          "attempts": {
            "type": "integer"
          },
          "http_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "credits_remaining",
          "free_records_remaining",
          "free_records_per_month",
          "free_period_start",
          "price_per_record_usd",
          "research_price_usd"
        ],
        "properties": {
          "credits_remaining": {
            "type": "number",
            "description": "USD credits left."
          },
          "free_records_remaining": {
            "type": "integer",
            "description": "Free records left this calendar month."
          },
          "free_records_per_month": {
            "type": "integer"
          },
          "free_period_start": {
            "type": "string",
            "format": "date",
            "description": "The first day of the current free-record month (UTC)."
          },
          "price_per_record_usd": {
            "type": "number"
          },
          "research_price_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "The price of one POST /v1/research, or null while research is not priced."
          }
        }
      },
      "FeedbackRequest": {
        "type": "object",
        "example": {
          "kind": "bug",
          "title": "country filter ignores accents",
          "details": "GET /v1/funding?country=Curaçao returned 0 records; expected 2."
        },
        "required": [
          "title",
          "details"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "bug",
              "feature",
              "question"
            ],
            "default": "bug"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "details": {
            "type": "string",
            "minLength": 1,
            "maxLength": 8000
          },
          "tool": {
            "type": "string",
            "maxLength": 60,
            "description": "The tool or endpoint the report is about, e.g. research_get."
          }
        },
        "additionalProperties": false
      },
      "FeedbackAccepted": {
        "type": "object",
        "required": [
          "feedback_id",
          "status"
        ],
        "properties": {
          "feedback_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "sent."
          }
        }
      },
      "Version": {
        "type": "object",
        "required": [
          "version",
          "git_sha"
        ],
        "properties": {
          "version": {
            "type": "string",
            "description": "The SemVer API version."
          },
          "git_sha": {
            "type": [
              "string",
              "null"
            ],
            "description": "The deployed commit, when set."
          }
        }
      },
      "Pricing": {
        "type": "object",
        "required": [
          "currency",
          "funding",
          "research",
          "watchlists"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "description": "usd."
          },
          "funding": {
            "type": "object",
            "required": [
              "price_per_record_usd",
              "free_records_per_month"
            ],
            "properties": {
              "price_per_record_usd": {
                "type": "number"
              },
              "free_records_per_month": {
                "type": "integer"
              }
            }
          },
          "research": {
            "type": "object",
            "required": [
              "available",
              "price_per_research_usd"
            ],
            "properties": {
              "available": {
                "type": "boolean"
              },
              "price_per_research_usd": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "watchlists": {
            "type": "object",
            "required": [
              "price_per_delivered_record_usd",
              "free_records_apply"
            ],
            "properties": {
              "price_per_delivered_record_usd": {
                "type": "number"
              },
              "free_records_apply": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "ok."
          },
          "stale_holds": {
            "description": "Count of holds older than the release cutoff, or \"unknown\".",
            "type": [
              "integer",
              "string"
            ]
          },
          "stale_hold_minutes": {
            "type": "integer"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "required": [
          "type",
          "watchlist_id",
          "delivered_at",
          "data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "funding_event.matched"
          },
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "Deduplicate on this (also sent as the Prospect-Delivery-Id header). Absent on a test event."
          },
          "test": {
            "type": "boolean",
            "description": "True only on a test delivery."
          },
          "watchlist_id": {
            "type": "string",
            "format": "uuid"
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "$ref": "#/components/schemas/FundingRecord"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was invalid (e.g. a bad filter or input); nothing was charged.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The API key is missing or invalid.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Out of credits and free records. The body carries `top_up_url`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such record for this account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "WatchlistLimit": {
        "description": "The account already has the maximum number of active watchlists.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests; retry after the window.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ResearchNotPriced": {
        "description": "Research is not priced yet; no hold was taken.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "FeedbackUndelivered": {
        "description": "The report could not be delivered to the team; retry shortly.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "FeedbackUnavailable": {
        "description": "Feedback is not being accepted right now.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}