openapi: 3.2.0 info: title: Cape Partners — Sniffer Agent Registration API version: 1.0.0 description: Machine-readable API backing the Cape Partners M&A deal-flow workspace (click, humans). contact: name: Cape Partners url: https://www.capepartners.fr servers: - url: https://www.capepartners.fr description: Production (www) via Cloudflare - url: https://sniffer.capepartners.fr description: Workspace host - url: http://localhost:3000 description: Local dev tags: - name: Registration paths: /api/submit: post: summary: Register a seller (opportunity) or buyer (investor) inbound lead and get… tags: - Registration responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/SubmitResponse' '400': description: Empty/Invalid body content: application/json: schema: type: object description: Empty/Invalid body properties: error: type: string required: - error '403': description: Turnstile human-verification failed content: application/json: schema: type: object description: Turnstile human-verification failed properties: error: type: string required: - error requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SubmitRequest' security: [] operationId: postApiSubmit x-operation-id-source: derived components: schemas: SellerProfile: type: object properties: revenue: type: number description: Revenue in EUR millions growth: type: number description: Revenue growth, percent ebitda_margin: type: number description: EBITDA margin, percent product: type: string description: Product/solution description sector: type: string description: type: string data_quality: type: integer description: Data-quality score /10 missing_fields: type: array items: type: string SubmitResponse: type: object properties: session_id: type: string matches: type: integer match_details: type: array items: $ref: '#/components/schemas/Match' summary: type: string SubmitRequest: type: object properties: session_id: type: string user_type: type: string enum: - investor - opportunity - seller identity: $ref: '#/components/schemas/Identity' buyer: $ref: '#/components/schemas/BuyerProfile' seller: $ref: '#/components/schemas/SellerProfile' turnstileToken: type: string description: Cloudflare Turnstile verification token (required) required: - user_type - turnstileToken BuyerProfile: type: object properties: sector: type: string check_size_min: type: number description: Ticket (deal size) min, in EUR millions check_size_max: type: number description: Ticket (deal size) max, in EUR millions geography: type: string growth_target: type: number description: Target revenue growth, percent ebitda_target: type: number description: Target EBITDA margin, percent solution_1: type: string solution_2: type: string solution_3: type: string data_quality: type: integer description: Data-quality score /10 missing_fields: type: array items: type: string Match: type: object description: A ranked counterparty match. Names are redacted (Company A/B/C…) and financial fit signals are returned as coarse bands inside `reasons` (strong/moderate/weak/poor) until an NDA is recorded. Full identity and granular metrics unlock only after POST /api/nda/sign. properties: id: type: integer name: type: string description: Redacted name (Company A/B/C…) unless NDA-gated reveal score: type: number format: float description: Overall fit score (deterministic x semantic) scores: type: object description: Per-dimension deterministic sub-scores (revenue/growth/ebitda/deterministic/semantic) data_quality: type: number format: float reasons: type: array items: type: string description: 'Band-qualified fit reasons, e.g. "Revenue fit: strong vs range €2M–€50M" (no raw revenue/growth/EBITDA)' Identity: type: object properties: name: type: string description: Contact first/last name email: type: string format: email company: type: string role: type: string securitySchemes: SessionToken: type: apiKey in: header name: X-Session-Id description: 'The workspace session UUID is a capability token carried in the URL PATH (not this header — shown here only because OpenAPI securitySchemes cannot model a path parameter as a credential). A valid request must present a well-formed UUID-v4 in the path segment {session_id} AND a first-party Origin/Referer (or none). Requests carrying a known-foreign Origin/Referer are refused 403. Per-IP rate limiting applies. All responses carry Referrer-Policy: strict-origin-when-cross-origin.' NdaSigned: type: apiKey in: header name: X-Nda-Signed description: 'Precondition (not a literal header): a server-side NDA signature for {session_id} must be recorded in the nda_signatures table via POST /api/nda/sign before NDA-gated resources (/api/matched-names, /api/infomemo/*) will serve data. Recorded signatures are enforced server-side (helper `nda_signed`), not by trusting a client header.'