{
  "openapi": "3.1.0",
  "info": {
    "title": "SupaCrawlX API",
    "version": "1.0.0",
    "description": "Extract transcripts, metadata, and structured data from YouTube, TikTok, Instagram, X (Twitter), Facebook, and any web URL. All endpoints authenticate with an API key sent in the `x-api-key` header. Credit usage is returned in the `X-Credits-Used` and `X-Credits-Remaining` response headers.",
    "contact": { "name": "SupaCrawlX Support", "url": "https://supacrawlx.com/contact" }
  },
  "servers": [{ "url": "https://api.supacrawlx.com", "description": "Production" }],
  "security": [{ "ApiKeyAuth": [] }],
  "tags": [
    { "name": "Transcripts", "description": "Transcript extraction across platforms" },
    { "name": "YouTube", "description": "YouTube search, channel, playlist, and batch endpoints" },
    { "name": "Web", "description": "Web scraping, crawling, and sitemap mapping" },
    { "name": "Analysis", "description": "AI-powered video analysis and metadata" },
    { "name": "Jobs", "description": "Asynchronous job status" },
    { "name": "Account", "description": "Account and credit information" }
  ],
  "paths": {
    "/v1/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "Universal transcript",
        "description": "Auto-detects the platform from the URL and returns a transcript. Cost: 1 credit (native captions) or 2 credits/minute (AI-generated).",
        "parameters": [
          { "$ref": "#/components/parameters/Url" },
          { "$ref": "#/components/parameters/Lang" },
          { "$ref": "#/components/parameters/Translate" },
          { "$ref": "#/components/parameters/Timestamps" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Transcript" },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/metadata": {
      "get": {
        "tags": ["Analysis"],
        "summary": "Universal metadata",
        "description": "Extracts metadata (title, description, author, counts, thumbnails) from a YouTube, TikTok, Instagram, X, Facebook, or web URL. Cost: 1 credit.",
        "parameters": [{ "$ref": "#/components/parameters/Url" }],
        "responses": {
          "200": { "description": "Metadata object", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
          "400": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/youtube/transcript": {
      "get": {
        "tags": ["Transcripts", "YouTube"],
        "summary": "YouTube transcript",
        "description": "Returns a YouTube transcript by `url` or `video_id`, with AI fallback when no captions exist. Cost: 1 credit (native) or 2 credits/minute (AI).",
        "parameters": [
          { "name": "url", "in": "query", "schema": { "type": "string", "format": "uri" }, "description": "YouTube video URL (or use video_id)." },
          { "name": "video_id", "in": "query", "schema": { "type": "string" }, "description": "YouTube video ID (or use url)." },
          { "$ref": "#/components/parameters/Lang" },
          { "$ref": "#/components/parameters/Translate" },
          { "$ref": "#/components/parameters/Timestamps" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Transcript" },
          "400": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/youtube/transcript/batch": {
      "post": {
        "tags": ["Transcripts", "YouTube"],
        "summary": "Batch YouTube transcripts (Pro+)",
        "description": "Extract transcripts for up to 50 URLs in a single request. Requires a Pro plan or higher.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object",
            "required": ["urls"],
            "properties": {
              "urls": { "type": "array", "items": { "type": "string", "format": "uri" }, "minItems": 1, "maxItems": 50 },
              "lang": { "type": "string", "description": "Optional language code (e.g. en, es)." }
            }
          } } }
        },
        "responses": {
          "200": { "description": "Per-URL results", "content": { "application/json": { "schema": { "type": "object", "properties": {
            "results": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
            "creditsUsed": { "type": "integer" }
          } } } } },
          "402": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/youtube/transcript/translate": {
      "post": {
        "tags": ["Transcripts", "YouTube"],
        "summary": "Translate transcript (Pro+)",
        "description": "Extracts a YouTube transcript and translates it to the target language. Cost: 30 credits/minute. Requires a Pro plan or higher.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object",
            "required": ["url", "targetLang"],
            "properties": {
              "url": { "type": "string", "format": "uri" },
              "targetLang": { "type": "string", "description": "Target language code (e.g. es, fr)." }
            }
          } } }
        },
        "responses": { "200": { "$ref": "#/components/responses/Transcript" }, "402": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/youtube/search": {
      "get": {
        "tags": ["YouTube"],
        "summary": "Search YouTube",
        "description": "Search YouTube for videos, channels, and playlists with filtering and pagination. Returns up to 5,000 results via automatic pagination. Cost: 1 credit per page (50 results) fetched.",
        "parameters": [
          { "name": "query", "in": "query", "required": true, "schema": { "type": "string", "maxLength": 500 } },
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["video", "channel", "playlist", "all"], "default": "all" } },
          { "name": "duration", "in": "query", "schema": { "type": "string", "enum": ["short", "medium", "long"] }, "description": "Video duration filter (videos only)." },
          { "name": "sortBy", "in": "query", "schema": { "type": "string", "enum": ["relevance", "date", "viewCount", "rating"], "default": "relevance" } },
          { "name": "definition", "in": "query", "schema": { "type": "string", "enum": ["any", "high", "standard"], "default": "any" }, "description": "Filter by video definition (high = HD/4K)." },
          { "name": "caption", "in": "query", "schema": { "type": "string", "enum": ["any", "closedCaption", "none"], "default": "any" }, "description": "Filter by subtitle/caption availability." },
          { "name": "publishedAfter", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Only results published after this RFC 3339 timestamp." },
          { "name": "publishedBefore", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Only results published before this RFC 3339 timestamp." },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 5000, "default": 20 }, "description": "Maximum results to return; pages are fetched automatically." },
          { "name": "pageToken", "in": "query", "schema": { "type": "string" }, "description": "Resume from a specific page (advanced)." }
        ],
        "responses": {
          "200": { "description": "Search results", "content": { "application/json": { "schema": { "type": "object", "properties": {
            "query": { "type": "string" },
            "results": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
            "nextPageToken": { "type": ["string", "null"] },
            "totalResults": { "type": ["integer", "null"] }
          } } } } },
          "503": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/youtube/channel": {
      "get": {
        "tags": ["YouTube"],
        "summary": "Channel info",
        "description": "Get channel details by ID. Cost: 1 credit.",
        "parameters": [{ "name": "id", "in": "query", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Channel object", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/youtube/channel/videos": {
      "get": {
        "tags": ["YouTube"],
        "summary": "Channel videos",
        "description": "List a channel's videos, shorts, and live streams. Cost: 1 credit.",
        "parameters": [
          { "name": "id", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 5000, "default": 30 } },
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["all", "video", "short", "live"], "default": "all" } }
        ],
        "responses": { "200": { "description": "Video list", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/youtube/playlist": {
      "get": {
        "tags": ["YouTube"],
        "summary": "Playlist info",
        "description": "Get playlist details by ID. Cost: 1 credit.",
        "parameters": [{ "name": "id", "in": "query", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Playlist object", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/youtube/playlist/videos": {
      "get": {
        "tags": ["YouTube"],
        "summary": "Playlist videos",
        "description": "List videos in a playlist. Cost: 1 credit.",
        "parameters": [
          { "name": "id", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 5000, "default": 100 } }
        ],
        "responses": { "200": { "description": "Video list", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/youtube/video/batch": {
      "post": {
        "tags": ["YouTube"],
        "summary": "Batch video metadata (Pro+)",
        "description": "Fetch metadata for up to 50 videos by IDs, playlist, or channel. Requires a Pro plan or higher.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": {
          "type": "object",
          "properties": {
            "videoIds": { "type": "array", "items": { "type": "string" }, "maxItems": 50 },
            "playlistId": { "type": "string" },
            "channelId": { "type": "string" },
            "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
          }
        } } } },
        "responses": { "200": { "description": "Video metadata list", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/tiktok/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "TikTok transcript",
        "description": "AI-powered transcript for a TikTok video. Cost: 2 credits/minute.",
        "parameters": [{ "$ref": "#/components/parameters/Url" }, { "$ref": "#/components/parameters/Lang" }, { "$ref": "#/components/parameters/Timestamps" }],
        "responses": { "200": { "$ref": "#/components/responses/Transcript" }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/instagram/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "Instagram transcript",
        "description": "AI-powered transcript for an Instagram Reel. Cost: 2 credits/minute.",
        "parameters": [{ "$ref": "#/components/parameters/Url" }, { "$ref": "#/components/parameters/Lang" }, { "$ref": "#/components/parameters/Timestamps" }],
        "responses": { "200": { "$ref": "#/components/responses/Transcript" }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/twitter/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "X (Twitter) transcript",
        "description": "AI-powered transcript for an X / Twitter video. Cost: 2 credits/minute.",
        "parameters": [{ "$ref": "#/components/parameters/Url" }, { "$ref": "#/components/parameters/Lang" }, { "$ref": "#/components/parameters/Timestamps" }],
        "responses": { "200": { "$ref": "#/components/responses/Transcript" }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/facebook/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "Facebook transcript",
        "description": "AI-powered transcript for a Facebook video. Cost: 2 credits/minute.",
        "parameters": [{ "$ref": "#/components/parameters/Url" }, { "$ref": "#/components/parameters/Lang" }, { "$ref": "#/components/parameters/Timestamps" }],
        "responses": { "200": { "$ref": "#/components/responses/Transcript" }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/video/transcript": {
      "get": {
        "tags": ["Transcripts"],
        "summary": "Generic video transcript",
        "description": "Transcript for a direct video file URL or any supported platform. Cost: 1 credit (native) or 2 credits/minute (AI).",
        "parameters": [{ "$ref": "#/components/parameters/Url" }, { "$ref": "#/components/parameters/Lang" }, { "$ref": "#/components/parameters/Timestamps" }],
        "responses": { "200": { "$ref": "#/components/responses/Transcript" } }
      }
    },
    "/v1/video/analysis": {
      "post": {
        "tags": ["Analysis"],
        "summary": "AI video analysis (Pro+)",
        "description": "Extract structured data from a video using a natural-language prompt and/or JSON schema. Cost: 5 credits. Requires a Pro plan or higher.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": {
          "type": "object",
          "required": ["url"],
          "properties": {
            "url": { "type": "string", "format": "uri" },
            "prompt": { "type": "string", "maxLength": 1000 },
            "schema": { "type": "object", "additionalProperties": true, "description": "JSON Schema describing the desired output shape." }
          }
        } } } },
        "responses": { "200": { "description": "Structured analysis result", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "402": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/web/scrape": {
      "get": {
        "tags": ["Web"],
        "summary": "Scrape a web page",
        "description": "Returns clean page content as Markdown, plain text, or HTML. Cost: 1 credit.",
        "parameters": [
          { "$ref": "#/components/parameters/Url" },
          { "name": "format", "in": "query", "schema": { "type": "string", "enum": ["markdown", "text", "html"], "default": "markdown" } }
        ],
        "responses": { "200": { "description": "Scraped content", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }
      }
    },
    "/v1/web/crawl": {
      "post": {
        "tags": ["Web", "Jobs"],
        "summary": "Crawl a website (Pro+)",
        "description": "Starts an asynchronous crawl of up to 500 pages. Returns a `jobId`; poll `/v1/jobs/{jobId}` or supply a `webhook`. Requires a Pro plan or higher.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": {
          "type": "object",
          "required": ["url"],
          "properties": {
            "url": { "type": "string", "format": "uri" },
            "mode": { "type": "string", "enum": ["sitemap", "recursive"], "default": "sitemap" },
            "maxPages": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 },
            "format": { "type": "string", "enum": ["markdown", "text", "html"], "default": "markdown" },
            "webhook": { "type": "string", "format": "uri", "description": "Optional URL to receive results on completion." }
          }
        } } } },
        "responses": { "202": { "description": "Job accepted", "content": { "application/json": { "schema": { "type": "object", "properties": {
          "jobId": { "type": "string" }, "status": { "type": "string" }, "message": { "type": "string" }
        } } } } }, "402": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/web/map": {
      "get": {
        "tags": ["Web"],
        "summary": "Map a website's URLs",
        "description": "Discovers all URLs on a site via sitemap.xml or link discovery. Cost: 1 credit.",
        "parameters": [
          { "$ref": "#/components/parameters/Url" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 500, "default": 200 } }
        ],
        "responses": { "200": { "description": "Discovered URLs", "content": { "application/json": { "schema": { "type": "object", "properties": {
          "urls": { "type": "array", "items": { "type": "string" } }
        } } } } } }
      }
    },
    "/v1/jobs/{jobId}": {
      "get": {
        "tags": ["Jobs"],
        "summary": "Get job status",
        "description": "Poll the status and result of an asynchronous job (e.g. a web crawl).",
        "parameters": [{ "name": "jobId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Job status", "content": { "application/json": { "schema": { "type": "object", "properties": {
          "jobId": { "type": "string" },
          "status": { "type": "string", "enum": ["queued", "processing", "completed", "failed"] },
          "result": { "type": ["object", "null"], "additionalProperties": true }
        } } } } }, "404": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/me": {
      "get": {
        "tags": ["Account"],
        "summary": "Account & credits",
        "description": "Returns the authenticated account's plan and remaining credits.",
        "responses": { "200": { "description": "Account info", "content": { "application/json": { "schema": { "type": "object", "properties": {
          "id": { "type": "string" },
          "plan": { "type": "string" },
          "credits": { "type": "integer" }
        } } } } } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "x-api-key", "description": "Your SupaCrawlX API key." }
    },
    "parameters": {
      "Url": { "name": "url", "in": "query", "required": true, "schema": { "type": "string", "format": "uri" }, "description": "The target URL." },
      "Lang": { "name": "lang", "in": "query", "schema": { "type": "string" }, "description": "Preferred language code (e.g. en, es, zh-TW)." },
      "Translate": { "name": "translate", "in": "query", "schema": { "type": "string" }, "description": "Translate the transcript to this language code." },
      "Timestamps": { "name": "timestamps", "in": "query", "schema": { "type": "boolean", "default": true }, "description": "Include per-segment offset and duration." }
    },
    "schemas": {
      "TranscriptSegment": {
        "type": "object",
        "properties": {
          "text": { "type": "string" },
          "offset": { "type": "integer", "description": "Start offset in milliseconds." },
          "duration": { "type": "integer", "description": "Segment duration in milliseconds." },
          "lang": { "type": "string" }
        }
      },
      "TranscriptResponse": {
        "type": "object",
        "properties": {
          "lang": { "type": "string" },
          "aiGenerated": { "type": "boolean" },
          "durationMinutes": { "type": "number" },
          "cached": { "type": "boolean" },
          "content": { "type": "array", "items": { "$ref": "#/components/schemas/TranscriptSegment" } }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "requestId": { "type": "string" }
            }
          }
        }
      }
    },
    "responses": {
      "Transcript": { "description": "Transcript result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TranscriptResponse" } } } },
      "Error": { "description": "Error response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
