{
  "openapi": "3.0.1",
  "info": {
    "title": "Audio Transcription - Speech to Text, Audio to Text, Whisper",
    "description": "Bulk audio transcription with Whisper: transcribe audio to text, video to text, speech to text, MP3 to text, YouTube video transcription, podcast RSS, Google Drive/Dropbox links. SRT/VTT subtitle generator, speaker diarization, TXT/Markdown, 90+ languages. $0.006/min.",
    "version": "0.1",
    "x-build-id": "Xg8lvPmgyMh6VKRwM"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~audio-transcriber/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-audio-transcriber",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/tidytools~audio-transcriber/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-audio-transcriber",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/tidytools~audio-transcriber/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-audio-transcriber",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "urls": {
            "title": "Audio or video file URLs",
            "type": "array",
            "description": "Paste public media links, one per line, including voice notes (.ogg/.opus). Choose a file or video with spoken words; music-only audio returns free no_text, not a transcript. Cloud shares must download without sign-in in a private window; temporary links must still be valid. If sharing is restricted, use audioFiles upload. Accepts audio/video files, public Drive/Dropbox/OneDrive shares and YouTube, TikTok, Instagram Reel, Loom, Wistia, Streamable or v.redd.it videos. Files up to 2 GB.",
            "items": {
              "type": "string"
            }
          },
          "audioFiles": {
            "title": "Or upload audio / video files",
            "type": "array",
            "description": "Upload recordings from your computer in Apify Console (they are stored in a key-value store of your account and read from there). Same formats and 2 GB limit as the URLs. In API calls, pass file URLs in \"urls\" instead."
          },
          "podcastFeeds": {
            "title": "Podcast RSS feeds (optional)",
            "type": "array",
            "description": "Podcast RSS feed URLs or Apple Podcasts show links. The newest episodes are transcribed (see the next field). Each result includes the episode title and publish date. Leave blank to try only the short speech sample in Audio or video file URLs; add your own feed when ready.",
            "items": {
              "type": "string"
            }
          },
          "audioUrls": {
            "title": "File URLs (request list, optional)",
            "type": "array",
            "description": "Same as \"Audio or video file URLs\", in Apify's request list format (also accepts a link to a text file with URLs). Kept for existing integrations; new integrations should use \"urls\".",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxEpisodesPerFeed": {
            "title": "Episodes per podcast feed",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "How many of the newest episodes to transcribe from each feed.",
            "default": 3
          },
          "usePublisherTranscripts": {
            "title": "Use publisher transcripts when the feed has them",
            "type": "boolean",
            "description": "Many podcasts publish their own transcript in the feed (Podcasting 2.0 <podcast:transcript>: VTT, SRT, JSON, HTML or text). When an episode has one, it is downloaded and converted to the same output (text, segments, SRT/VTT for timed formats) with transcriptSource \"publisher\", and no audio minutes are charged. A transcript that is empty or does not match the episode length is ignored and the audio is transcribed as usual.",
            "default": true
          },
          "episodesSince": {
            "title": "Episodes published since (optional)",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$|^(\\d+)\\s*(day|week|month|year)s?$",
            "type": "string",
            "description": "Only feed episodes published on or after this date (YYYY-MM-DD), or within e.g. \"30 days\". Applied before \"Episodes per podcast feed\". Filtered episodes get no row; SUMMARY.episodesFiltered counts them."
          },
          "episodesUntil": {
            "title": "Episodes published until (optional)",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
            "type": "string",
            "description": "Only feed episodes published on or before this date (YYYY-MM-DD, the whole day counts)."
          },
          "titleIncludes": {
            "title": "Episode title contains (optional)",
            "type": "array",
            "description": "Only feed episodes whose title contains one of these texts (case-insensitive). * matches anything, e.g. \"interview*ceo\".",
            "items": {
              "type": "string"
            }
          },
          "titleExcludes": {
            "title": "Episode title does not contain (optional)",
            "type": "array",
            "description": "Skip feed episodes whose title contains one of these texts (case-insensitive), e.g. \"trailer\", \"rerun\", \"best of\".",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Language (optional)",
            "type": "string",
            "description": "ISO 639-1 code such as en, es, de, ja or zh (names such as English also work). Leave empty to detect automatically. YouTube links are always transcribed in the spoken language; when it differs from this, the row says so in languageNote."
          },
          "vocabulary": {
            "title": "Vocabulary hints (optional)",
            "type": "string",
            "description": "Names, brands or terms that appear in the audio, e.g. \"Apify, Cloudflare, Kubernetes\". Helps spell them correctly."
          },
          "transcriptionEngine": {
            "title": "Transcription engine",
            "enum": [
              "fast",
              "accurate"
            ],
            "type": "string",
            "description": "Choose \"fast\" (default, Cloudflare Workers AI Whisper) or \"accurate\" (self-hosted Whisper with more thorough decoding), e.g. {\"transcriptionEngine\":\"accurate\"}. Accurate is slower; busy pieces fall back to Fast and each result reports asrBackend. Both cost the same. Speaker labels use Deepgram; YouTube links use the YouTube service regardless of this setting.",
            "default": "fast"
          },
          "searchTerms": {
            "title": "Search the transcripts for (optional)",
            "type": "array",
            "description": "JSON array of up to 50 brands, names or topics to find, e.g. {\"searchTerms\":[\"Apify\",\"customer churn\"]}; in the form, enter one per line. Matches include timestamp, sentence, speaker and a link to that moment; the run also saves KEYWORD_MATCHES.csv. Matching ignores case and accents; a trailing * matches word endings, e.g. \"transcri*\". No extra charge.",
            "items": {
              "type": "string"
            }
          },
          "saveSubtitles": {
            "title": "Save SRT and VTT subtitles",
            "type": "boolean",
            "description": "Also save subtitle files for every transcript (no extra charge).",
            "default": true
          },
          "saveTranscriptFiles": {
            "title": "Save TXT and Markdown transcripts",
            "type": "boolean",
            "description": "Also save a plain-text (.txt) and a Markdown (.md) transcript for every file, linked as txtUrl and mdUrl, plus one combined file for the whole run when there are 2 or more transcripts (no extra charge).",
            "default": true
          },
          "summarize": {
            "title": "AI summary and chapters",
            "type": "boolean",
            "description": "Add a short summary and timestamped chapters to each transcript. Charged as a separate event per file (see Pricing). Recordings shorter than 2 minutes get a summary only.",
            "default": false
          },
          "meetingNotes": {
            "title": "Meeting notes (summary, decisions, action items)",
            "type": "boolean",
            "description": "Add structured meeting notes to each transcript: a short summary, decisions, action items (task, owner, due date) and, with speaker labels on, talk time per speaker and each speaker's main points. Saved in the row (meetingNotes) and as a Markdown file (meetingNotesUrl). No extra charge.",
            "default": false
          },
          "speakerLabels": {
            "title": "Speaker labels (who said what)",
            "type": "boolean",
            "description": "Label each segment and paragraph with Speaker 1, Speaker 2… and count the speakers. Uses Deepgram nova-3 instead of Whisper and is billed as \"audio minute with speaker labels\" ($0.015/min) instead of the regular audio minute. Some languages (e.g. Chinese) are not available; those files fail with errorType \"unsupported\" and are not charged. Not available for YouTube links (free \"unsupported\" row).",
            "default": false
          },
          "wordTimestamps": {
            "title": "Word-level timestamps",
            "type": "boolean",
            "description": "Add a words array [{word, start, end}] to every segment (for video editing and precise subtitle alignment). Included in the regular $0.006/min price. With speaker labels on, the words come from nova-3 and the speaker-label price applies (not charged twice).",
            "default": false
          },
          "subtitleLanguages": {
            "title": "Translated subtitles (optional)",
            "type": "array",
            "description": "Also make SRT + VTT subtitles in these languages (up to 5), e.g. Spanish, German, Traditional Chinese, ja. Timings and speaker labels are kept. $0.002 per audio minute per language, charged only for languages that succeed.",
            "items": {
              "type": "string"
            }
          },
          "datasetId": {
            "title": "Read URLs from a dataset (optional)",
            "type": "string",
            "description": "A dataset from another Actor run, e.g. a podcast or video scraper. Its media URLs are added to the list above. Have the rows themselves instead? Paste them into \"datasetItems\" below."
          },
          "datasetField": {
            "title": "Dataset field with the URL (optional)",
            "type": "string",
            "description": "Field that holds the media URL, e.g. audioUrl or media.url (a dot path, for nested fields). Leave empty to detect it (audioUrl, mediaUrl, videoUrl, url...). Used for the dataset above and for pasted dataset rows."
          },
          "datasetItems": {
            "title": "Or paste dataset rows (optional)",
            "type": "array",
            "description": "JSON array of rows from another Actor dataset, e.g. {\"datasetItems\":[{\"audioUrl\":\"https://example.com/episode.mp3\"}]}. Each row needs a media URL field (audioUrl, mediaUrl, videoUrl, url, etc.), or set datasetField to its field name; dot paths work. A row may itself be a URL. Rows without usable links get free error rows with their index; duplicate media is transcribed once. Other source columns are not copied to results."
          },
          "maxMinutesPerFile": {
            "title": "Max minutes per file (optional)",
            "minimum": 0,
            "type": "integer",
            "description": "Skip files longer than this. Skipped files get a result row with errorType \"too_large\" and are not charged. Empty = no limit (0 also means no limit). YouTube videos: empty = 240 minutes (the maximum)."
          },
          "maxTotalMinutes": {
            "title": "Max total minutes per run (optional)",
            "minimum": 0,
            "type": "integer",
            "description": "Stop charging for new files once this many audio minutes were transcribed. Files that would go over it get a row with errorType \"limit_reached\" and are not charged. Empty or 0 = no limit (your Apify spending limit still applies)."
          },
          "maxConcurrency": {
            "title": "Parallel pieces per file",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "Long files are split into 90-second pieces that are transcribed in parallel. More is faster.",
            "default": 3
          },
          "fileConcurrency": {
            "title": "Files in parallel",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many files (podcast episodes, URLs) are downloaded and transcribed at the same time. More is faster for batches; rows then arrive in the order files finish (inputIndex gives the input position). Your max charge per run and maxTotalMinutes are still respected: the cost of every file in progress is reserved before it is transcribed. With little run memory fewer files run at once (about 3 at 1024 MB).",
            "default": 3
          },
          "fileTimeoutSecs": {
            "title": "Time limit per file (seconds)",
            "minimum": 0,
            "maximum": 7200,
            "type": "integer",
            "description": "A file whose download, conversion and transcription take longer than this is reported with errorType \"timeout\" and not charged; the run goes on with the next file. Raise it for recordings of several hours. YouTube videos get at least their length x 15 s + 20 min (our YouTube queue decides how long they take). 0 = no limit.",
            "default": 1800
          },
          "proxyConfiguration": {
            "title": "Proxy (optional)",
            "type": "object",
            "description": "Only used for requests sent from Apify's network (file downloads and podcast feeds). Apify proxy usage is billed to your Apify account."
          },
          "downloadVia": {
            "title": "Download files from",
            "enum": [
              "auto",
              "direct",
              "backend",
              "vm",
              "residential"
            ],
            "type": "string",
            "description": "Some file hosts refuse downloads from data centers or after many files in a row (HTTP 401/403/429 or a bot-check page). Auto then tries our backend (any size), our Oracle server (up to 15 MB) and our home line in Taiwan (up to 10 MB) before giving up. Each failed file is a free row that lists what was tried. No extra charge. We never use cookies or logins and never solve CAPTCHAs; when a host sends Retry-After we wait that long.",
            "default": "auto"
          },
          "downloadUserAgent": {
            "title": "Download User-Agent",
            "enum": [
              "auto",
              "tidytools"
            ],
            "type": "string",
            "description": "Every file is first requested with our own User-Agent (TidyToolsTranscriber). Some hosts serve media files only to browsers: with Auto, a file that was refused is requested once more with a standard desktop browser User-Agent string (a plain header; no cookies, logins, CAPTCHA solving or browser automation). Choose TidyTools only to never switch. Only used for the audio/video file links you give.",
            "default": "auto"
          },
          "newEpisodesOnly": {
            "title": "Only new episodes and files (for schedules)",
            "type": "boolean",
            "description": "Remember what was transcribed (podcast episode GUID or file URL) and skip it in later runs with the same monitor name. From podcast feeds, only episodes published after the newest one already transcribed are taken, so a run on a day without a new episode transcribes (and charges) nothing. Failed files are retried next time.",
            "default": false
          },
          "backfillOlderEpisodes": {
            "title": "Also transcribe older episodes not done yet",
            "type": "boolean",
            "description": "With \"Only new episodes\": also take older episodes that were never transcribed (up to Max episodes per feed per run), to work through a back catalogue over several runs. Off by default, so scheduled runs only pick up new releases.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name (for new episodes only)",
            "type": "string",
            "description": "Runs with the same name share the list of transcribed files, e.g. one name per podcast schedule. Letters, digits and dashes."
          },
          "sourceFileId": {
            "title": "Source file ID (for n8n / Make retries)",
            "type": "string",
            "description": "Your own id of the file (Drive file id, Dropbox file id `id:...`, storage object key...). Used for runs with one file; it is copied to the row so your workflow can match results, and it is the key of `resumeStore`. Without it, an id is derived from the link (Drive file id, Dropbox shared link id, the bucket and object of a presigned URL). Every row also has this run's `runId`."
          },
          "resumeStore": {
            "title": "Resume store name (reuse finished transcripts)",
            "type": "string",
            "description": "Optional. A name such as `n8n-recordings`: finished transcripts are remembered by source file id in a named key-value store of your Apify account. When the same file is sent again with the same settings (a workflow retry), its saved transcript is returned again with `reused: true` and is not charged again; if another run is still transcribing that file, this run waits for it. Leave empty to turn off."
          },
          "tiktokOnly": {
            "title": "Only TikTok video links",
            "type": "boolean",
            "description": "Only public TikTok video links are accepted; other links get a free invalid_input row. The TikTok Transcript variant always enables this mode.",
            "default": false
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}