openapi: 3.1.0
info:
  title: Kira Integration Surface
  version: 1.1.0
  description: >
    Kira-side endpoints for external system integrations.
    POST /mcp is available today on every Kira tenant. The
    /webhooks/{partner}/{connectionId} ingress route is configured
    per partner during onboarding.
  contact:
    name: Rezonate integration team
servers:
  - url: https://{kiraHost}
    description: Your tenant's Kira API host, issued at partner onboarding.
    variables:
      kiraHost:
        default: your-kira-host.example.com
paths:
  /mcp:
    post:
      operationId: mcpJsonRpc
      summary: "MCP JSON-RPC gateway (tools/list, tools/call). Available today."
      security:
        - kiraBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JsonRpcRequest'
            examples:
              toolsList:
                summary: Discover the tools enabled for your tenant
                value:
                  jsonrpc: "2.0"
                  id: 1
                  method: "tools/list"
              toolsCallRead:
                summary: Read tool example
                value:
                  jsonrpc: "2.0"
                  id: 2
                  method: "tools/call"
                  params:
                    name: "connector_search_record"
                    arguments: { phone: "+61400000000" }
              toolsCallWrite:
                summary: Write tool example (idempotency key required)
                value:
                  jsonrpc: "2.0"
                  id: 3
                  method: "tools/call"
                  params:
                    name: "connector_log_interaction"
                    arguments:
                      externalId: "external-record-id"
                      subject: "Membership enquiry"
                      idempotencyKey: "conv-abc-turn-4"
      responses:
        "200":
          description: JSON-RPC result (tool output) or JSON-RPC error object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonRpcResponse'
        "401":
          description: Missing or invalid bearer credential; includes WWW-Authenticate
          headers:
            WWW-Authenticate:
              schema: { type: string }
  /webhooks/{partner}/{connectionId}:
    post:
      operationId: partnerInboundEvent
      summary: "External system to Kira event ingress. Configured at partner onboarding."
      description: >
        Pattern: authenticate the ingress secret, validate required fields,
        schedule an outreach workflow off the request path, return 202.
        The concrete route for your integration (for example
        POST /webhooks/engagerm/{connectionId}) is provisioned during
        onboarding together with your ingress secret.
      parameters:
        - name: partner
          in: path
          required: true
          schema: { type: string }
          description: Partner slug assigned at onboarding
        - name: connectionId
          in: path
          required: true
          schema: { type: string }
      security:
        - ingressSecret: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerInboundEvent'
      responses:
        "202":
          description: Accepted; outreach workflow scheduled off the request path
          content:
            application/json:
              schema:
                type: object
                properties:
                  scheduled: { type: boolean, const: true }
                  eventId: { type: string }
        "400":
          description: Missing required fields
        "401":
          description: Missing or invalid ingress secret
components:
  securitySchemes:
    kiraBearer:
      type: http
      scheme: bearer
      description: Kira-issued bearer credential; resolves to your tenant.
    ingressSecret:
      type: http
      scheme: bearer
      description: >
        Kira-issued ingress secret (Authorization Bearer header, or the
        x-workflow-ingress-secret header). Kira issues the secret; the
        partner stores it in their webhook or plug-in configuration.
  schemas:
    JsonRpcRequest:
      type: object
      required: [jsonrpc, method]
      properties:
        jsonrpc: { type: string, const: "2.0" }
        id: { type: [integer, string, "null"] }
        method: { type: string, enum: ["tools/list", "tools/call"] }
        params:
          type: object
          properties:
            name:
              type: string
              description: "Tool name, for example connector_search_record"
            arguments: { type: object, additionalProperties: true }
    JsonRpcResponse:
      type: object
      required: [jsonrpc]
      properties:
        jsonrpc: { type: string, const: "2.0" }
        id: { type: [integer, string, "null"] }
        result: { type: object, additionalProperties: true }
        error:
          type: object
          properties:
            code: { type: integer }
            message: { type: string }
    PartnerInboundEvent:
      type: object
      required: [tenantId, event]
      properties:
        tenantId: { type: string }
        event:
          type: string
          description: >
            Partner-specific event type. Examples: "membership.lapsed",
            "appointment.cancelled", "case.updated", "record.created".
            The supported event list for your integration is agreed at
            onboarding.
        externalId:
          type: string
          description: "Primary external record ID (GUID or system-assigned key)"
        payload: { type: object, additionalProperties: true }
    PersonLookupInput:
      type: object
      description: "At least one identifier required."
      properties:
        phone: { type: string, description: "E.164" }
        email: { type: string, format: email }
        externalId: { type: string, description: "Record ID in the external system" }
    Person:
      type: object
      description: "Kira canonical Person (mapped from external contact/patient/member)."
      properties:
        externalId: { type: string, description: "Record ID in the external system" }
        fullName: { type: string }
        email: { type: string }
        phone: { type: string }
    TimelineEvent:
      type: object
      description: >
        Kira canonical TimelineEvent (interaction, appointment, order, consent).
        Used for both read results and write confirmations.
      properties:
        externalId: { type: string }
        type:
          type: string
          examples: ["call", "appointment", "order", "consent", "note"]
        subject: { type: string }
        timestamp: { type: string, format: date-time }
    LogInteractionInput:
      type: object
      required: [externalId, subject, idempotencyKey]
      properties:
        externalId: { type: string, description: "External record ID for the entity the interaction regards" }
        type: { type: string, examples: ["call", "note"] }
        subject: { type: string }
        body: { type: string }
        outcome: { type: string, examples: ["resolved", "escalated", "renewal_intent"] }
        idempotencyKey: { type: string }
    WriteResult:
      type: object
      properties:
        id: { type: string, description: "Created or updated external record id" }
        status: { type: string, examples: ["success", "error"] }
    ToolError:
      type: object
      description: "Surfaced as a JSON-RPC error object."
      properties:
        code:
          type: string
          examples: ["permission_denied", "not_found", "upstream_error", "timeout"]
        message: { type: string }
