{
  "info": {
    "title": "Ribbon API",
    "version": "v1",
    "description": "API for Ribbon"
  },
  "servers": [
    {
      "url": "https://app.ribbon.ai/be-api/"
    },
    {
      "url": "https://staging.ribbon.ai/be-api/"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "UUID",
        "description": "Provide your API key UUID in the 'Authorization' header prefixed with 'Bearer '.\nExample: 'Authorization: Bearer 123e4567-e89b-12d3-a456-426614174000'"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "description": "Error code"
          },
          "status": {
            "type": "string",
            "description": "Error name"
          },
          "message": {
            "type": "string",
            "description": "Error message"
          },
          "errors": {
            "type": "object",
            "description": "Errors",
            "additionalProperties": {}
          }
        },
        "additionalProperties": false
      },
      "PaginationMetadata": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          },
          "first_page": {
            "type": "integer"
          },
          "last_page": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "previous_page": {
            "type": "integer"
          },
          "next_page": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      },
      "PingResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Returns 'pong'"
          }
        },
        "required": [
          "message"
        ],
        "additionalProperties": false
      },
      "Team": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the team."
          },
          "name": {
            "type": "string",
            "description": "The name of the team."
          },
          "created_at": {
            "type": "string",
            "description": "The date the team was created."
          }
        },
        "required": [
          "created_at",
          "id",
          "name"
        ],
        "additionalProperties": false
      },
      "GetTeamsResponse": {
        "type": "object",
        "properties": {
          "teams": {
            "type": "array",
            "description": "A list of teams in the organization.",
            "items": {
              "$ref": "#/components/schemas/Team"
            }
          }
        },
        "required": [
          "teams"
        ],
        "additionalProperties": false
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "The error message"
          },
          "code": {
            "type": "integer",
            "description": "The status code"
          },
          "status": {
            "type": "string",
            "description": "The status"
          }
        },
        "required": [
          "code",
          "message",
          "status"
        ],
        "additionalProperties": false
      },
      "Word": {
        "type": "object",
        "properties": {
          "end": {
            "type": "number"
          },
          "start": {
            "type": "number"
          },
          "word": {
            "type": "string"
          }
        },
        "required": [
          "end",
          "start",
          "word"
        ],
        "additionalProperties": false
      },
      "Segment": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "words": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Word"
            }
          }
        },
        "required": [
          "content",
          "role",
          "words"
        ],
        "additionalProperties": false
      },
      "BaseSegment": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string"
          },
          "role": {
            "type": "string"
          }
        },
        "required": [
          "content",
          "role"
        ],
        "additionalProperties": false
      },
      "QuestionToTranscriptMapping": {
        "type": "object",
        "properties": {
          "script_question": {
            "type": "string",
            "description": "The question as provided during interview flow creation."
          },
          "transcript_item_indices": {
            "type": "array",
            "description": "A list of indices. The indices are the indices of the items in transcript_with_timestamp which are relevant to the script question. It includes the question asked by the agent as well as the user answers, but can also include follow up questions. The indices are often but not necessarily consecutive.",
            "items": {
              "type": "integer"
            }
          },
          "start_timestamp": {
            "type": "number",
            "description": "The start timestamp of the section of the recording that is relevant to the script question."
          },
          "end_timestamp": {
            "type": "number",
            "description": "The end timestamp of the section of the recording that is relevant to the script question."
          },
          "transcript_items": {
            "type": "array",
            "description": "The items in transcript_with_timestamp which are relevant to the script question. For brevity, these items do not include a detailed list of words, but these can be accessed from transcript_with_timestamp by the transcript_item_indices",
            "items": {
              "$ref": "#/components/schemas/BaseSegment"
            }
          }
        },
        "required": [
          "end_timestamp",
          "script_question",
          "start_timestamp",
          "transcript_item_indices",
          "transcript_items"
        ],
        "additionalProperties": false
      },
      "Scores": {
        "type": "object",
        "properties": {
          "communication": {
            "type": "number",
            "default": null,
            "description": "Communication score from the interview.",
            "nullable": true
          },
          "motivation": {
            "type": "number",
            "default": null,
            "description": "Motivation score from the interview.",
            "nullable": true
          },
          "skills": {
            "type": "number",
            "default": null,
            "description": "Skills score from the interview.",
            "nullable": true
          },
          "language_vocabulary_and_expression": {
            "type": "number",
            "default": null,
            "description": "Language vocabulary and expression score from the interview.",
            "nullable": true
          },
          "language_grammar_and_structure": {
            "type": "number",
            "default": null,
            "description": "Language grammar and structure score from the interview.",
            "nullable": true
          },
          "language_fluency_and_pace": {
            "type": "number",
            "default": null,
            "description": "Language fluency and pace score from the interview.",
            "nullable": true
          },
          "language_comprehension": {
            "type": "number",
            "default": null,
            "description": "Language comprehension score from the interview.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InterviewData": {
        "type": "object",
        "properties": {
          "transcript": {
            "type": "string",
            "description": "Full transcript of the interview."
          },
          "transcript_with_timestamp": {
            "type": "array",
            "description": "Full transcript of the interview with word-level timestamps.",
            "items": {
              "$ref": "#/components/schemas/Segment"
            }
          },
          "questions_to_transcript_mapping": {
            "type": "array",
            "description": "A mapping of all the script questions to the actual interview transcript segments.",
            "items": {
              "$ref": "#/components/schemas/QuestionToTranscriptMapping"
            }
          },
          "audio_url": {
            "type": "string",
            "default": null,
            "description": "Url to the interview audio recording.",
            "nullable": true
          },
          "video_url": {
            "type": "string",
            "default": null,
            "description": "Url to the interview video recording.",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "default": null,
            "description": "Summary of the interview.",
            "nullable": true
          },
          "scores": {
            "default": null,
            "description": "Interview scores grouped together.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/Scores"
              },
              {
                "type": "object",
                "nullable": true
              }
            ]
          },
          "interviewee_email_address": {
            "type": "string",
            "default": null,
            "description": "Email address of the interviewee.",
            "nullable": true
          },
          "interviewee_first_name": {
            "type": "string",
            "default": null,
            "description": "First name of the interviewee.",
            "nullable": true
          },
          "interviewee_last_name": {
            "type": "string",
            "default": null,
            "description": "Last name of the interviewee.",
            "nullable": true
          }
        },
        "required": [
          "questions_to_transcript_mapping",
          "transcript",
          "transcript_with_timestamp"
        ],
        "additionalProperties": false
      },
      "Interview": {
        "type": "object",
        "properties": {
          "interview_flow_id": {
            "type": "string",
            "description": "The ID of the interview flow."
          },
          "interview_id": {
            "type": "string",
            "description": "The ID of the interview."
          },
          "team_id": {
            "type": "string",
            "description": "The ID of the team this interview belongs to."
          },
          "status": {
            "description": "The status of the interview.",
            "type": "string",
            "enum": [
              "incomplete",
              "completed"
            ]
          },
          "interview_data": {
            "description": "Data for the completed interview. If the interview is incomplete, this field will be null.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/InterviewData"
              },
              {
                "type": "object",
                "nullable": true
              }
            ]
          }
        },
        "required": [
          "interview_data",
          "interview_flow_id",
          "interview_id",
          "status",
          "team_id"
        ],
        "additionalProperties": false
      },
      "GetInterviewsResponse": {
        "type": "object",
        "properties": {
          "interviews": {
            "type": "array",
            "description": "A list of interviews.",
            "items": {
              "$ref": "#/components/schemas/Interview"
            }
          }
        },
        "required": [
          "interviews"
        ],
        "additionalProperties": false
      },
      "DeleteInterviewResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indicates successful deletion of interview recordings."
          }
        },
        "required": [
          "success"
        ],
        "additionalProperties": false
      },
      "PostInterviewRequest": {
        "type": "object",
        "properties": {
          "interview_flow_id": {
            "type": "string",
            "description": "The interview flow ID."
          },
          "interviewee_email_address": {
            "type": "string",
            "default": null,
            "description": "The interviewee email address. This is used to identify the interviewee on the Ribbon platform. If not provided, this interview will not appear on the Ribbon platform",
            "nullable": true
          },
          "interviewee_first_name": {
            "type": "string",
            "default": null,
            "description": "The interviewee first name.",
            "nullable": true
          },
          "interviewee_last_name": {
            "type": "string",
            "default": null,
            "description": "The interviewee last name.",
            "nullable": true
          },
          "assigned_recruiter_id": {
            "type": "string",
            "default": null,
            "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
            "description": "The ID of the team member to assign this interview to. Must belong to the same team as the interview flow. If provided, the returned interview_link will include assignedRecruiterId as a query parameter. Use GET /team-members to retrieve valid team member IDs.",
            "nullable": true
          }
        },
        "required": [
          "interview_flow_id"
        ],
        "additionalProperties": false
      },
      "PostInterviewResponse": {
        "type": "object",
        "properties": {
          "interview_id": {
            "type": "string",
            "description": "The ID of the created interview."
          },
          "interview_link": {
            "type": "string",
            "description": "The single-use link to begin and conduct the interview."
          },
          "hint": {
            "type": "string",
            "default": null,
            "description": "Helpful hint about interview visibility.",
            "nullable": true
          }
        },
        "required": [
          "interview_id",
          "interview_link"
        ],
        "additionalProperties": false
      },
      "InterviewFlow": {
        "type": "object",
        "properties": {
          "interview_flow_id": {
            "type": "string",
            "description": "The ID of the interview flow."
          },
          "team_id": {
            "type": "string",
            "description": "The ID of the team this interview flow belongs to."
          },
          "org_name": {
            "type": "string",
            "description": "The name of the organization requesting the interview."
          },
          "title": {
            "type": "string",
            "description": "The title for the interview."
          },
          "status": {
            "description": "The status of the interview flow. One of: open, closed, archived. Archived flows have been deleted.",
            "type": "string",
            "enum": [
              "open",
              "closed",
              "archived"
            ]
          },
          "questions": {
            "type": "array",
            "description": "A list of questions to include in the interview.",
            "items": {
              "type": "string"
            }
          },
          "voice_id": {
            "default": "11labs-Kate",
            "enum": [
              "11labs-Anna",
              "openai-Onyx",
              "openai-Shimmer",
              "11labs-Anthony",
              "11labs-Kate",
              "11labs-Amy",
              "11labs-Rahul",
              "IPgYtHTNLjC7Bq7IPHrm",
              "UOIqAnmS11Reiei1Ytkc",
              "vUmLiNBm6MDcy1NUHaVr",
              "bhJUNIXWQQ94l8eI2VUf",
              "b3jcIbyC3BSnaRu8avEk",
              "xF681s0UeE04gsf0mVsJ",
              "uNsWM1StCcpydKYOjKyu",
              "BGEU6wFi2uNm6Kje1Yhk",
              "4kCDY3HJwvO7Zp3con83",
              null
            ],
            "description": "The voice ID to be used for the interview agent.",
            "nullable": true
          },
          "language": {
            "default": "en-US",
            "enum": [
              "en-US",
              "de-DE",
              "es-419",
              "hi-IN",
              "ja-JP",
              "pt-BR",
              "fr-FR",
              "zh-CN",
              "ko-KR",
              "vi-VN",
              "th-TH",
              "ar-AE",
              "no-NO",
              null
            ],
            "description": "The language of the interview flow.",
            "nullable": true
          },
          "company_logo_url": {
            "type": "string",
            "default": null,
            "description": "Optional URL for the company's logo. If not provided, the Ribbon logo will be shown.",
            "nullable": true
          },
          "additional_info": {
            "type": "string",
            "default": null,
            "description": "Extra contextual information relevant to the interview. This can include background details, facts, or data points that the AI may use to enrich its questions or answers. For example: research focus, demographics or situational context.",
            "nullable": true
          },
          "additional_instructions": {
            "type": "string",
            "default": null,
            "description": "Guidelines on how the AI should behave during the interview. For example, adjust tone formality, avoid certain topics, or follow specific communication rules.",
            "nullable": true
          },
          "interview_type": {
            "default": "general",
            "description": "The type of interview.",
            "type": "string",
            "enum": [
              "recruitment",
              "general",
              null
            ],
            "nullable": true
          },
          "is_video_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether the interview is video recorded or not.",
            "nullable": true
          },
          "is_doc_upload_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether candidates can add resumes or other documents during the interview or not.",
            "nullable": true
          },
          "redirect_url": {
            "type": "string",
            "default": null,
            "description": "The URL where interviewee will be redirected after completing the interview. Make sure you're using the full URL, including https://",
            "nullable": true
          },
          "webhook_url": {
            "type": "string",
            "default": null,
            "description": "The URL that will be called after interview processing is complete. The payload will contain interview_flow_id, interview_id, and status.",
            "nullable": true
          },
          "webhook_secret_key": {
            "type": "string",
            "default": null,
            "description": "A secret key used to sign webhook payloads. When set, an X-Ribbon-Signature header containing an HMAC-SHA256 signature will be included with each webhook request.",
            "nullable": true
          },
          "intro": {
            "type": "string",
            "default": null,
            "description": "Introductory text spoken by the AI interviewer at the beginning of the interview.",
            "nullable": true
          },
          "outro": {
            "type": "string",
            "default": null,
            "description": "Concluding text spoken by the AI interviewer at the end of the interview.",
            "nullable": true
          }
        },
        "required": [
          "interview_flow_id",
          "org_name",
          "questions",
          "status",
          "team_id",
          "title"
        ],
        "additionalProperties": false
      },
      "GetInterviewFlowsResponse": {
        "type": "object",
        "properties": {
          "interview_flows": {
            "type": "array",
            "description": "A list of interview flows.",
            "items": {
              "$ref": "#/components/schemas/InterviewFlow"
            }
          }
        },
        "required": [
          "interview_flows"
        ],
        "additionalProperties": false
      },
      "DeleteInterviewFlowResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indicates successful deletion of the interview flow."
          },
          "interview_flow_id": {
            "type": "string",
            "description": "The ID of the interview flow that was archived."
          },
          "status": {
            "type": "string",
            "description": "The new status of the interview flow after deletion."
          }
        },
        "required": [
          "interview_flow_id",
          "status",
          "success"
        ],
        "additionalProperties": false
      },
      "TeamMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the team member."
          },
          "email": {
            "type": "string",
            "default": null,
            "description": "The primary email address of the team member.",
            "nullable": true
          },
          "full_name": {
            "type": "string",
            "default": null,
            "description": "The full name of the team member (may be null).",
            "nullable": true
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      },
      "GetTeamMembersResponse": {
        "type": "object",
        "properties": {
          "team_members": {
            "type": "array",
            "description": "A list of team members.",
            "items": {
              "$ref": "#/components/schemas/TeamMember"
            }
          }
        },
        "required": [
          "team_members"
        ],
        "additionalProperties": false
      },
      "PostInterviewFlowsRequest": {
        "type": "object",
        "properties": {
          "org_name": {
            "type": "string",
            "description": "The name of the organization requesting the interview."
          },
          "title": {
            "type": "string",
            "description": "The title for the interview."
          },
          "questions": {
            "type": "array",
            "description": "A list of questions to include in the interview. Maximum 20 questions.",
            "items": {
              "type": "string"
            }
          },
          "voice_id": {
            "default": "11labs-Kate",
            "enum": [
              "11labs-Anna",
              "openai-Onyx",
              "openai-Shimmer",
              "11labs-Anthony",
              "11labs-Kate",
              "11labs-Amy",
              "11labs-Rahul",
              "IPgYtHTNLjC7Bq7IPHrm",
              "UOIqAnmS11Reiei1Ytkc",
              "vUmLiNBm6MDcy1NUHaVr",
              "bhJUNIXWQQ94l8eI2VUf",
              "b3jcIbyC3BSnaRu8avEk",
              "xF681s0UeE04gsf0mVsJ",
              "uNsWM1StCcpydKYOjKyu",
              "BGEU6wFi2uNm6Kje1Yhk",
              "4kCDY3HJwvO7Zp3con83",
              null
            ],
            "description": "The voice ID to be used for the interview agent.",
            "nullable": true
          },
          "language": {
            "default": "en-US",
            "enum": [
              "en-US",
              "de-DE",
              "es-419",
              "hi-IN",
              "ja-JP",
              "pt-BR",
              "fr-FR",
              "zh-CN",
              "ko-KR",
              "vi-VN",
              "th-TH",
              "ar-AE",
              "no-NO",
              null
            ],
            "description": "The language of the interview flow.",
            "nullable": true
          },
          "company_logo_url": {
            "type": "string",
            "default": null,
            "description": "Optional URL for the company's logo. If not provided, the Ribbon logo will be shown.",
            "nullable": true
          },
          "additional_info": {
            "type": "string",
            "default": null,
            "description": "Extra contextual information relevant to the interview. This can include background details, facts, or data points that the AI may use to enrich its questions or answers. For example: research focus, demographics or situational context.",
            "nullable": true
          },
          "additional_instructions": {
            "type": "string",
            "default": null,
            "description": "Guidelines on how the AI should behave during the interview. For example, adjust tone formality, avoid certain topics, or follow specific communication rules.",
            "nullable": true
          },
          "interview_type": {
            "default": "general",
            "description": "The type of interview.",
            "type": "string",
            "enum": [
              "recruitment",
              "general",
              null
            ],
            "nullable": true
          },
          "is_video_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether the interview is video recorded or not.",
            "nullable": true
          },
          "is_doc_upload_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether candidates can add resumes or other documents during the interview or not.",
            "nullable": true
          },
          "redirect_url": {
            "type": "string",
            "default": null,
            "description": "The URL where interviewee will be redirected after completing the interview. Make sure you're using the full URL, including https://",
            "nullable": true
          },
          "webhook_url": {
            "type": "string",
            "default": null,
            "description": "The URL that will be called after interview processing is complete. The payload will contain interview_flow_id, interview_id, and status.",
            "nullable": true
          },
          "webhook_secret_key": {
            "type": "string",
            "default": null,
            "description": "A secret key used to sign webhook payloads. When set, an X-Ribbon-Signature header containing an HMAC-SHA256 signature will be included with each webhook request.",
            "nullable": true
          },
          "intro": {
            "type": "string",
            "default": null,
            "description": "Introductory text spoken by the AI interviewer at the beginning of the interview.",
            "nullable": true
          },
          "outro": {
            "type": "string",
            "default": null,
            "description": "Concluding text spoken by the AI interviewer at the end of the interview.",
            "nullable": true
          },
          "team_id": {
            "type": "string",
            "default": null,
            "description": "The team ID to create the interview flow for. If not provided, defaults to the oldest team in the organization.",
            "nullable": true
          },
          "preamble_video_url": {
            "type": "string",
            "default": null,
            "description": "URL of an intro video to show candidates before the interview starts. The video will be downloaded and stored by Ribbon. Supported formats: MP4 (video/mp4), QuickTime (video/quicktime), WebM (video/webm). Maximum file size: 100 MB. The URL must be publicly accessible and served by a reasonably fast host \u2014 slow or unreliable servers may cause the request to time out. When provided, the intro video is automatically enabled for the interview flow.",
            "nullable": true
          }
        },
        "required": [
          "org_name",
          "questions",
          "title"
        ],
        "additionalProperties": false
      },
      "PostInterviewFlowsResponse": {
        "type": "object",
        "properties": {
          "interview_flow_id": {
            "type": "string",
            "description": "The ID of the interview flow."
          }
        },
        "required": [
          "interview_flow_id"
        ],
        "additionalProperties": false
      }
    },
    "responses": {
      "DEFAULT_ERROR": {
        "description": "Default error response",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "UNPROCESSABLE_ENTITY": {
        "description": "Unprocessable Entity",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/ping": {
      "get": {
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PingResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Ping",
        "description": "Send a dummy request."
      }
    },
    "/v1/teams": {
      "get": {
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetTeamsResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get teams",
        "description": "Retrieve all teams in the organization."
      }
    },
    "/v1/interviews": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "description": "The number of interviews to return.",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "required": false
          },
          {
            "in": "query",
            "name": "offset",
            "description": "The offset for the list of interviews.",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "required": false
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter interviews by status. Omit to return all (completed and incomplete).",
            "schema": {
              "default": null,
              "type": "string",
              "enum": [
                "incomplete",
                "completed",
                null
              ],
              "nullable": true
            },
            "required": false
          },
          {
            "in": "query",
            "name": "team_id",
            "description": "Filter interviews by team ID. If not provided, returns interviews for all teams in the organization.",
            "schema": {
              "type": "string",
              "default": null,
              "nullable": true
            },
            "required": false
          },
          {
            "in": "query",
            "name": "transcript",
            "description": "How much transcript data to return. 'full' (default) returns the transcript, word-level timestamps, and question mapping. 'text' returns the raw transcript only. 'none' omits all transcript fields.",
            "schema": {
              "default": "full",
              "type": "string",
              "enum": [
                "full",
                "text",
                "none"
              ]
            },
            "required": false
          }
        ],
        "responses": {
          "422": {
            "$ref": "#/components/responses/UNPROCESSABLE_ENTITY"
          },
          "403": {
            "description": "The team_id does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetInterviewsResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get interviews",
        "description": "Retrieve all interview sessions. If team_id is not provided, returns interviews for all teams in the organization."
      },
      "post": {
        "responses": {
          "422": {
            "description": "No interview flow found with provided interview_flow_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The interview flow found does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostInterviewResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostInterviewRequest"
              }
            }
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Post interview",
        "description": "Create an interview session. The interview will be created in the same team as the interview flow."
      }
    },
    "/v1/interviews/{interview_id}": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "transcript",
            "description": "How much transcript data to return. 'full' (default) returns the transcript, word-level timestamps, and question mapping. 'text' returns the raw transcript only. 'none' omits all transcript fields.",
            "schema": {
              "default": "full",
              "type": "string",
              "enum": [
                "full",
                "text",
                "none"
              ]
            },
            "required": false
          },
          {
            "in": "path",
            "name": "interview_id",
            "description": "The ID of the interview.",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "422": {
            "description": "No interview found with provided interview_session_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The interview found does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Interview"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get interview",
        "description": "Retrieve a specific interview session."
      },
      "parameters": [
        {
          "in": "path",
          "name": "interview_id",
          "required": true,
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "delete": {
        "parameters": [
          {
            "in": "path",
            "name": "interview_id",
            "description": "The ID of the interview whose recordings should be deleted.",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "422": {
            "description": "No interview found with provided interview_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error occurred while deleting interview recordings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The interview found does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteInterviewResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "summary": "Revoke Access to Interview Recordings",
        "description": "Revoke access to video and audio recordings for an interview.",
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/v1/interview-flows": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "description": "The number of interview flows to return.",
            "schema": {
              "type": "integer",
              "default": 100
            },
            "required": false
          },
          {
            "in": "query",
            "name": "offset",
            "description": "The offset for the list of interview flows.",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "required": false
          },
          {
            "in": "query",
            "name": "team_id",
            "description": "Filter interview flows by team ID. If not provided, returns interview flows for all teams in the organization.",
            "schema": {
              "type": "string",
              "default": null,
              "nullable": true
            },
            "required": false
          }
        ],
        "responses": {
          "422": {
            "$ref": "#/components/responses/UNPROCESSABLE_ENTITY"
          },
          "403": {
            "description": "The team_id does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetInterviewFlowsResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get interview flows",
        "description": "Retrieve all interview flows. If team_id is not provided, returns interview flows for all teams in the organization."
      },
      "post": {
        "responses": {
          "422": {
            "description": "Unable to use file provided for company_logo_url or preamble_video_url. Or no teams found in organization. Or more than 20 questions provided.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The team_id does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostInterviewFlowsResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostInterviewFlowsRequest"
              }
            }
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Post interview flow",
        "description": "Create an interview flow. If team_id is not provided, defaults to the oldest team in the organization."
      }
    },
    "/v1/interview-flows/{interview_flow_id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "interview_flow_id",
            "description": "The ID of the interview flow.",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "422": {
            "description": "No interview flow found with provided interview_flow_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The interview flow found does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InterviewFlow"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get interview flow",
        "description": "Retrieve a specific interview flow."
      },
      "parameters": [
        {
          "in": "path",
          "name": "interview_flow_id",
          "required": true,
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "delete": {
        "parameters": [
          {
            "in": "path",
            "name": "interview_flow_id",
            "description": "The ID of the interview flow to delete.",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "422": {
            "description": "No interview flow found with provided interview_flow_id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The interview flow found does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteInterviewFlowResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Delete interview flow",
        "description": "Delete an interview flow."
      }
    },
    "/v1/team-members": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "team_id",
            "description": "Filter team members by team ID. If not provided, returns team members for all teams in the organization.",
            "schema": {
              "type": "string",
              "default": null,
              "nullable": true
            },
            "required": false
          }
        ],
        "responses": {
          "422": {
            "$ref": "#/components/responses/UNPROCESSABLE_ENTITY"
          },
          "403": {
            "description": "The team_id does not belong to authenticated organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetTeamMembersResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "Ribbon Public API"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Get team members",
        "description": "Retrieve all team members in the organization. Use the returned id as assigned_recruiter_id when creating an interview. If team_id is not provided, returns members for all teams in the organization."
      }
    },
    "/ping": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/ping-protected": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/new-user": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/submit-feedback": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/send-test-global-webhook": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/confirm-verification": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/setup-stripe-checkout-session": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-stripe-subscription-portal": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/stripe-connect-webhook": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/stripe-account-webhook": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/new-document": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/update-user-chat-context": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/on-document-update": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/on-onboarding-update": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/create-interview-flow": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/duplicate-interview-flow": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/upsert-recruiting-plan": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-client-secret": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/kombo-webhook": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/update-interview-flow": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/update-interview-flow-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/save-question": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/delete-question": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-ats-integration-jobs-and-stages-list": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-ats-integration-connection-link": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/force-ats-sync": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/delete-integration": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-ats-integrations-list": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/send-invitation-to-join-recruiting-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/respond-to-invitation-to-join-recruiting-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/exclude-from-recruiting-org": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/remove-from-recruiting-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/leave-recruiting-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/delete-recruiting-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-recruiter-plan-details": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-recruit-catalog-pricing": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/extract-interview-flow-from-free-text": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/extract-interview-flow-from-job-post-url": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/add-pipeline-members-from-csv": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/send-candidate-outreach-from-csv": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/send-candidate-outreach-from-emails": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/save-custom-scores": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/create-custom-scoring-from-file": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-company-details-from-website": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/create-transcript-highlight-note": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/find-importable-jobs-from-ats": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/import-select-jobs-from-ats": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-connection-details": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/get-demo-connection-details": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/livekit-webhook": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/submit-request-to-ribbon-team": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/submit-accommodation-request": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/export-candidates-csv": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/update-candidate-status": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/record-integrity-monitoring-vote": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/update-assigned-recruiter": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/mixpanel-pageviews": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/.well-known/oauth-authorization-server": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/oauth/register": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/oauth/authorize": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/oauth/consent": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/oauth/token": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/oauth/revoke": {
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    },
    "/mcp/ats": {
      "get": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      },
      "post": {
        "responses": {
          "default": {
            "$ref": "#/components/responses/DEFAULT_ERROR"
          }
        },
        "tags": [
          "private_routes"
        ]
      }
    }
  },
  "tags": [
    {
      "name": "Ribbon Public API",
      "description": ""
    },
    {
      "name": "private_routes",
      "description": ""
    }
  ],
  "openapi": "3.0.2"
}