Railway

Deploy Cobalt | (Just Updated) Media Downloader No Stranger Can Use on Your Bill

Self-hosted media downloader: API-key auth enforced, YouTube poToken server

Deploy Cobalt | (Just Updated) Media Downloader No Stranger Can Use on Your Bill

Deploy and Host Cobalt on Railway

Cobalt is an open-source media downloader from imput: give it a link from YouTube, TikTok, Instagram, X, Reddit, SoundCloud, Twitch clips, Vimeo, Bluesky and about twenty other sites, and it returns a clean file — no ads, no trackers, no remuxing service in the middle. This template deploys the Cobalt API (the part that does the work and that apps, scripts and the public cobalt frontend talk to), with the API key already generated and enforced.

About Hosting Cobalt

Cobalt's API is a small Node service that resolves a media URL and then either hands back a direct link or tunnels the stream through itself, remuxing on the fly when the site serves video and audio separately. That makes it bandwidth- and CPU-resident rather than storage-heavy: there is no database, no volume, and nothing to migrate — but every request costs the instance real egress. The consequence people miss when self-hosting is that an instance with no authentication is a public service, and the bill is the deployer's.

This deployment pins Cobalt 11.7.1, turns authentication on (API_AUTH_REQUIRED), generates a UUID API key for you at deploy time, writes the key file the API expects, and runs a poToken provider alongside the API so that YouTube requests keep working if Google starts challenging the datacenter address your instance runs on.

Why Deploy Cobalt on Railway

Railway gives the API a public HTTPS domain, restarts it on failure, and bills the bandwidth it actually uses — which suits a service whose entire cost profile is "outbound traffic when someone downloads something". There is no state to persist, so a redeploy is free of risk, and the two services in this template talk over Railway's private network rather than the public internet.

Common Use Cases

  1. A private backend for a personal downloader page or bot, with a key only you hold.
  2. An archiving script that saves your own posts and uploads before a platform removes them.
  3. A step in an automation (n8n, Make, a cron job) that needs the raw media file behind a link.
  4. A self-hosted API for the official cobalt web frontend, instead of using someone else's instance.

Dependencies for Cobalt Hosting

  • The official Cobalt API image, pinned: ghcr.io/imputnet/cobalt:11.7.1.
  • A poToken provider for YouTube: brainicism/bgutil-ytdlp-pot-provider:1.3.1-node, deployed as a private service the API reaches over Railway's internal network.

Deployment Dependencies

Implementation Details

Authentication is on by default. The template generates COBALT_API_KEY as a UUID and writes it into the key file Cobalt reads (API_KEY_URL), so nothing is left for you to configure. Requests must carry that key with the Api-Key scheme — not Bearer, which Cobalt rejects:

curl -X POST https://your-instance.up.railway.app/ \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Api-Key ' \
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "videoQuality": "1080"}'

Without the header the API answers 400 {"error":{"code":"error.api.auth.key.missing"}}.

The API honours the port Railway injects, and the service refuses to start if the key variable is ever emptied, so a misconfigured instance fails loudly instead of coming up unprotected.

Why this template

  • The API is not open to the world. Two of the templates in this category publish a variable named API_KEY — a name that appears nowhere in Cobalt's source, which reads only API_KEY_URL and API_AUTH_REQUIRED. Deployed from those templates, an anonymous POST / with no headers at all returns 200 {"status":"tunnel", ...} and streams the file, on the deployer's bandwidth. One of them documents an Authorization: Bearer header that the API ignores. Here the same anonymous request returns 400 error.api.auth.key.missing, and the generated key works.
  • YouTube keeps working when the IP gets challenged. Cobalt asks its session server for a poToken by POST /get_pot, which is the API of the bgutil provider deployed here — Cobalt's own docs still point at yt-session-generator, whose webserver serves /token and answers that call 404 Not Found. No other template in this category deploys a token provider at all, including the one whose name promises fixed YouTube downloads.
  • The version is pinned. Everyone else runs :latest on both images.
  • Nothing to fill in. The deploy form asks for nothing: the key is generated, the public URL is wired to API_URL, and the provider address is wired over private networking.

Notes and limits

  • This deploys the API, not the cobalt web page. Point the official frontend or your own client at the instance URL, with the key.
  • Downloading YouTube from a datacenter address is challenged by Google intermittently. The token provider is what keeps that working; measured on the day this template was published, a stock instance without one still resolved every test video, so treat the provider as insurance rather than as a fix for a failure you are seeing today.
  • Cobalt keeps no library and no history — files stream through and are gone.

Template Content

More templates in this category

View Template
Telegram JavaScript Bot
A template for Telegram bot in JavaScript using grammY

Agampreet Singh
294
View Template
Cobalt Tools [Updated Aug ’26]
Cobalt Tools [Aug ’26] (Media Downloader, Converter & Automation) Self Host

shinyduo
262
View Template
Telegram Gateway
Multi-bot Telegram webhook gateway with real-time WebSocket event streaming

INAPP
4