{
  "openapi": "3.1.1",
  "info": {
    "title": "Twitch Token Generator v2 API",
    "version": "2",
    "description": "Public v2 API for Twitch Token Generator. Workflow credentials are returned once after authorization. Examples use placeholder credentials.",
    "contact": {
      "url": "https://github.com/swiftyspiffy"
    }
  },
  "servers": [
    {
      "url": "https://twitchtokengenerator.com"
    }
  ],
  "paths": {
    "/api/v2/scopes": {
      "get": {
        "operationId": "listScopes",
        "x-ttg-order": 1,
        "summary": "Available Token Scopes",
        "x-ttg-summary-key": "ui.available_token_scopes",
        "description": "Read current scope IDs, names, descriptions, and availability. This request needs no credentials.",
        "x-ttg-description-key": "docs.op.scopes",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Scopes"
                },
                "example": {
                  "success": true,
                  "scopes": [
                    {
                      "id": 28,
                      "api_set": "helix",
                      "scope": "chat:read",
                      "description": "View live Stream Chat and Rooms messages.",
                      "secret": false,
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "x-ttg-description-key": "docs.status.unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "service temporarily unavailable"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "include_sensitive",
            "in": "query",
            "required": false,
            "description": "Include scopes marked sensitive in the catalog.",
            "x-ttg-description-key": "docs.param.include_sensitive",
            "schema": {
              "type": "boolean"
            },
            "example": false
          }
        ]
      }
    },
    "/api/v2/workflows": {
      "post": {
        "operationId": "createWorkflow",
        "x-ttg-order": 2,
        "summary": "Create an authorization workflow",
        "x-ttg-summary-key": "docs.create_workflow",
        "description": "Creates a 24-hour workflow under TTG’s shared Twitch application. The response separates the public authorization URL from the private retrieval key.",
        "x-ttg-description-key": "docs.op.create_workflow",
        "responses": {
          "201": {
            "description": "Created",
            "x-ttg-description-key": "docs.status.created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowCreated"
                },
                "example": {
                  "success": true,
                  "id": "example0000000000000",
                  "retrieval_key": "example000000000000000000000000000000000",
                  "authorization_url": "https://twitchtokengenerator.com/api/example0000000000000",
                  "status_url": "https://twitchtokengenerator.com/api/v2/workflows/example0000000000000",
                  "expires_at": "2030-01-01T12:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "500": {
            "description": "The request could not be processed",
            "x-ttg-description-key": "docs.status.server_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "unable to process request"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 500,
                    "x-ttg-max-bytes": 500,
                    "description": "Application name, up to 500 UTF-8 bytes.",
                    "x-ttg-description-key": "docs.param.title"
                  },
                  "scope_ids": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1,
                      "format": "int64"
                    },
                    "description": "Numeric IDs from the scope catalog. Choose active scopes; at most 150 distinct scopes.",
                    "x-ttg-description-key": "docs.param.scope_ids",
                    "x-ttg-max-distinct": 150
                  },
                  "redirect_url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Optional absolute HTTP or HTTPS destination after authorization. URL credentials are not allowed.",
                    "x-ttg-description-key": "docs.param.redirect_url",
                    "x-ttg-max-bytes": 2048
                  },
                  "is_ai": {
                    "type": "boolean",
                    "description": "Mark a workflow as AI-assisted.",
                    "x-ttg-description-key": "docs.param.is_ai"
                  },
                  "ai_agent": {
                    "type": "string",
                    "maxLength": 64,
                    "x-ttg-max-bytes": 64,
                    "x-ttg-no-controls": true,
                    "description": "Optional AI client name, up to 64 UTF-8 bytes without control characters. This is attribution, not authentication.",
                    "x-ttg-description-key": "docs.param.ai_agent"
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "title": "Example integration",
                "scope_ids": [
                  28,
                  29
                ]
              }
            }
          }
        }
      }
    },
    "/api/v2/workflows/{id}": {
      "get": {
        "operationId": "getWorkflow",
        "x-ttg-order": 3,
        "summary": "Retrieve workflow credentials",
        "x-ttg-summary-key": "docs.get_workflow",
        "description": "Returns credentials once after authorization. Send the workflow retrieval key as a Bearer credential. A successful read consumes the stored credentials.",
        "x-ttg-description-key": "docs.op.get_workflow",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowCredentials"
                },
                "example": {
                  "success": true,
                  "status": "authorized",
                  "access_token": "EXAMPLE_ACCESS_TOKEN",
                  "refresh_token": "EXAMPLE_REFRESH_TOKEN",
                  "client_id": "EXAMPLE_CLIENT_ID",
                  "username": "exampleuser",
                  "user_id": "123456789",
                  "scopes": [
                    "chat:read",
                    "chat:edit"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Invalid token or retrieval key",
            "x-ttg-description-key": "docs.status.unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid retrieval key"
                }
              }
            }
          },
          "404": {
            "description": "Workflow not found",
            "x-ttg-description-key": "docs.status.not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "workflow not found"
                }
              }
            }
          },
          "410": {
            "description": "Credentials expired or already retrieved",
            "x-ttg-description-key": "docs.status.gone",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "workflow credentials are no longer available",
                  "status": "expired"
                }
              }
            }
          },
          "500": {
            "description": "The request could not be processed",
            "x-ttg-description-key": "docs.status.server_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "unable to process request"
                }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "x-ttg-description-key": "docs.status.unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "service temporarily unavailable"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          },
          "202": {
            "description": "Authorization is still pending",
            "x-ttg-description-key": "docs.status.pending",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pending"
                },
                "example": {
                  "success": false,
                  "status": "pending",
                  "expires_at": "2030-01-01T12:00:00Z"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The workflow ID returned when it was created.",
            "x-ttg-description-key": "docs.param.id",
            "schema": {
              "type": "string",
              "minLength": 20,
              "maxLength": 20,
              "pattern": "^[a-z0-9]{20}$"
            },
            "example": "example0000000000000"
          }
        ],
        "security": [
          {
            "workflowRetrieval": []
          }
        ]
      }
    },
    "/api/v2/ai/workflows/create": {
      "get": {
        "operationId": "createAIWorkflow",
        "x-ttg-order": 4,
        "summary": "Create a fetch-only AI workflow",
        "x-ttg-summary-key": "docs.create_ai",
        "description": "GET alternative for fetch-only clients. Creates a workflow using scope names and returns a private retrieval URL. The JSON response is served as text/plain.",
        "x-ttg-description-key": "docs.op.create_ai",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/AIWorkflowCreated"
                },
                "example": {
                  "success": true,
                  "id": "example0000000000000",
                  "authorization_url": "https://twitchtokengenerator.com/api/example0000000000000",
                  "retrieval_url": "https://twitchtokengenerator.com/api/v2/ai/workflows/example0000000000000/example000000000000000000000000000000000",
                  "expires_at": "2030-01-01T12:00:00Z",
                  "retrieval_notice": "Keep retrieval_url private: it grants one-time access to the generated credentials. Give the user only authorization_url. Retrieve after they finish authorizing."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "500": {
            "description": "The request could not be processed",
            "x-ttg-description-key": "docs.status.server_error",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "unable to process request"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "scopes",
            "in": "query",
            "required": true,
            "description": "Comma-separated scope names. The parameter must be present; an empty value requests no scopes.",
            "x-ttg-description-key": "docs.param.scopes",
            "schema": {
              "type": "string",
              "maxLength": 4096,
              "x-ttg-max-bytes": 4096
            },
            "example": "chat:read,chat:edit",
            "allowEmptyValue": true
          },
          {
            "name": "ai_agent",
            "in": "query",
            "required": false,
            "description": "Optional AI client name, up to 64 UTF-8 bytes without control characters. This is attribution, not authentication.",
            "x-ttg-description-key": "docs.param.ai_agent",
            "schema": {
              "type": "string",
              "maxLength": 64,
              "x-ttg-max-bytes": 64,
              "x-ttg-no-controls": true
            },
            "example": ""
          },
          {
            "name": "nonce",
            "in": "query",
            "required": false,
            "description": "Optional cache-busting value, up to 128 UTF-8 bytes. It is not an idempotency key.",
            "x-ttg-description-key": "docs.param.nonce",
            "schema": {
              "type": "string",
              "maxLength": 128,
              "x-ttg-max-bytes": 128
            },
            "example": ""
          }
        ]
      }
    },
    "/api/v2/ai/workflows/{id}/{key}": {
      "get": {
        "operationId": "getAIWorkflow",
        "x-ttg-order": 5,
        "summary": "Retrieve fetch-only AI credentials",
        "x-ttg-summary-key": "docs.get_ai",
        "description": "GET alternative with the retrieval key in the URL. The JSON response is served as text/plain. A successful read consumes the stored credentials.",
        "x-ttg-description-key": "docs.op.get_ai",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowCredentials"
                },
                "example": {
                  "success": true,
                  "status": "authorized",
                  "access_token": "EXAMPLE_ACCESS_TOKEN",
                  "refresh_token": "EXAMPLE_REFRESH_TOKEN",
                  "client_id": "EXAMPLE_CLIENT_ID",
                  "username": "exampleuser",
                  "user_id": "123456789",
                  "scopes": [
                    "chat:read",
                    "chat:edit"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Invalid token or retrieval key",
            "x-ttg-description-key": "docs.status.unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid retrieval key"
                }
              }
            }
          },
          "404": {
            "description": "Workflow not found",
            "x-ttg-description-key": "docs.status.not_found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "workflow not found"
                }
              }
            }
          },
          "410": {
            "description": "Credentials expired or already retrieved",
            "x-ttg-description-key": "docs.status.gone",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "workflow credentials are no longer available",
                  "status": "expired"
                }
              }
            }
          },
          "500": {
            "description": "The request could not be processed",
            "x-ttg-description-key": "docs.status.server_error",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "unable to process request"
                }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "x-ttg-description-key": "docs.status.unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "service temporarily unavailable"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          },
          "202": {
            "description": "Authorization is still pending",
            "x-ttg-description-key": "docs.status.pending",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Pending"
                },
                "example": {
                  "success": false,
                  "status": "pending",
                  "expires_at": "2030-01-01T12:00:00Z"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The workflow ID returned when it was created.",
            "x-ttg-description-key": "docs.param.id",
            "schema": {
              "type": "string",
              "minLength": 20,
              "maxLength": 20,
              "pattern": "^[a-z0-9]{20}$"
            },
            "example": "example0000000000000"
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "The private retrieval key returned when the workflow was created. Keep it out of public links.",
            "x-ttg-description-key": "docs.param.key",
            "schema": {
              "type": "string",
              "minLength": 40,
              "maxLength": 40,
              "pattern": "^[a-z0-9]{40}$",
              "format": "password"
            },
            "example": "example000000000000000000000000000000000"
          }
        ]
      }
    },
    "/api/v2/tokens/refresh": {
      "post": {
        "operationId": "refreshToken",
        "x-ttg-order": 6,
        "summary": "Refresh Access Token",
        "x-ttg-summary-key": "ui.refresh_access_token",
        "description": "Renews an access token using a refresh token. Supply both client_id and client_secret when refreshing a token from your own Twitch application.",
        "x-ttg-description-key": "docs.op.refresh",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefreshedTokens"
                },
                "example": {
                  "success": true,
                  "access_token": "EXAMPLE_ACCESS_TOKEN",
                  "refresh_token": "EXAMPLE_REFRESH_TOKEN",
                  "client_id": "EXAMPLE_CLIENT_ID",
                  "expires_in": 3600,
                  "scopes": [
                    "chat:read",
                    "chat:edit"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "502": {
            "description": "Twitch request failed",
            "x-ttg-description-key": "docs.status.bad_gateway",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "Twitch request failed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refresh_token": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096,
                    "format": "password",
                    "description": "The latest refresh token for the account and Twitch application.",
                    "x-ttg-description-key": "docs.param.refresh_token",
                    "x-ttg-max-bytes": 4096
                  },
                  "client_id": {
                    "type": "string",
                    "description": "Twitch application client ID. Omit it to use TTG’s shared application.",
                    "x-ttg-description-key": "docs.param.client_id"
                  },
                  "client_secret": {
                    "type": "string",
                    "format": "password",
                    "description": "Twitch application client secret. For refresh requests, provide it together with client_id.",
                    "x-ttg-description-key": "docs.param.client_secret"
                  }
                },
                "required": [
                  "refresh_token"
                ],
                "additionalProperties": false
              },
              "example": {
                "refresh_token": "EXAMPLE_REFRESH_TOKEN"
              }
            }
          }
        }
      }
    },
    "/api/v2/tokens/revoke": {
      "post": {
        "operationId": "revokeToken",
        "x-ttg-order": 7,
        "summary": "Revoke Your Access Token",
        "x-ttg-summary-key": "ui.revoke_your_access_token",
        "description": "Invalidates the supplied access token. Supply its application’s client_id if it differs from TTG’s shared application.",
        "x-ttg-description-key": "docs.op.revoke",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "502": {
            "description": "Twitch request failed",
            "x-ttg-description-key": "docs.status.bad_gateway",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "Twitch request failed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "access_token": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096,
                    "format": "password",
                    "description": "The Twitch access token to inspect or revoke, without an oauth: prefix.",
                    "x-ttg-description-key": "docs.param.access_token",
                    "x-ttg-max-bytes": 4096
                  },
                  "client_id": {
                    "type": "string",
                    "description": "Twitch application client ID. Omit it to use TTG’s shared application.",
                    "x-ttg-description-key": "docs.param.client_id"
                  }
                },
                "required": [
                  "access_token"
                ],
                "additionalProperties": false
              },
              "example": {
                "access_token": "EXAMPLE_ACCESS_TOKEN"
              }
            }
          }
        }
      }
    },
    "/api/v2/tokens/validate": {
      "post": {
        "operationId": "validateToken",
        "x-ttg-order": 8,
        "summary": "Validate a token",
        "x-ttg-summary-key": "ui.validate_a_token",
        "description": "Inspects the token’s account, application, granted permissions, and remaining lifetime.",
        "x-ttg-description-key": "docs.op.validate",
        "responses": {
          "200": {
            "description": "Successful response",
            "x-ttg-description-key": "docs.status.ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Validation"
                },
                "example": {
                  "success": true,
                  "username": "exampleuser",
                  "user_id": "123456789",
                  "client_id": "EXAMPLE_CLIENT_ID",
                  "expires_in": 3600,
                  "scopes": [
                    "chat:read"
                  ],
                  "scope_details": [
                    {
                      "id": 28,
                      "api_set": "helix",
                      "scope": "chat:read",
                      "description": "View live Stream Chat and Rooms messages.",
                      "secret": false,
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token or retrieval key",
            "x-ttg-description-key": "docs.status.unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid retrieval key"
                }
              }
            }
          },
          "502": {
            "description": "Twitch request failed",
            "x-ttg-description-key": "docs.status.bad_gateway",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "Twitch request failed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "access_token": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096,
                    "format": "password",
                    "description": "The Twitch access token to inspect or revoke, without an oauth: prefix.",
                    "x-ttg-description-key": "docs.param.access_token",
                    "x-ttg-max-bytes": 4096
                  }
                },
                "required": [
                  "access_token"
                ],
                "additionalProperties": false
              },
              "example": {
                "access_token": "EXAMPLE_ACCESS_TOKEN"
              }
            }
          }
        }
      }
    },
    "/api/v2/quick-links": {
      "post": {
        "operationId": "createQuickLink",
        "x-ttg-order": 9,
        "summary": "Quick Link Generator",
        "x-ttg-summary-key": "ui.quick_link_generator",
        "description": "Creates a reusable link with selected scope IDs. auth=stay opens the generator; auth=authorize starts Twitch authorization.",
        "x-ttg-description-key": "docs.op.quick_link",
        "responses": {
          "201": {
            "description": "Created",
            "x-ttg-description-key": "docs.status.created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkCreated"
                },
                "example": {
                  "success": true,
                  "id": "example000",
                  "url": "https://twitchtokengenerator.com/quick/example000"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "500": {
            "description": "The request could not be processed",
            "x-ttg-description-key": "docs.status.server_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "unable to process request"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scope_ids": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1,
                      "format": "int64"
                    },
                    "description": "Numeric IDs from the scope catalog. Choose active scopes; at most 150 distinct scopes.",
                    "x-ttg-description-key": "docs.param.scope_ids",
                    "x-ttg-max-distinct": 150
                  },
                  "auth": {
                    "type": "string",
                    "enum": [
                      "stay",
                      "authorize",
                      "auth_auth"
                    ],
                    "default": "stay",
                    "description": "stay opens the generator. authorize and the compatibility alias auth_auth begin authorization immediately.",
                    "x-ttg-description-key": "docs.param.auth"
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "scope_ids": [
                  28,
                  29
                ],
                "auth": "stay"
              }
            }
          }
        }
      }
    },
    "/api/v2/token-requests": {
      "post": {
        "operationId": "createTokenRequest",
        "x-ttg-order": 10,
        "summary": "Request Token From User",
        "x-ttg-summary-key": "ui.request_token_from_user",
        "description": "Creates an authorization request link. After the account owner completes authorization, credentials are sent to my_email.",
        "x-ttg-description-key": "docs.op.token_request",
        "responses": {
          "201": {
            "description": "Created",
            "x-ttg-description-key": "docs.status.created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkCreated"
                },
                "example": {
                  "success": true,
                  "id": "example-request",
                  "url": "https://twitchtokengenerator.com/request/example-request"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "x-ttg-description-key": "docs.status.bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "invalid request"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "x-ttg-description-key": "docs.status.rate_limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "success": false,
                  "message": "rate limit exceeded"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scope_ids": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1,
                      "format": "int64"
                    },
                    "description": "Numeric IDs from the scope catalog. Choose active scopes; at most 150 distinct scopes.",
                    "x-ttg-description-key": "docs.param.scope_ids",
                    "x-ttg-max-distinct": 150
                  },
                  "my_name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128,
                    "x-ttg-max-bytes": 128,
                    "description": "Requester name, up to 128 UTF-8 bytes.",
                    "x-ttg-description-key": "docs.param.my_name"
                  },
                  "my_email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 254,
                    "description": "Email address that receives credentials after the request is completed.",
                    "x-ttg-description-key": "docs.param.my_email"
                  }
                },
                "required": [
                  "my_name",
                  "my_email"
                ],
                "additionalProperties": false
              },
              "example": {
                "scope_ids": [
                  28,
                  29
                ],
                "my_name": "Example developer",
                "my_email": "developer@example.com"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "workflowRetrieval": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Workflow retrieval key",
        "description": "The private retrieval key returned when the workflow was created. Keep it out of public links."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "message"
        ],
        "additionalProperties": true
      },
      "Scope": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 0
          },
          "api_set": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "secret": {
            "type": "boolean"
          },
          "active": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "api_set",
          "scope",
          "description",
          "secret",
          "active"
        ],
        "additionalProperties": true
      },
      "Scopes": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          }
        },
        "required": [
          "success",
          "scopes"
        ],
        "additionalProperties": true
      },
      "WorkflowCreated": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "retrieval_key": {
            "type": "string"
          },
          "authorization_url": {
            "type": "string"
          },
          "status_url": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "id",
          "retrieval_key",
          "authorization_url",
          "status_url",
          "expires_at"
        ],
        "additionalProperties": true
      },
      "WorkflowCredentials": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "client_id": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "success",
          "status",
          "access_token",
          "refresh_token",
          "client_id",
          "username",
          "user_id",
          "scopes"
        ],
        "additionalProperties": true
      },
      "Pending": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "const": "pending"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "status",
          "expires_at"
        ],
        "additionalProperties": true
      },
      "RefreshedTokens": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "client_id": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer",
            "minimum": 0
          },
          "scopes": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "success",
          "access_token",
          "refresh_token",
          "client_id",
          "expires_in",
          "scopes"
        ],
        "additionalProperties": true
      },
      "Success": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "required": [
          "success"
        ],
        "additionalProperties": true
      },
      "Validation": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "username": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "client_id": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer",
            "minimum": 0
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scope_details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          }
        },
        "required": [
          "success",
          "username",
          "user_id",
          "client_id",
          "expires_in",
          "scopes",
          "scope_details"
        ],
        "additionalProperties": true
      },
      "LinkCreated": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "success",
          "id",
          "url"
        ],
        "additionalProperties": true
      },
      "AIWorkflowCreated": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "authorization_url": {
            "type": "string"
          },
          "retrieval_url": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "retrieval_notice": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "id",
          "authorization_url",
          "retrieval_url",
          "expires_at",
          "retrieval_notice"
        ],
        "additionalProperties": true
      }
    }
  }
}
