{
  "openapi": "3.1.0",
  "info": {
    "title": "Billion Connect API",
    "version": "0.3.0",
    "description": "Delegated personal CRM metadata and agency intake contract for runtime connect/0.3. This contract describes implemented operations, not certification of an agent host, provider readiness or a commercial result. Read the integration guide at https://billionleadspro.com/docs/api. All examples are synthetic."
  },
  "servers": [{ "url": "https://billionleadspro.com/api/connect/v1" }],
  "externalDocs": { "description": "Billion Connect integration guide", "url": "https://billionleadspro.com/docs/api" },
  "security": [{ "BearerAuth": [] }],
  "tags": [
    { "name": "Personal", "description": "Agent keys, including keys issued by owners and managers, can access only the issuer's currently assigned leads." },
    { "name": "Agency", "description": "Agency keys are server credentials with leads:ingest only. Routing is configured separately in the authenticated application." }
  ],
  "x-contract-version": "connect/0.3",
  "x-scopes": {
    "profile:read": "Technical connection identity, granted scopes and expiry, without email.",
    "leads:read": "Opaque metadata of leads currently assigned to the issuer.",
    "pipeline:read": "Active technical pipeline/stage catalog and personal counts; requires current CRM entitlement.",
    "notes:create": "Append one manual note; requires explicit delegated write acceptance.",
    "pipeline:move": "Organize a card without changing sales status, assignment or consent; requires current CRM entitlement and explicit write acceptance.",
    "leads:profile:update": "Update permitted basic fields; requires explicit delegated write acceptance. Names and timezone remain unavailable to reads.",
    "leads:ingest": "Agency key only: capture a private CRM lead without verified contact permission or external sending."
  },
  "x-quotas": {
    "bucket_type": "fixed",
    "per_key_per_minute": 30,
    "per_account_per_minute": 120,
    "per_account_per_utc_day": 2000,
    "shared_across": ["REST", "MCP", "agent keys", "agency keys"],
    "retry_after_seconds": 60,
    "description": "Each admitted operation costs quota, including a later business conflict or denial. MCP revalidates with me for every transport request, including negotiation and discovery; executing a tool adds its own admission. A tool call can therefore cost two admissions. Rotating keys does not reset account quota."
  },
  "x-limits": {
    "http_json_body_bytes": 32768,
    "personal_sql_object_representation_bytes": 16384,
    "personal_receipt_hours": 24,
    "description": "Unknown fields, duplicate query parameters and token query parameters are rejected. Only GET /leads accepts limit and after; all other operations reject query parameters. Responses use Cache-Control: private, no-store, Pragma: no-cache and X-Content-Type-Options: nosniff. HTTPS and approved hosts/origins are enforced; external integrations run on a server without a browser Origin."
  },
  "x-mcp": {
    "url": "https://billionleadspro.com/api/connect/mcp",
    "transport": "Streamable HTTP",
    "method": "POST",
    "response_mode": "JSON",
    "authentication": "Manual Authorization: Bearer API key header; no OAuth or OAuth discovery.",
    "description": "The REST paths below do not describe MCP JSON-RPC messages. MCP exposes only the personal tools allowed by granted scopes, with a fresh server instance per request. No agency intake, key management or arbitrary execution tool exists."
  },
  "paths": {
    "/me": {
      "get": {
        "operationId": "getConnectionIdentity",
        "tags": ["Personal"],
        "summary": "Identify the delegated personal connection",
        "description": "Start here with an agent key. Returns technical IDs, current granted scopes, expiry and contract version. Authorization is revalidated on every request. Agency keys cannot call this operation.",
        "x-key-kind": "agent",
        "x-required-scopes": ["profile:read"],
        "x-mcp-tool": "billion_me",
        "responses": {
          "200": { "description": "Current technical connection identity", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeResponse" }, "example": { "data": { "key_id": "50000001-0000-4000-8000-000000000001", "account_id": "10000001-0000-4000-8000-000000000001", "actor_id": "60000001-0000-4000-8000-000000000001", "visibility": "personal", "scopes": ["profile:read", "leads:read"], "expires_at": "2026-10-30T12:00:00Z", "contract_version": "connect/0.3" }, "meta": { "request_id": "70000001-0000-4000-8000-000000000001" } } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/leads": {
      "get": {
        "operationId": "listPersonalLeads",
        "tags": ["Personal"],
        "summary": "List currently assigned lead metadata",
        "description": "UUID ascending cursor pagination over live personal assignments, not a portfolio snapshot. Continue with after equal to next_cursor until next_cursor is null. Concurrent transfers can change membership between pages. Returns opaque labels without names, phone, email, timezone, note content or acquisition/consent evidence. No additional filters are supported.",
        "x-key-kind": "agent",
        "x-required-scopes": ["leads:read"],
        "x-mcp-tool": "billion_list_leads",
        "parameters": [
          { "name": "limit", "in": "query", "required": false, "description": "Page size; exactly one occurrence is allowed.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
          { "name": "after", "in": "query", "required": false, "description": "Previous next_cursor UUID. Omit on the first page; do not send null or duplicate this parameter.", "schema": { "$ref": "#/components/schemas/Uuid" } }
        ],
        "responses": {
          "200": { "description": "Page of personal metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LeadListResponse" }, "example": { "data": { "items": [{ "id": "20000001-0000-4000-8000-000000000001", "label": "Lead 20000001", "state": "FL", "language": "pt", "status": "novo", "received_at": "2026-09-01T00:00:00Z", "updated_at": "2026-09-05T00:00:00Z", "revision": 4, "placement": { "pipeline_id": null, "stage_id": null, "version": 0 } }], "next_cursor": null }, "meta": { "request_id": "70000001-0000-4000-8000-000000000001" } } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/leads/{lead_id}": {
      "parameters": [{ "$ref": "#/components/parameters/LeadId" }],
      "get": {
        "operationId": "getPersonalLead",
        "tags": ["Personal"],
        "summary": "Read personal lead metadata and current versions",
        "description": "Read before a new write intent to obtain revision and placement.version. A lead outside the personal portfolio, in another account or undergoing erasure returns not_found without distinguishing those causes. Status is the existing CRM value, not proof of a sale, conversation, attendance or consent.",
        "x-key-kind": "agent",
        "x-required-scopes": ["leads:read"],
        "x-mcp-tool": "billion_get_lead",
        "responses": {
          "200": { "description": "Authorized lead metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LeadResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/pipeline/catalog": {
      "get": {
        "operationId": "getPersonalPipelineCatalog",
        "tags": ["Personal"],
        "summary": "Read the active technical pipeline catalog",
        "description": "Requires current CRM entitlement. Pipeline/stage labels are technical and opaque, not free-form CRM names. Counts include only the issuer's currently assigned leads. Obtain catalog_version before a pipeline move. Agency distribution queues product/recruitment are unrelated to this placement catalog.",
        "x-key-kind": "agent",
        "x-required-scopes": ["pipeline:read"],
        "x-mcp-tool": "billion_pipeline_catalog",
        "responses": {
          "200": { "description": "Active catalog and personal stage counts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CatalogResponse" }, "example": { "data": { "catalog_version": 12, "pipelines": [{ "id": "30000001-0000-4000-8000-000000000001", "label": "Pipeline 30000001", "stages": [{ "id": "40000001-0000-4000-8000-000000000001", "label": "Stage 40000001", "count": 2 }] }] }, "meta": { "request_id": "70000001-0000-4000-8000-000000000001" } } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/leads/{lead_id}/notes": {
      "parameters": [{ "$ref": "#/components/parameters/LeadId" }],
      "post": {
        "operationId": "appendPersonalLeadNote",
        "tags": ["Personal"],
        "summary": "Append one manual note",
        "description": "Requires the granted write scope and explicit write acceptance at key creation. Append-only; notes cannot be read, edited or deleted through Connect. Use a fresh positive expected_revision and a UUID idempotency_key stable for this exact intent. Receipts are scoped to key + operation + idempotency_key for 24 hours. After a timeout repeat the same payload and key; changed payload, expired receipt or stale fences conflict. Never fabricate contact, consent or sales evidence.",
        "x-key-kind": "agent",
        "x-required-scopes": ["notes:create"],
        "x-mcp-tool": "billion_append_note",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteRequest" }, "example": { "content": "Synthetic manual review note. No contact occurred.", "expected_revision": 4, "idempotency_key": "70000002-0000-4000-8000-000000000001" } } } },
        "responses": {
          "200": { "description": "Committed note receipt or authorized exact replay", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriteResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/leads/{lead_id}/placement": {
      "parameters": [{ "$ref": "#/components/parameters/LeadId" }],
      "post": {
        "operationId": "movePersonalLeadPlacement",
        "tags": ["Personal"],
        "summary": "Organize a card in a pipeline stage",
        "description": "Requires explicit write acceptance, pipeline:move and current CRM entitlement. Read the lead revision, placement.version and catalog_version before a new intent. Both targets must be active IDs in the same account, or both null to detach. Does not change sales status, assignment or consent. Application leads and outside-US leads without the existing pipeline gate cannot be moved. Exact authorized replay is available for 24 hours; changed intent or stale versions conflict.",
        "x-key-kind": "agent",
        "x-required-scopes": ["pipeline:move"],
        "x-mcp-tool": "billion_move_pipeline",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlacementRequest" }, "example": { "pipeline_id": "30000001-0000-4000-8000-000000000001", "stage_id": "40000001-0000-4000-8000-000000000001", "expected_revision": 4, "expected_version": 0, "expected_catalog_version": 12, "idempotency_key": "70000003-0000-4000-8000-000000000001" } } } },
        "responses": {
          "200": { "description": "Committed placement receipt, including placement_version, or authorized exact replay", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriteResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/leads/{lead_id}/profile": {
      "parameters": [{ "$ref": "#/components/parameters/LeadId" }],
      "patch": {
        "operationId": "updatePersonalLeadProfile",
        "tags": ["Personal"],
        "summary": "Update permitted basic profile fields",
        "description": "Requires explicit write acceptance and leads:profile:update. A nonempty patch can include only first_name, last_name, state, language and timezone. Updating a name or timezone does not make it readable through Connect. Phone, email, status, assignment, consent, money and medical information are rejected. Use fresh expected_revision and a stable intent UUID. Exact authorized replay is available for 24 hours.",
        "x-key-kind": "agent",
        "x-required-scopes": ["leads:profile:update"],
        "x-mcp-tool": "billion_update_profile",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProfileRequest" }, "example": { "patch": { "state": "FL", "language": "pt", "timezone": "America/New_York" }, "expected_revision": 4, "idempotency_key": "70000004-0000-4000-8000-000000000001" } } } },
        "responses": {
          "200": { "description": "Committed basic profile receipt or authorized exact replay", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriteResponse" } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    },
    "/intake": {
      "post": {
        "operationId": "ingestAgencyLead",
        "tags": ["Agency"],
        "summary": "Capture one private CRM lead from an agency backend",
        "description": "Agency key with leads:ingest only; the current issuer must remain an active owner/platform_admin. The server derives the account and recipient from the key and configured queue. product/recruitment are agency distribution queues, not CRM placement IDs. Default hold assigns to the issuer; round_robin uses only 1 to 20 explicitly configured eligible members and falls back to hold if none remain eligible. Stable account + event_id with an exact payload returns duplicate, including after key rotation; changed payload or an existing account phone conflicts. Erased leads or retained identity tombstones return not_found and require human privacy review, even for a new event_id. Created leads have status novo, list_kind cold, manual_transfer_only true, callable false, import_opt_in false and consent_given false. Claimed consent is agency_declared_unverified with granted false even if contact_requested is true. Only an internal CRM notification occurs; no campaign, email, call, WhatsApp or provider starts. Agency receipts have no automatic expiry or cleanup in this runtime.",
        "x-key-kind": "agency",
        "x-required-scopes": ["leads:ingest"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IntakeRequest" }, "example": { "event_id": "synthetic-form-event-001", "pipeline": "product", "first_name": "Synthetic", "last_name": "Fixture", "phone": "+15555550101", "state": "FL", "language": "pt", "timezone": "America/New_York", "captured_at": "2026-09-30T12:00:00Z", "source_reference": "synthetic-form-v1", "consent": { "contact_requested": false, "evidence_text": "Synthetic denied contact request, fixture only.", "occurred_at": "2026-09-30T12:00:00Z" } } } } },
        "responses": {
          "200": { "description": "New capture or exact duplicate receipt", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IntakeResponse" }, "example": { "data": { "lead_id": "20000001-0000-4000-8000-000000000001", "event_id": "synthetic-form-event-001", "disposition": "held", "assigned_to": "60000001-0000-4000-8000-000000000001" }, "meta": { "request_id": "70000001-0000-4000-8000-000000000001" } } } } },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "Billion Connect API key", "description": "Send Authorization: Bearer <API_KEY_FROM_SERVER_VAULT>. Use a Connect key issued in Settings > Integrations. Application cookies/session JWTs, Supabase keys, service role credentials and tokens in query strings are not Connect credentials. API keys are displayed once and must be stored in a server secret manager. No OAuth is implemented." }
    },
    "parameters": {
      "LeadId": { "name": "lead_id", "in": "path", "required": true, "description": "UUID of a currently assigned lead; lowercase canonical form is required by the REST route.", "schema": { "$ref": "#/components/schemas/PathUuid" }, "example": "20000001-0000-4000-8000-000000000001" }
    },
    "responses": {
      "InvalidRequest": { "description": "400 invalid_request: unknown fields, unsupported/duplicate query parameters, invalid types, missing fields or invalid values. Correct the request.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "Unauthorized": { "description": "401 unauthorized: wrong key kind, invalid, expired or revoked key, or issuer membership/authority no longer valid. Reconfigure the authorized connection.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "Forbidden": { "description": "403 insufficient_scope or operation_unavailable: missing granted scope, write acceptance, current entitlement or permitted host/origin. Do not infer authorization from tool discovery alone.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "NotFound": { "description": "404 not_found: unavailable resource, personal/account boundary or privacy exclusion. This does not disclose whether a resource exists elsewhere. Intake privacy tombstones require human review.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "Conflict": { "description": "409 conflict: stale version, changed/expired personal intent, duplicate agency event with changed payload, existing phone or concurrent operation. Re-read state and obtain a new decision before creating a new personal intent. Never change event_id to bypass privacy or deduplication.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "TooLarge": { "description": "413 invalid_request: missing HTTP JSON body or body exceeds 32768 bytes. Personal SQL object representation is additionally limited to 16384 bytes and may produce 400.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "RateLimited": { "description": "429 rate_limited: shared quota exceeded. Respect Retry-After and back off; key rotation does not bypass account limits.", "headers": { "Retry-After": { "description": "Seconds before retry", "schema": { "type": "string", "const": "60" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "Unavailable": { "description": "503 temporarily_unavailable: safe failure. Treat as unavailable, never as an empty successful dataset. For an ambiguous personal write, repeat the same exact intent before considering a new one.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
    },
    "schemas": {
      "Uuid": { "type": "string", "format": "uuid", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" },
      "PathUuid": { "type": "string", "format": "uuid", "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" },
      "NullableUuid": { "oneOf": [{ "$ref": "#/components/schemas/Uuid" }, { "type": "null" }] },
      "Version": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Technical concurrency counter, not a commercial metric." },
      "ExpectedRevision": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Positive current lead revision obtained by reading the lead before a new intent." },
      "CleanText": { "type": "string", "minLength": 1, "pattern": "^(?![\\s\\S]*[\\u0000-\\u001f\\u007f])(?=[\\s\\S]*\\S)[\\s\\S]+$", "description": "Must contain a non-whitespace character and no control characters. The server trims surrounding whitespace." },
      "Name": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 100 },
      "Timezone": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 64, "description": "Valid timezone accepted by both the server runtime and database timezone catalog, for example America/New_York. Not returned by personal lead reads." },
      "State": { "type": "string", "enum": ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"], "description": "Uppercase US state code or DC; territories are excluded." },
      "Language": { "type": "string", "enum": ["pt", "en", "es"] },
      "ClaimedInstant": { "type": "string", "format": "date-time", "minLength": 1, "maxLength": 40, "pattern": "^\\d{4}-\\d{2}-\\d{2}T.*(?:Z|[+-]\\d{2}:\\d{2})$", "description": "Finite timestamp with explicit timezone; no more than five minutes in the future. An agency declaration, not a signed or verified provider event." },
      "Meta": { "type": "object", "additionalProperties": false, "required": ["request_id"], "properties": { "request_id": { "$ref": "#/components/schemas/Uuid" } } },
      "Me": {
        "type": "object", "additionalProperties": false,
        "required": ["key_id", "account_id", "actor_id", "visibility", "scopes", "expires_at", "contract_version"],
        "properties": {
          "key_id": { "$ref": "#/components/schemas/Uuid" },
          "account_id": { "$ref": "#/components/schemas/Uuid" },
          "actor_id": { "$ref": "#/components/schemas/Uuid" },
          "visibility": { "type": "string", "const": "personal" },
          "scopes": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "enum": ["profile:read", "leads:read", "pipeline:read", "notes:create", "pipeline:move", "leads:profile:update"] } },
          "expires_at": { "type": "string", "format": "date-time" },
          "contract_version": { "type": "string", "const": "connect/0.3" }
        }
      },
      "Placement": {
        "type": "object", "additionalProperties": false, "required": ["pipeline_id", "stage_id", "version"],
        "properties": { "pipeline_id": { "$ref": "#/components/schemas/NullableUuid" }, "stage_id": { "$ref": "#/components/schemas/NullableUuid" }, "version": { "$ref": "#/components/schemas/Version" } }
      },
      "Lead": {
        "type": "object", "additionalProperties": false,
        "required": ["id", "label", "state", "language", "status", "received_at", "updated_at", "revision", "placement"],
        "properties": {
          "id": { "$ref": "#/components/schemas/Uuid" },
          "label": { "type": "string", "pattern": "^Lead [0-9A-F]{8}$", "description": "Opaque UUID-derived label; never the person's name." },
          "state": { "oneOf": [{ "$ref": "#/components/schemas/State" }, { "type": "null" }], "description": "Null when the stored state is not a supported US/DC code." },
          "language": { "$ref": "#/components/schemas/Language" },
          "status": { "type": "string", "description": "Existing CRM status value. No contact, consent or sale is proven by this value." },
          "received_at": { "type": "string", "format": "date-time", "description": "Assignment timestamp when present, otherwise creation timestamp." },
          "updated_at": { "type": "string", "format": "date-time" },
          "revision": { "type": "integer", "minimum": 1 },
          "placement": { "$ref": "#/components/schemas/Placement" }
        },
        "description": "Personal metadata only. No real names, phone, email, timezone, notes, acquisition details, consent evidence, medical or financial data."
      },
      "LeadPage": { "type": "object", "additionalProperties": false, "required": ["items", "next_cursor"], "properties": { "items": { "type": "array", "maxItems": 100, "items": { "$ref": "#/components/schemas/Lead" } }, "next_cursor": { "$ref": "#/components/schemas/NullableUuid" } } },
      "Stage": { "type": "object", "additionalProperties": false, "required": ["id", "label", "count"], "properties": { "id": { "$ref": "#/components/schemas/Uuid" }, "label": { "type": "string", "pattern": "^Stage [0-9A-F]{8}$" }, "count": { "type": "integer", "minimum": 0, "description": "Count of the issuer's currently assigned leads in this stage." } } },
      "Pipeline": { "type": "object", "additionalProperties": false, "required": ["id", "label", "stages"], "properties": { "id": { "$ref": "#/components/schemas/Uuid" }, "label": { "type": "string", "pattern": "^Pipeline [0-9A-F]{8}$" }, "stages": { "type": "array", "items": { "$ref": "#/components/schemas/Stage" } } } },
      "Catalog": { "type": "object", "additionalProperties": false, "required": ["catalog_version", "pipelines"], "properties": { "catalog_version": { "$ref": "#/components/schemas/Version" }, "pipelines": { "type": "array", "items": { "$ref": "#/components/schemas/Pipeline" } } } },
      "NoteRequest": {
        "type": "object", "additionalProperties": false, "required": ["content", "expected_revision", "idempotency_key"],
        "properties": { "content": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 1000 }, "expected_revision": { "$ref": "#/components/schemas/ExpectedRevision" }, "idempotency_key": { "$ref": "#/components/schemas/Uuid" } }
      },
      "PlacementRequest": {
        "type": "object", "additionalProperties": false,
        "required": ["pipeline_id", "stage_id", "expected_revision", "expected_version", "expected_catalog_version", "idempotency_key"],
        "properties": { "pipeline_id": { "$ref": "#/components/schemas/NullableUuid" }, "stage_id": { "$ref": "#/components/schemas/NullableUuid" }, "expected_revision": { "$ref": "#/components/schemas/ExpectedRevision" }, "expected_version": { "$ref": "#/components/schemas/Version" }, "expected_catalog_version": { "$ref": "#/components/schemas/Version" }, "idempotency_key": { "$ref": "#/components/schemas/Uuid" } },
        "oneOf": [
          { "properties": { "pipeline_id": { "$ref": "#/components/schemas/Uuid" }, "stage_id": { "$ref": "#/components/schemas/Uuid" } } },
          { "properties": { "pipeline_id": { "type": "null" }, "stage_id": { "type": "null" } } }
        ]
      },
      "ProfilePatch": {
        "type": "object", "additionalProperties": false, "minProperties": 1,
        "properties": { "first_name": { "$ref": "#/components/schemas/Name" }, "last_name": { "$ref": "#/components/schemas/Name" }, "state": { "$ref": "#/components/schemas/State" }, "language": { "$ref": "#/components/schemas/Language" }, "timezone": { "$ref": "#/components/schemas/Timezone" } }
      },
      "ProfileRequest": {
        "type": "object", "additionalProperties": false, "required": ["patch", "expected_revision", "idempotency_key"],
        "properties": { "patch": { "$ref": "#/components/schemas/ProfilePatch" }, "expected_revision": { "$ref": "#/components/schemas/ExpectedRevision" }, "idempotency_key": { "$ref": "#/components/schemas/Uuid" } }
      },
      "WriteReceipt": {
        "type": "object", "additionalProperties": false,
        "required": ["action_id", "operation", "lead_id", "resource_id", "actor_id", "key_id", "revision", "committed_at", "replayed"],
        "properties": {
          "action_id": { "$ref": "#/components/schemas/Uuid" },
          "operation": { "type": "string", "enum": ["note_create", "pipeline_move", "profile_update"] },
          "lead_id": { "$ref": "#/components/schemas/Uuid" },
          "resource_id": { "$ref": "#/components/schemas/Uuid", "description": "New note ID for note_create; lead ID for the other personal writes." },
          "actor_id": { "$ref": "#/components/schemas/Uuid" },
          "key_id": { "$ref": "#/components/schemas/Uuid" },
          "revision": { "type": "integer", "minimum": 1 },
          "committed_at": { "type": "string", "format": "date-time" },
          "replayed": { "type": "boolean" },
          "placement_version": { "type": "integer", "minimum": 1, "description": "Present only for pipeline_move." }
        },
        "allOf": [{ "if": { "properties": { "operation": { "const": "pipeline_move" } } }, "then": { "required": ["placement_version"] }, "else": { "not": { "required": ["placement_version"] } } }],
        "description": "Receipt proves only this CRM mutation. Replay preserves the original result and sets replayed true. Authorization and personal assignment are revalidated before replay."
      },
      "AgencyConsent": {
        "type": "object", "additionalProperties": false, "required": ["contact_requested", "evidence_text", "occurred_at"],
        "properties": { "contact_requested": { "type": "boolean", "description": "Unverified agency declaration; even true does not grant channel permission." }, "evidence_text": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 1000 }, "occurred_at": { "$ref": "#/components/schemas/ClaimedInstant" } }
      },
      "IntakeRequest": {
        "type": "object", "additionalProperties": false,
        "required": ["event_id", "pipeline", "first_name", "last_name", "phone", "state", "language", "captured_at", "source_reference", "consent"],
        "properties": {
          "event_id": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 128, "description": "Stable opaque capture ID, unique within the key's account. Never include PII. Reuse the same ID and exact payload for a retry, including after key rotation." },
          "pipeline": { "type": "string", "enum": ["product", "recruitment"], "description": "Agency distribution queue, not a CRM placement pipeline ID." },
          "first_name": { "$ref": "#/components/schemas/Name" },
          "last_name": { "$ref": "#/components/schemas/Name" },
          "phone": { "type": "string", "pattern": "^\\+[1-9][0-9]{6,14}$", "description": "E.164 phone; an existing phone in this account causes conflict, without merge or overwrite." },
          "email": { "type": "string", "maxLength": 254, "pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$", "description": "Optional email; omitted values are allowed, null is rejected." },
          "state": { "$ref": "#/components/schemas/State" },
          "language": { "$ref": "#/components/schemas/Language" },
          "timezone": { "$ref": "#/components/schemas/Timezone", "description": "Optional valid server/database timezone; defaults to America/New_York when omitted." },
          "product_interest": { "type": "string", "enum": ["final_expense", "term", "iul", "whole_life", "annuity", "mortgage_protection"], "default": "final_expense" },
          "captured_at": { "$ref": "#/components/schemas/ClaimedInstant" },
          "source_reference": { "allOf": [{ "$ref": "#/components/schemas/CleanText" }], "maxLength": 120 },
          "consent": { "$ref": "#/components/schemas/AgencyConsent" }
        }
      },
      "IntakeReceipt": { "type": "object", "additionalProperties": false, "required": ["lead_id", "event_id", "disposition", "assigned_to"], "properties": { "lead_id": { "$ref": "#/components/schemas/Uuid" }, "event_id": { "type": "string", "minLength": 1, "maxLength": 128 }, "disposition": { "type": "string", "enum": ["held", "assigned", "duplicate"] }, "assigned_to": { "$ref": "#/components/schemas/Uuid" } } },
      "MeResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/Me" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "LeadListResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/LeadPage" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "LeadResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/Lead" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "CatalogResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/Catalog" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "WriteResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/WriteReceipt" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "IntakeResponse": { "type": "object", "additionalProperties": false, "required": ["data", "meta"], "properties": { "data": { "$ref": "#/components/schemas/IntakeReceipt" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "ErrorResponse": {
        "type": "object", "additionalProperties": false, "required": ["error", "meta"],
        "properties": {
          "error": { "type": "object", "additionalProperties": false, "required": ["code", "message"], "properties": { "code": { "type": "string", "enum": ["invalid_request", "unauthorized", "operation_unavailable", "insufficient_scope", "not_found", "conflict", "rate_limited", "temporarily_unavailable"] }, "message": { "type": "string", "description": "Sanitized message; the current REST runtime repeats the error code. Contains no SQL, submitted payload or PII." } } },
          "meta": { "$ref": "#/components/schemas/Meta" }
        },
        "example": { "error": { "code": "conflict", "message": "conflict" }, "meta": { "request_id": "70000001-0000-4000-8000-000000000001" } }
      }
    }
  }
}
