> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bridge.new/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Bridge exposes three integration surfaces: the REST Integrations API for pushing data into Bridge, webhooks for receiving events from Bridge, and the public Lead Capture endpoint that a tenant's landing page posts to.
> The Integrations API host is https://api-connect-us.bridge.new and every request to it must be authenticated with the x-api-key header. Bridge does not use bearer tokens or OAuth.
> The Lead Capture endpoint is different and the Integrations API rules do not apply to it: it has its own host, it takes no x-api-key and no authentication header of any kind, and it is called from a visitor's browser. It is identified by a workspace id and a capture key together with a reCAPTCHA token. Never tell a reader to authenticate it with an API key, and never tell them to keep its capture key out of frontend code - it is designed to live in the page.
> Integrations API error codes follow the BRIDGE_<DOMAIN>_<NNNN> format, for example BRIDGE_CONVERSATION_0001, and are listed on the error codes page. Lead Capture error codes follow a different format, BRIDGE.CAMPAIGN_LEADS.<NAME>, and are listed on the Lead Capture error reference. Never invent a code that is not listed on the page for its own surface.
> This documentation covers the Integrations API, webhooks and Lead Capture only. It does not describe the Bridge web application or its internal APIs.

# Register a campaign lead

> Registers a lead captured by a tenant's landing page and queues the first outbound WhatsApp message. A 202 means the lead was accepted, not that a message was sent.



## OpenAPI

````yaml /api-reference/campaign-leads.openapi.yaml post /leadscout/campaign-leads
openapi: 3.1.0
info:
  title: Bridge Campaign Leads API
  description: >-
    Public endpoint for registering leads captured by a tenant's landing page.
    No API key is required: the caller is identified by its workspace and
    capture key together with a reCAPTCHA v3 token.
  version: 1.0.0
servers:
  - url: https://integrations-us.app.bridge.new/api/v1
security: []
paths:
  /leadscout/campaign-leads:
    post:
      tags:
        - Campaign leads
      summary: Register a campaign lead
      description: >-
        Registers a lead captured by a tenant's landing page and queues the
        first outbound WhatsApp message. A 202 means the lead was accepted, not
        that a message was sent.
      operationId: create_campaign_lead_leadscout_campaign_leads_post
      parameters:
        - description: >-
            Required when calling from a browser. A CORS preflight carries no
            body, so the tenant cannot be resolved — and
            Access-Control-Allow-Origin cannot be echoed — unless the workspace
            is on the URL. Server-to-server callers do not preflight and may
            omit it.
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Workspaceid
            description: >-
              Required when calling from a browser. A CORS preflight carries no
              body, so the tenant cannot be resolved — and
              Access-Control-Allow-Origin cannot be echoed — unless the
              workspace is on the URL. Server-to-server callers do not preflight
              and may omit it.
          name: workspaceId
          in: query
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignLeadRequestDto'
        required: true
      responses:
        '202':
          description: >-
            Accepted and queued. NOT sent — a separate service transmits the
            first message later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignLeadAcceptedDto'
        '400':
          description: >-
            Malformed payload, unusable phone, consent not granted, or a missing
            brand.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
        '403':
          description: >-
            Capture disabled, capture key mismatch, captcha rejected, or origin
            not allowed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
        '422':
          description: >-
            The captcha provider could not be reached. Transient; retrying is
            safe.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
        '500':
          description: Unexpected failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
components:
  schemas:
    CampaignLeadRequestDto:
      properties:
        workspaceId:
          type: string
          title: Workspaceid
        captureKey:
          type: string
          title: Capturekey
        cellphone:
          type: string
          title: Cellphone
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
        brandId:
          anyOf:
            - type: string
            - type: 'null'
          title: Brandid
        landingUri:
          type: string
          title: Landinguri
        utm:
          additionalProperties:
            type: string
          type: object
          title: Utm
        consent:
          $ref: '#/components/schemas/ConsentDto'
        recaptchaToken:
          type: string
          title: Recaptchatoken
      type: object
      required:
        - workspaceId
        - captureKey
        - cellphone
        - landingUri
        - consent
        - recaptchaToken
      title: CampaignLeadRequestDto
      description: Wire contract for `POST api/v1/leadscout/campaign-leads`.
    CampaignLeadAcceptedDto:
      properties:
        requestId:
          type: string
          title: Requestid
          description: >-
            Correlation id for this submission. Present on acceptance only;
            error responses do not carry one.
      type: object
      required:
        - requestId
      title: CampaignLeadAcceptedDto
      description: >-
        Body of the `202 Accepted` response.


        Named rather than a bare `dict[str, str]` so the published schema states
        what the

        single field is and what it is for, instead of "an object with string
        properties".
    ProblemDetailsDto:
      properties:
        type:
          type: string
          title: Type
          description: Stable machine-readable error code.
        title:
          type: string
          title: Title
          description: Short human-readable summary.
        status:
          type: integer
          title: Status
          description: HTTP status code, repeated in the body.
        detail:
          anyOf:
            - type: string
            - type: 'null'
          title: Detail
          description: Optional elaboration. Absent on most rejections.
      type: object
      required:
        - type
        - title
        - status
      title: ProblemDetailsDto
      description: >-
        RFC 9457 problem details, as the global exception handler emits them.


        Context is deliberately stripped before this reaches a caller: on a
        public endpoint,

        a detailed rejection tells an attacker which check they failed.
    ConsentDto:
      properties:
        status:
          $ref: '#/components/schemas/ConsentStatus'
        capturedAt:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Capturedat
      type: object
      required:
        - status
      title: ConsentDto
      description: >-
        The tenant's attestation that the visitor gave permission to be
        messaged.


        This is NOT `CommercialConsentState`, which is our own record of a
        contact's opt-in

        lifecycle. This is a claim arriving from outside, and it is not
        verifiable by us: it

        proves what we were told and when, which is what we would present if a
        tenant's

        portfolio were ever restricted.
    ConsentStatus:
      type: string
      enum:
        - GRANTED
        - NOT_PROVIDED
      title: ConsentStatus

````