{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Pongg customer-owned CRM bridge",
    "version": "1.0.0",
    "description": "Implement these endpoints on your own public HTTPS bridge. This is a fixed pongg.crm.v1 connector contract, not a public Pongg API or arbitrary CRM URL connector. All examples are synthetic."
  },
  "servers": [
    {
      "url": "https://crm.example.com/pongg/v1",
      "description": "EXAMPLE ONLY. Replace with the customer-owned base URL configured in Pongg."
    }
  ],
  "security": [
    {
      "BridgeBearer": []
    },
    {
      "BridgeServiceAccount": []
    }
  ],
  "paths": {
    "/capabilities": {
      "post": {
        "operationId": "capabilities",
        "summary": "capabilities",
        "description": "Read-only setup probe.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CapabilitiesRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapabilitiesResponse"
                },
                "example": {
                  "contract_version": "pongg.crm.v1",
                  "operations": [
                    "contacts.search",
                    "contacts.upsert",
                    "leads.create",
                    "availability.list",
                    "appointments.create"
                  ],
                  "booking_closes_availability": true
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        }
      }
    },
    "/contacts/search": {
      "post": {
        "operationId": "contacts_search",
        "summary": "contacts.search",
        "description": "Fixed Pongg CRM bridge operation. Return a typed receipt, not an empty acknowledgement.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1",
                "phone": "+12145550148",
                "email": "jordan@example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                },
                "example": {
                  "contact": {
                    "id": "contact-example-001"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        }
      }
    },
    "/contacts/upsert": {
      "post": {
        "operationId": "contacts_upsert",
        "summary": "contacts.upsert",
        "description": "Fixed Pongg CRM bridge operation. Return a typed receipt, not an empty acknowledgement.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1",
                "contact": {
                  "full_name": "Jordan Example",
                  "first_name": "Jordan",
                  "last_name": "Example",
                  "phones": [
                    "+12145550148"
                  ],
                  "emails": [
                    "jordan@example.com"
                  ],
                  "address": "100 Example St, Dallas TX 75201",
                  "source": "Pongg (phone)",
                  "tags": [
                    "Pongg"
                  ],
                  "call_id": "example-call-001",
                  "postal_code": "75201"
                },
                "idempotency_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                },
                "example": {
                  "id": "contact-example-001",
                  "is_new": false
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "description": "Must exactly match idempotency_key in the JSON body."
          }
        ]
      }
    },
    "/availability": {
      "post": {
        "operationId": "availability_list",
        "summary": "availability.list",
        "description": "Fixed Pongg CRM bridge operation. Return a typed receipt, not an empty acknowledgement.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AvailabilityRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1",
                "window": {
                  "start": "2026-10-20T00:00:00+00:00",
                  "end": "2026-10-21T00:00:00+00:00",
                  "timezone": "America/Chicago",
                  "windows": [
                    [
                      1,
                      420,
                      1080
                    ]
                  ],
                  "slot_minutes": 60,
                  "job_type": "Roof repair"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                },
                "example": {
                  "slots": [
                    {
                      "start": "2026-10-20T15:00:00+00:00",
                      "end": "2026-10-20T16:00:00+00:00",
                      "timezone": "America/Chicago"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        }
      }
    },
    "/appointments": {
      "post": {
        "operationId": "appointments_create",
        "summary": "appointments.create",
        "description": "Fixed Pongg CRM bridge operation. Return a typed receipt, not an empty acknowledgement.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AppointmentRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1",
                "appointment": {
                  "contact_external_id": "contact-example-001",
                  "timezone": "America/Chicago",
                  "start": "2026-10-20T15:00:00+00:00",
                  "end": "2026-10-20T16:00:00+00:00",
                  "slot_text": "Tuesday at 10 AM Central",
                  "job_type": "Roof repair",
                  "address": "100 Example St, Dallas TX 75201",
                  "notes": "Synthetic example: inspect a small roof leak.",
                  "title": "Roof repair visit",
                  "source": "Pongg (phone)",
                  "location": {
                    "id": "dallas",
                    "name": "Dallas office"
                  },
                  "service_id": "repair-inspection"
                },
                "idempotency_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppointmentResponse"
                },
                "example": {
                  "id": "appointment-example-001",
                  "confirmed": true,
                  "start": "2026-10-20T15:00:00+00:00",
                  "end": "2026-10-20T16:00:00+00:00",
                  "timezone": "America/Chicago"
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "description": "Must exactly match idempotency_key in the JSON body."
          }
        ]
      }
    },
    "/leads": {
      "post": {
        "operationId": "leads_create",
        "summary": "leads.create",
        "description": "Fixed Pongg CRM bridge operation. Return a typed receipt, not an empty acknowledgement.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadRequest"
              },
              "example": {
                "tenant_id": "tenant-example-001",
                "contract_version": "pongg.crm.v1",
                "lead": {
                  "contact": {
                    "full_name": "Jordan Example",
                    "first_name": "Jordan",
                    "last_name": "Example",
                    "phones": [
                      "+12145550148"
                    ],
                    "emails": [
                      "jordan@example.com"
                    ],
                    "address": "100 Example St, Dallas TX 75201",
                    "source": "Pongg (phone)",
                    "tags": [
                      "Pongg"
                    ],
                    "call_id": "example-call-001",
                    "postal_code": "75201"
                  },
                  "job_type": "Roof repair",
                  "summary": "Caller requested an inspection.",
                  "notes": "Synthetic example only.",
                  "urgency": "routine",
                  "source": "Pongg (phone)",
                  "call_id": "example-call-001",
                  "location": {
                    "id": "dallas",
                    "name": "Dallas office"
                  }
                },
                "idempotency_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful typed response. Other 2xx statuses are accepted only with this same valid JSON object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                },
                "example": {
                  "id": "lead-example-001"
                }
              }
            }
          },
          "409": {
            "description": "Conflict or unavailable slot; no booking confirmed. Not automatically retried."
          },
          "429": {
            "description": "Rate limited. Retry-After may specify seconds or an HTTP date."
          },
          "5XX": {
            "description": "Temporary provider error; post-call delivery may retry with the same idempotency key."
          },
          "4XX": {
            "description": "Rejected request or credentials. Error bodies are not treated as receipts or shown verbatim."
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "description": "Must exactly match idempotency_key in the JSON body."
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BridgeBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Configured API key, or access token obtained using configured OAuth2 client credentials. Never put secrets in a URL."
      },
      "BridgeServiceAccount": {
        "type": "oauth2",
        "description": "EXAMPLE TOKEN URL ONLY: replace with the customer-owned authorization server configured in Pongg. Client credentials flow using HTTP Basic client authentication; optional configured scope is sent only when provided. No Pongg authorization-code or browser-consent server is described here.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://auth.example.com/oauth/token",
            "scopes": {}
          }
        }
      }
    },
    "schemas": {
      "Contact": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "description": "Caller name as captured; empty when unknown."
          },
          "first_name": {
            "type": "string",
            "description": "Caller given name when available; may be empty."
          },
          "last_name": {
            "type": "string",
            "description": "Caller family name when available; may be empty."
          },
          "address": {
            "type": "string",
            "description": "Service or street address captured from the caller; may be empty."
          },
          "source": {
            "type": "string",
            "description": "Lead attribution text, for example Pongg (phone); may be empty."
          },
          "call_id": {
            "type": "string",
            "description": "Originating call identifier. May be empty during an in-call action before post-call processing."
          },
          "phones": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Normalized phone identity; often E.164, but ambiguous source numbers can be bare digits. No strict E.164-only assumption."
            },
            "description": "Array of callback phone strings. Normalized where possible; can be empty or contain ambiguous bare-digit identities."
          },
          "emails": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Email as captured in the canonical contact; do not assume lowercasing or format validation."
            },
            "description": "Array of email strings captured from the caller. Can be empty; no assumed lowercase or strict format."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Source tags, for example Pongg."
            },
            "description": "Array of source tag strings, for example Pongg. Can be empty."
          },
          "postal_code": {
            "type": "string",
            "description": "Optional captured postal code. Omitted when no postal code is supplied."
          }
        },
        "required": [
          "full_name",
          "first_name",
          "last_name",
          "address",
          "source",
          "call_id",
          "phones",
          "emails",
          "tags"
        ],
        "additionalProperties": true,
        "description": "All listed fields are present except postal_code. Unknown scalar values are empty strings; collections can be empty arrays. At least one phone/email identity is required for contacts.upsert."
      },
      "Lead": {
        "type": "object",
        "properties": {
          "job_type": {
            "type": "string",
            "description": "Requested service or job type captured from the call; free-form string, not a fixed enum. May be empty."
          },
          "summary": {
            "type": "string",
            "description": "Short description of the caller need or call result; may be empty."
          },
          "notes": {
            "type": "string",
            "description": "Additional free-form call details and instructions; may be empty."
          },
          "urgency": {
            "type": "string",
            "description": "Captured urgency text or label. No fixed enum is required; may be empty."
          },
          "source": {
            "type": "string",
            "description": "Lead attribution text, for example Pongg (phone); may be empty."
          },
          "call_id": {
            "type": "string",
            "description": "Originating call identifier for provenance and call-based idempotency; may be empty."
          },
          "contact": {
            "$ref": "#/components/schemas/Contact",
            "description": "Nested caller Contact object with the fields listed above."
          },
          "location": {
            "$ref": "#/components/schemas/Location",
            "description": "Optional configured business location: id and name. Omitted when the call has no location."
          }
        },
        "required": [
          "job_type",
          "summary",
          "notes",
          "urgency",
          "source",
          "call_id",
          "contact"
        ],
        "additionalProperties": true
      },
      "Appointment": {
        "type": "object",
        "properties": {
          "contact_external_id": {
            "type": "string",
            "description": "Durable contact ID previously returned by this bridge.",
            "minLength": 1,
            "maxLength": 512
          },
          "timezone": {
            "type": "string",
            "description": "Valid IANA timezone, for example America/Chicago.",
            "minLength": 1,
            "maxLength": 128
          },
          "start": {
            "type": "string",
            "description": "Offset-aware ISO 8601 instant. Required and non-null for booking.",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "description": "Offset-aware ISO 8601 instant. Required and non-null for booking.",
            "format": "date-time"
          },
          "slot_text": {
            "type": "string",
            "description": "Verbatim or display time description from the call. It is not parsed as a substitute for start and end; may be empty."
          },
          "job_type": {
            "type": "string",
            "description": "Requested service or job type as captured; free-form string, not a fixed enum. May be empty."
          },
          "address": {
            "type": "string",
            "description": "Service address for the visit as captured; may be empty."
          },
          "notes": {
            "type": "string",
            "description": "Free-form booking details or instructions; may be empty."
          },
          "title": {
            "type": "string",
            "description": "Appointment title or display label; may be empty."
          },
          "source": {
            "type": "string",
            "description": "Appointment attribution text, for example Pongg (phone); may be empty."
          },
          "location": {
            "$ref": "#/components/schemas/Location",
            "description": "Optional configured business location: id and name. Omitted when the call has no location."
          },
          "service_id": {
            "type": "string",
            "description": "Optional service identifier supplied with the booking. Omitted when empty."
          }
        },
        "required": [
          "contact_external_id",
          "timezone",
          "start",
          "end",
          "slot_text",
          "job_type",
          "address",
          "notes",
          "title",
          "source"
        ],
        "additionalProperties": true
      },
      "Location": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Configured location ID."
          },
          "name": {
            "type": "string",
            "description": "Configured location name; may be empty."
          }
        },
        "required": [
          "id",
          "name"
        ],
        "additionalProperties": true
      },
      "Window": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "description": "Inclusive offset-aware start.",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "description": "Offset-aware end; later than start.",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone used for local business hours."
          },
          "windows": {
            "type": "array",
            "items": {
              "type": "array",
              "prefixItems": [
                {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                },
                {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                }
              ],
              "items": false,
              "minItems": 3,
              "maxItems": 3
            },
            "description": "Weekly hours: [day, openingMinute, closingMinute], day0=Monday; [] when not supplied."
          },
          "slot_minutes": {
            "type": "integer",
            "minimum": 0,
            "description": "Requested duration in minutes; 0 means unspecified."
          },
          "job_type": {
            "type": "string",
            "description": "Present as a string; may be empty when unknown."
          }
        },
        "required": [
          "start",
          "end",
          "timezone",
          "windows",
          "slot_minutes",
          "job_type"
        ],
        "additionalProperties": true
      },
      "Slot": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "description": "Offset-aware start within the requested window.",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "description": "Offset-aware end after start and within the requested window.",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "description": "Valid IANA timezone.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "start",
          "end",
          "timezone"
        ],
        "additionalProperties": true
      },
      "Envelope": {
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "description": "Pongg client tenant ID. Bind the configured credential to this tenant.",
            "minLength": 1
          },
          "contract_version": {
            "type": "string",
            "const": "pongg.crm.v1"
          }
        },
        "required": [
          "tenant_id",
          "contract_version"
        ],
        "additionalProperties": true,
        "description": "Present on every request. Accept additive fields for compatible v1 evolution."
      },
      "WriteEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "idempotency_key": {
                "type": "string",
                "description": "Opaque deterministic key, identical to the Idempotency-Key header.",
                "pattern": "^[0-9a-f]{64}$"
              }
            },
            "required": [
              "idempotency_key"
            ],
            "additionalProperties": true
          }
        ]
      },
      "CapabilitiesResponse": {
        "type": "object",
        "properties": {
          "contract_version": {
            "type": "string",
            "const": "pongg.crm.v1"
          },
          "operations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "capabilities",
                "contacts.search",
                "contacts.upsert",
                "availability.list",
                "appointments.create",
                "leads.create"
              ]
            },
            "minItems": 2
          },
          "booking_closes_availability": {
            "type": "boolean",
            "description": "Must be true when availability.list is advertised; bookings must close the same openings."
          }
        },
        "required": [
          "contract_version",
          "operations"
        ],
        "additionalProperties": true,
        "description": "Must include contacts.upsert and at least one of leads.create or appointments.create. availability.list also requires appointments.create and booking_closes_availability:true.",
        "allOf": [
          {
            "properties": {
              "operations": {
                "contains": {
                  "const": "contacts.upsert"
                }
              }
            }
          },
          {
            "anyOf": [
              {
                "properties": {
                  "operations": {
                    "contains": {
                      "const": "leads.create"
                    }
                  }
                }
              },
              {
                "properties": {
                  "operations": {
                    "contains": {
                      "const": "appointments.create"
                    }
                  }
                }
              }
            ]
          }
        ],
        "if": {
          "properties": {
            "operations": {
              "contains": {
                "const": "availability.list"
              }
            }
          }
        },
        "then": {
          "required": [
            "booking_closes_availability"
          ],
          "properties": {
            "booking_closes_availability": {
              "const": true
            },
            "operations": {
              "contains": {
                "const": "appointments.create"
              }
            }
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "contact": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Nonblank durable contact ID.",
                    "minLength": 1,
                    "maxLength": 512
                  }
                },
                "required": [
                  "id"
                ],
                "additionalProperties": true
              }
            ]
          }
        },
        "required": [
          "contact"
        ],
        "additionalProperties": true
      },
      "ContactResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Nonblank durable CRM contact ID; no control characters.",
            "minLength": 1,
            "maxLength": 512
          },
          "is_new": {
            "type": "boolean",
            "description": "True only if a new contact was created; false when matched/updated."
          }
        },
        "required": [
          "id",
          "is_new"
        ],
        "additionalProperties": true
      },
      "AvailabilityResponse": {
        "type": "object",
        "properties": {
          "slots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Slot"
            },
            "maxItems": 50
          }
        },
        "required": [
          "slots"
        ],
        "additionalProperties": true
      },
      "AppointmentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Nonblank durable CRM appointment ID.",
            "minLength": 1,
            "maxLength": 512
          },
          "confirmed": {
            "type": "boolean",
            "const": true
          },
          "start": {
            "type": "string",
            "description": "Must equal the requested start instant.",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "description": "Must equal the requested end instant.",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "description": "Valid IANA timezone.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "id",
          "confirmed",
          "start",
          "end",
          "timezone"
        ],
        "additionalProperties": true
      },
      "LeadResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Nonblank durable CRM lead ID.",
            "minLength": 1,
            "maxLength": 512
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": true
      },
      "CapabilitiesRequest": {
        "$ref": "#/components/schemas/Envelope"
      },
      "SearchRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "phone": {
                "type": "string",
                "description": "Present as a string; may be empty when unknown."
              },
              "email": {
                "type": "string",
                "description": "Present as a string; may be empty when unknown."
              }
            },
            "required": [
              "phone",
              "email"
            ],
            "additionalProperties": true
          }
        ]
      },
      "ContactRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WriteEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "contact": {
                "$ref": "#/components/schemas/Contact"
              }
            },
            "required": [
              "contact"
            ],
            "additionalProperties": true
          }
        ]
      },
      "AvailabilityRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "window": {
                "$ref": "#/components/schemas/Window"
              }
            },
            "required": [
              "window"
            ],
            "additionalProperties": true
          }
        ]
      },
      "AppointmentRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WriteEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "appointment": {
                "$ref": "#/components/schemas/Appointment"
              }
            },
            "required": [
              "appointment"
            ],
            "additionalProperties": true
          }
        ]
      },
      "LeadRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WriteEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "lead": {
                "$ref": "#/components/schemas/Lead"
              }
            },
            "required": [
              "lead"
            ],
            "additionalProperties": true
          }
        ]
      }
    }
  },
  "x-pongg-mcp": {
    "protocolVersion": "2026-07-28",
    "transport": "Streamable HTTP",
    "method": "tools/call",
    "tools": {
      "capabilities": "pongg_capabilities",
      "contacts.search": "pongg_contacts_search",
      "contacts.upsert": "pongg_contacts_upsert",
      "availability.list": "pongg_availability_list",
      "appointments.create": "pongg_appointments_create",
      "leads.create": "pongg_leads_create"
    },
    "description": "The same operation request body becomes params.arguments; result.structuredContent contains the same response object. Fixed bridge tools only; no arbitrary discovery or browser OAuth."
  }
}
