Getting started

Build a minimal add-on, serve a manifest, install it in wako.

An add-on is a public HTTPS service that returns JSON. The smallest thing you can ship is a manifest and one stream endpoint. This page walks through both, using Node.js to make it concrete — but anything that can serve JSON works.

1. Serve a manifest

Every add-on starts with a manifest at /manifest.json. It tells wako your add-on's name, version, what resources you support, and which content types (movie, series, etc.) you handle.

JSON
{
  "id": "com.example.hello-streams",
  "name": "Hello Streams",
  "description": "A minimal example add-on for wako.",
  "version": "1.0.0",
  "resources": ["stream"],
  "types": ["movie", "series"],
  "catalogs": [],
  "idPrefixes": ["tt"]
}

resources is the list of endpoint families this add-on serves — here, only stream. types are the content kinds it understands. idPrefixes narrows the IDs wako will send: with ["tt"] the add-on only receives IMDb IDs, which is what wako uses for most content.

2. Serve a stream

When the user opens a movie or episode, wako requests streams from every add-on that declares stream as a resource. The endpoint shape is:

HTTP
GET /stream/movie/tt0111161.json           # The Shawshank Redemption
GET /stream/series/tt0903747:1:1.json      # Breaking Bad S01E01

For series, the ID is the show's IMDb followed by :season:episode. Your response is a JSON object containing a streams array:

JSON
{
  "streams": [
    {
      "url": "https://cdn.example.com/movie.mp4",
      "title": "1080p — H.264 — Direct",
      "name": "Hello Streams",
      "behaviorHints": {
        "bingeGroup": "hello-streams-1080p"
      }
    }
  ]
}

At least one of url, externalUrl, or infoHash must be present — any other entry is dropped by wako. The title field is the line the user sees in the stream list.

3. A complete Node.js example

JavaScript
import express from "express";

const app = express();

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Content-Type", "application/json");
  next();
});

const manifest = {
  id: "com.example.hello-streams",
  name: "Hello Streams",
  description: "A minimal example add-on for wako.",
  version: "1.0.0",
  resources: ["stream"],
  types: ["movie", "series"],
  catalogs: [],
  idPrefixes: ["tt"],
};

app.get("/manifest.json", (_req, res) => {
  res.send(manifest);
});

app.get("/stream/:type/:id.json", (req, res) => {
  res.send({
    streams: [
      {
        url: "https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4",
        title: "Big Buck Bunny — demo stream",
        name: "Hello Streams",
      },
    ],
  });
});

app.listen(7000, () => console.log("http://127.0.0.1:7000/manifest.json"));
!
CORS is mandatory
wako runs the request from a native mobile or TV context, but a missing Access-Control-Allow-Origin header still breaks the in-app developer test page and confuses anyone trying to debug your add-on from a browser. Always allow cross-origin requests.

4. Install it in wako

  1. Open wako on your phone or TV.
  2. Go to Settings > Extensions.
  3. Tap Install an add-on.
  4. Paste your manifest URL (for example https://my-host.example/manifest.json).

wako fetches the manifest, validates it, and stores a reference. Open a movie and your add-on shows up in the stream list, with its name and any title you returned.

Local development on TV
Android TV cannot reach localhost from your laptop. Use a tunnel (Cloudflare Tunnel, ngrok, Tailscale) or your machine's LAN IP. wako accepts plain HTTP for http:// and https:// URLs, but most production deployments should use HTTPS so the add-on works on every network.

Next steps

  • Add a catalog so your content appears on the home screen — see the Catalog page.
  • Return richer metadata (cast, episodes, posters) with the Meta resource.
  • Read the behavior hints reference to control playback, binge-watching, and proxy headers.