API Documentation

Video Embed Link Extractor API

Extract RPM, P2P, and UPN stream links for any movie or series

🚀 Quick Start

Get Up and Running in 3 Steps

  1. Register — Get your unique API key via POST /auth/register
  2. Request — Send a movie/series name to POST /v1/extract
  3. Use Links — Receive RPM, P2P, and UPN stream URLs in milliseconds

Base URL:

📑 Contents
🔐 Authentication

Authentication

All extraction endpoints require an API key passed in the X-API-Key header.

X-API-Key: mk-m5z8abc-def1234567890abcdef1234567890-a1b2c3d4

API keys follow the format mk-{timestamp}-{random}-{checksum} — each key is cryptographically unique and non-guessable.

📝 Register

Register a New API Key

POST /auth/register

No authentication required. Rate limited to 10 registrations per IP per hour.

Request Body

FieldTypeDescription
name REQUIREDstringYour name or site name (2–80 chars)
email OPTIONALstringYour email address

Example Request

curl -X POST /auth/register \
  -H "Content-Type: application/json" \
  -d '{"name": "My Website", "email": "admin@example.com"}'

Example Response 201

{
  "success": true,
  "message": "API key created successfully. Save it — it won't be shown again.",
  "data": {
    "api_key": "mk-m5z8abc-def1234567890abcdef1234567890-a1b2c3d4",
    "name": "My Website",
    "created_at": "2026-05-18T12:00:00.000Z"
  }
}
📡 Extract

Extract Stream Links

POST /v1/extract

Requires X-API-Key header. Returns RPM, P2P, and UPN stream URLs.

Request Body

FieldTypeDescription
type REQUIREDstring"movie" or "series"
name REQUIREDstringTitle of the movie or series
season OPTIONALintegerSeason number (required for series)
episode OPTIONALintegerEpisode number (required for series)

Example Request — Movie

curl -X POST /v1/extract \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"type": "movie", "name": "Dhurandhar"}'

Example Request — Series

curl -X POST /v1/extract \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"type": "series", "name": "Mirzapur", "season": 3, "episode": 1}'

Example Response 200

{
  "success": true,
  "request_time_ms": 2847,
  "cached": false,
  "data": {
    "type": "movie",
    "original_name": "Dhurandhar",
    "normalized_name": "dhurandhar",
    "source_url": "https://multimovies.fyi/movies/dhurandhar/",
    "links": {
      "rpm": "https://multimovies.rpmhub.site/#abc123",
      "p2p": "https://multimovies.p2pplay.pro/#abc123",
      "upn": "https://server1.uns.bio/#abc123"
    },
    "generated_at": "2026-05-18T12:00:00.000Z"
  }
}
💚 Health

Health Check

GET /health

No authentication required. Returns server status and uptime.

Example Response 200

{
  "status": "ok",
  "uptime": 3600
}
📦 Response Format

Consistent Response Structure

Success

{
  "success": true,
  "request_time_ms": 2847,
  "cached": false,
  "data": { ... }
}

Error

{
  "success": false,
  "error": "Clear human-readable error message",
  "code": "ERROR_CODE"
}

The cached field indicates whether the result was served from cache (instant) or freshly extracted.

⚠️ Error Codes

Error Reference

CodeHTTP StatusMeaning
MISSING_NAME400Request body missing the "name" field
INVALID_TYPE400"type" must be "movie" or "series"
INVALID_API_KEY401Missing, invalid, or revoked API key
SOURCE_NOT_FOUND404Movie/series not found on source
LINKS_NOT_FOUND422No embed links found in page
RATE_LIMITED429Too many requests — slow down
TIMEOUT408Source page did not respond in time
INTERNAL_ERROR500Unexpected server error
🛡️ Rate Limiting

Rate Limits

Rate limit headers are included in every response (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset).

🔗 Integration Guide

How to Integrate Into Your Website

Step 1: Get Your API Key

Call the registration endpoint once and save the returned key securely on your server. Never expose your API key in frontend JavaScript.

Step 2: Create a Backend Proxy

From your server, call our API and forward the results to your frontend. This keeps your API key hidden.

Step 3: Display Links to Users

Use the returned RPM, P2P, and UPN URLs in your video player or as download links.

Architecture

User's Browser → Your Server (proxy) → Our API → Stream URLs → Your Server → User's Browser

Caching Recommendation

Cache results on your end for the same movie/series. Our API already caches, but your own cache reduces latency and API calls.

💻 Code Examples

Integration Examples

Node.js / Express

const express = require('express');
const app = express();

const API_KEY = process.env.MOVIE_API_KEY;
const API_URL = process.env.MOVIE_API_URL || 'http://localhost:3000';

app.get('/api/stream-links', async (req, res) => {
  try {
    const { type, name, season, episode } = req.query;

    const response = await fetch(`${API_URL}/v1/extract`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': API_KEY,
      },
      body: JSON.stringify({
        type,
        name,
        ...(type === 'series' && { season: parseInt(season), episode: parseInt(episode) }),
      }),
    });

    const data = await response.json();

    if (!data.success) {
      return res.status(response.status).json({ error: data.error });
    }

    res.json({ links: data.data.links });
  } catch (err) {
    console.error('Stream link extraction failed:', err.message);
    res.status(500).json({ error: 'Failed to fetch stream links' });
  }
});

app.listen(8080);

Python / Flask

import os
import requests
from flask import Flask, request, jsonify

app = Flask(__name__)

API_KEY = os.environ.get("MOVIE_API_KEY")
API_URL = os.environ.get("MOVIE_API_URL", "http://localhost:3000")

@app.route("/api/stream-links")
def stream_links():
    try:
        payload = {
            "type": request.args.get("type"),
            "name": request.args.get("name"),
        }
        if payload["type"] == "series":
            payload["season"] = int(request.args.get("season", 1))
            payload["episode"] = int(request.args.get("episode", 1))

        resp = requests.post(
            f"{API_URL}/v1/extract",
            json=payload,
            headers={"X-API-Key": API_KEY},
            timeout=10,
        )
        data = resp.json()

        if not data.get("success"):
            return jsonify({"error": data.get("error")}), resp.status_code

        return jsonify({"links": data["data"]["links"]})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    app.run(port=8080)

PHP

<?php
$apiKey = getenv('MOVIE_API_KEY');
$apiUrl = getenv('MOVIE_API_URL') ?: 'http://localhost:3000';

$type = $_GET['type'] ?? '';
$name = $_GET['name'] ?? '';

if (!$type || !$name) {
    http_response_code(400);
    echo json_encode(['error' => 'Missing type or name']);
    exit;
}

$payload = ['type' => $type, 'name' => $name];
if ($type === 'series') {
    $payload['season'] = (int)($_GET['season'] ?? 1);
    $payload['episode'] = (int)($_GET['episode'] ?? 1);
}

$ch = curl_init("$apiUrl/v1/extract");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    "X-API-Key: $apiKey",
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

http_response_code($httpCode);
echo $response;
?>

cURL

curl -X POST /v1/extract \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"type": "movie", "name": "Pathaan"}'