{
  "openapi": "3.0.3",
  "info": {
    "title": "Triple Session Public API",
    "version": "2.0.0",
    "license": {
      "name": "Proprietary",
      "url": "https://triplesession.com/terms-of-service"
    },
    "description": "Public API v2 exposes Triple Session data through stable REST endpoints.\nRequests are authenticated with a public API key sent as a bearer token.\nThe API key determines the maximum accessible resource scope.\n"
  },
  "servers": [
    {
      "url": "https://api.triplesession.com/v2",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Calls",
      "description": "Call report data and artifacts."
    },
    {
      "name": "Scorecards",
      "description": "Scorecard rubric data."
    }
  ],
  "paths": {
    "/calls": {
      "get": {
        "operationId": "listCalls",
        "tags": ["Calls"],
        "summary": "List calls",
        "description": "Lists calls visible to the API key. Optionally narrow results with `workspaceId`. Requires `calls.read`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceIdFilter"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/CallsLimit"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/ScorecardIdQuery"
          }
        ],
        "responses": {
          "200": {
            "description": "Calls visible to the API key.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-RateLimit-Active-Window": {
                "$ref": "#/components/headers/XRateLimitActiveWindow"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallsListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/calls/{callId}": {
      "get": {
        "operationId": "getCall",
        "tags": ["Calls"],
        "summary": "Get a call",
        "description": "Gets one call report after direct resource authorization. Requires `calls.read`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "Call report details.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-RateLimit-Active-Window": {
                "$ref": "#/components/headers/XRateLimitActiveWindow"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/calls/{callId}/transcript": {
      "get": {
        "operationId": "getCallTranscript",
        "tags": ["Calls"],
        "summary": "Get a call transcript",
        "description": "Gets a paginated and capped transcript for a call. Requires `calls.read`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/TranscriptLimit"
          },
          {
            "$ref": "#/components/parameters/MaxChars"
          },
          {
            "$ref": "#/components/parameters/RawTranscript"
          }
        ],
        "responses": {
          "200": {
            "description": "Call transcript page.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-RateLimit-Active-Window": {
                "$ref": "#/components/headers/XRateLimitActiveWindow"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/calls/{callId}/scorecard": {
      "get": {
        "operationId": "getCallScorecard",
        "tags": ["Calls"],
        "summary": "Get a call scorecard",
        "description": "Gets scorecard evaluation output and coaching plan data for a call. Requires `calls.read`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "Scorecard evaluation output for the call.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-RateLimit-Active-Window": {
                "$ref": "#/components/headers/XRateLimitActiveWindow"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallScorecardResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/scorecards/{scorecardId}/rubric": {
      "get": {
        "operationId": "getScorecardRubric",
        "tags": ["Scorecards"],
        "summary": "Get a scorecard rubric",
        "description": "Gets the rubric for a scorecard visible in the workspace. Requires `coaching.read`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ScorecardId"
          }
        ],
        "responses": {
          "200": {
            "description": "Scorecard rubric details.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-RateLimit-Active-Window": {
                "$ref": "#/components/headers/XRateLimitActiveWindow"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScorecardRubricResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "Use a public API key with the endpoint's required scope."
      }
    },
    "parameters": {
      "WorkspaceIdFilter": {
        "name": "workspaceId",
        "in": "query",
        "required": false,
        "description": "Optional workspace ID filter. The value must be within the API key's accessible scope.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "CallId": {
        "name": "callId",
        "in": "path",
        "required": true,
        "description": "Call ID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "ScorecardId": {
        "name": "scorecardId",
        "in": "path",
        "required": true,
        "description": "Scorecard ID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "Page number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "CallsLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Number of calls to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "TranscriptLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Number of transcript segments to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 100
        }
      },
      "MaxChars": {
        "name": "max_chars",
        "in": "query",
        "required": false,
        "description": "Maximum transcript characters returned in one response.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 50000,
          "default": 20000
        }
      },
      "RawTranscript": {
        "name": "raw",
        "in": "query",
        "required": false,
        "description": "Whether to request the raw transcript. Any value except `false` is treated as true by the API.",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "Search": {
        "name": "search",
        "in": "query",
        "required": false,
        "description": "Search text used to filter calls.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        }
      },
      "ScorecardIdQuery": {
        "name": "scorecard_id",
        "in": "query",
        "required": false,
        "description": "Filter calls by scorecard ID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "headers": {
      "XRateLimitLimit": {
        "description": "Limit for the active rate limit window.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitRemaining": {
        "description": "Requests remaining in the active rate limit window.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitReset": {
        "description": "Unix timestamp when the active rate limit window resets.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitActiveWindow": {
        "description": "Active rate limit window.",
        "schema": {
          "type": "string",
          "enum": ["minute", "hour"]
        }
      },
      "RetryAfter": {
        "description": "Seconds until the request may be retried.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid path or query parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid bearer authentication.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Missing scope, expired key, unsupported key scope, or resource outside the API key scope.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Requested call or scorecard was not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          },
          "X-RateLimit-Active-Window": {
            "$ref": "#/components/headers/XRateLimitActiveWindow"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Unexpected server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["message"],
            "properties": {
              "message": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": false
      },
      "Pagination": {
        "type": "object",
        "required": ["page", "page_size", "total_count", "total_pages"],
        "properties": {
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "page_size": {
            "type": "integer",
            "minimum": 1
          },
          "total_count": {
            "type": "integer",
            "minimum": 0
          },
          "total_pages": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "TranscriptPagination": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "required": ["has_more"],
            "properties": {
              "has_more": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "CrmObject": {
        "type": "object",
        "required": ["id", "name", "url", "type"],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Call": {
        "type": "object",
        "required": [
          "id",
          "name",
          "owner_id",
          "score",
          "score_breakdown",
          "scorecard",
          "scorecard_id",
          "created_at",
          "duration_in_minutes",
          "source",
          "evaluatee_user_id",
          "evaluatee_user_name",
          "evaluatee_email"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "owner_id": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "score_breakdown": {
            "type": "object",
            "additionalProperties": true
          },
          "scorecard": {
            "type": "string"
          },
          "scorecard_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_in_minutes": {
            "type": "number",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "evaluatee_user_id": {
            "type": "string"
          },
          "evaluatee_user_name": {
            "type": "string"
          },
          "evaluatee_email": {
            "type": "string"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attendees": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "crm_objects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmObject"
            }
          }
        },
        "additionalProperties": false
      },
      "CallsListResponse": {
        "type": "object",
        "required": ["calls", "pagination"],
        "properties": {
          "calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Call"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "additionalProperties": false
      },
      "CallResponse": {
        "type": "object",
        "required": ["call"],
        "properties": {
          "call": {
            "$ref": "#/components/schemas/Call"
          }
        },
        "additionalProperties": false
      },
      "TranscriptSegment": {
        "type": "object",
        "required": ["index", "text"],
        "properties": {
          "index": {
            "type": "integer",
            "minimum": 0
          },
          "text": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Transcript": {
        "type": "object",
        "required": ["text", "is_format_supported", "segments"],
        "properties": {
          "text": {
            "type": "string"
          },
          "is_format_supported": {
            "type": "boolean"
          },
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranscriptSegment"
            }
          }
        },
        "additionalProperties": false
      },
      "TranscriptResponse": {
        "type": "object",
        "required": ["transcript", "pagination", "truncated"],
        "properties": {
          "transcript": {
            "$ref": "#/components/schemas/Transcript"
          },
          "pagination": {
            "$ref": "#/components/schemas/TranscriptPagination"
          },
          "truncated": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ScorecardCriterion": {
        "type": "object",
        "required": ["id", "name", "score", "comment"],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "score": {
            "type": "string",
            "enum": ["yes", "no", "partial"]
          },
          "comment": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ScorecardSection": {
        "type": "object",
        "required": ["name", "criteria"],
        "properties": {
          "name": {
            "type": "string"
          },
          "criteria": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScorecardCriterion"
            }
          }
        },
        "additionalProperties": false
      },
      "CallScorecard": {
        "type": "object",
        "required": ["name", "sections"],
        "properties": {
          "name": {
            "type": "string"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScorecardSection"
            }
          }
        },
        "additionalProperties": false
      },
      "CoachingFocusArea": {
        "type": "object",
        "required": [
          "biggest_improvement_opportunity",
          "recommendation",
          "try_this",
          "question_suggestions"
        ],
        "properties": {
          "biggest_improvement_opportunity": {
            "type": "string"
          },
          "recommendation": {
            "type": "string"
          },
          "try_this": {
            "type": "string"
          },
          "question_suggestions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "CoachingItem": {
        "type": "object",
        "required": ["name", "comment"],
        "properties": {
          "name": {
            "type": "string"
          },
          "comment": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "CoachingPlan": {
        "type": "object",
        "required": ["focus_area", "strengths", "areas_for_improvement"],
        "properties": {
          "focus_area": {
            "$ref": "#/components/schemas/CoachingFocusArea"
          },
          "strengths": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoachingItem"
            }
          },
          "areas_for_improvement": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoachingItem"
            }
          }
        },
        "additionalProperties": false
      },
      "CallScorecardResponse": {
        "type": "object",
        "required": ["scorecard", "coaching_plan"],
        "properties": {
          "scorecard": {
            "$ref": "#/components/schemas/CallScorecard"
          },
          "coaching_plan": {
            "$ref": "#/components/schemas/CoachingPlan"
          }
        },
        "additionalProperties": false
      },
      "ScorecardRubric": {
        "type": "object",
        "required": ["id", "name", "content"],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "content": {
            "description": "Scorecard content. Internal `deal_insights_order` metadata is omitted.",
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": false
      },
      "ScorecardRubricResponse": {
        "type": "object",
        "required": ["scorecard"],
        "properties": {
          "scorecard": {
            "$ref": "#/components/schemas/ScorecardRubric"
          }
        },
        "additionalProperties": false
      }
    }
  }
}
