Skip to main content
Remove Invisible Watermarks from AI-Generated MediaThe Remix API helps you remove invisible watermarks that AI media generation platforms add to their content. Process videos or images through our API to get clean output for your use cases.

Introduction

The Remix API allows you to process video and image files by providing public media URLs. The API downloads the media from the provided URL, applies your specified transformations, and processes it to remove invisible watermarks.
Upload Your Media FirstBefore using the Remix API, upload your video or image file to cloud storage such as Cloudflare R2 or AWS S3 and make it publicly accessible. The API requires direct URLs to your media files.

Authentication

All requests to the Remix API require authentication using an API key passed in the x-ty-api-key header.
x-ty-api-key: your-api-key-here

Endpoints

Video
POST https://www.topyappers.com/api/v1/remix
Images
POST https://www.topyappers.com/api/v1/image-rewrite

How to Upload Your Media

Before using the Remix API, you need to upload your media to cloud storage. Here are the recommended options:

Option 1: Cloudflare R2 Storage

Cloudflare R2 offers S3-compatible storage with no egress fees.
  1. Create an R2 bucket in your Cloudflare dashboard
  2. Upload your video or image file to the bucket
  3. Make the bucket or object publicly accessible
  4. Use the public URL in your API request
Example R2 URLs: https://pub-abc123.r2.dev/my-video.mp4, https://pub-abc123.r2.dev/image-1.jpg

Option 2: AWS S3 Storage

AWS S3 is a widely-used object storage service.
  1. Create an S3 bucket in your AWS console
  2. Upload your video or image file to the bucket
  3. Configure the bucket policy or object ACL to allow public read access
  4. Use the public URL in your API request
Example S3 URLs: https://my-bucket.s3.amazonaws.com/my-video.mp4, https://my-bucket.s3.amazonaws.com/image-1.jpg

Other Storage Options

Any cloud storage service that provides publicly accessible URLs will work, including:
  • Google Cloud Storage
  • Azure Blob Storage
  • DigitalOcean Spaces
  • Backblaze B2
Security Note: Only make media publicly accessible that you’re comfortable sharing. Consider using signed URLs with expiration times for sensitive content.

Request Format

Video Request

POST /api/v1/remix accepts JSON with the following fields:
FieldTypeRequiredDescription
video_urlStringYesURL to the video file (must be publicly accessible)
parametersObjectNoOptional processing parameters

Video Processing Parameters

The parameters field accepts an object with optional processing parameters. All parameters are optional and will use default values if not specified.
ParameterTypeDefaultRange/ValuesDescription
zoomFactornumber1.00.1 - 5.0Zoom level for the video
huenumber0.0-180 to 180Hue adjustment in degrees
playbackSpeednumber1.00.1 - 5.0Video playback speed multiplier
saturationnumber1.00.0 - 3.0Color saturation multiplier
brightnessnumber0.0-1.0 to 1.0Brightness adjustment
contrastnumber1.00.0 - 3.0Contrast multiplier
volumenumber1.00.0 - 2.0Audio volume multiplier
removeAudiobooleanfalsetrue/falseWhether to remove audio from the video
algorithmFingerprintstring”Fingerprint”Any stringAlgorithm identifier for processing
deviceMediastring-See supported values belowTarget device profile for media optimization
hueShiftnumber0.0-180 to 180Additional hue shift in degrees
gammanumber1.00.1 - 3.0Gamma correction value
temperaturenumber1.00.5 - 2.0Color temperature adjustment
noisenumber0.00.0 - 1.0Amount of noise to add
sharpnessnumber1.00.0 - 3.0Sharpness multiplier
blendnumber0.00.0 - 1.0Blending amount
bilateVariationnumber1.00.0 - 2.0Bilateral filter variation
frameBlendingnumber0.00.0 - 1.0Amount of frame blending
timeShiftnumber0.0-10.0 to 10.0Time shift in seconds

Supported deviceMedia Values

export enum DeviceModel {
  IPHONE_17_PRO_MAX = "iPhone 17 Pro Max",
  IPHONE_17_PRO = "iPhone 17 Pro",
  IPHONE_17 = "iPhone 17",
  IPHONE_16_PRO_MAX = "iPhone 16 Pro Max",
  IPHONE_16_PRO = "iPhone 16 Pro",
  IPHONE_16 = "iPhone 16",
  IPHONE_15_PRO_MAX = "iPhone 15 Pro Max",
  IPHONE_15_PRO = "iPhone 15 Pro",
  IPHONE_15 = "iPhone 15",
  IPHONE_14_PRO_MAX = "iPhone 14 Pro Max",
  IPHONE_14_PRO = "iPhone 14 Pro",
  IPHONE_14 = "iPhone 14",
  IPHONE_13_PRO_MAX = "iPhone 13 Pro Max",
  IPHONE_13_PRO = "iPhone 13 Pro",
  IPHONE_13 = "iPhone 13",
  META_RAYBAN = "Ray-Ban Meta Smart Glasses",
}

Example with Multiple Parameters

{
  "video_url": "https://pub-abc123.r2.dev/my-video.mp4",
  "parameters": {
    "playbackSpeed": 1.2,
    "brightness": 0.1,
    "contrast": 1.1,
    "saturation": 1.2,
    "hue": 15,
    "zoomFactor": 1.05,
    "removeAudio": false,
    "deviceMedia": "iPhone 16 Pro"
  }
}

Image Request

POST /api/v1/image-rewrite accepts either a single image_url or an images array for batch processing.
FieldTypeRequiredDescription
image_urlStringYes, unless images is providedURL to a single image file
imagesArrayYes, unless image_url is providedUp to 20 image objects with image_url and optional image-specific parameters
parametersObjectNoOptional global image processing parameters applied to every image

Image Processing Parameters

ParameterTypeDefaultRange/ValuesDescription
zoomFactornumber1.00.5 - 2.0Zoom level for the image
saturationnumber1.00.0 - 2.0Color saturation multiplier
brightnessnumber0.0-1.0 to 1.0Brightness adjustment
contrastnumber1.00.0 - 2.0Contrast multiplier
huenumber0.0-180 to 180Hue adjustment in degrees
hueShiftnumber0.0-180 to 180Alias for hue adjustment
gammanumber1.00.1 - 3.0Gamma correction value
temperaturenumber1.00.1 - 2.0Color temperature adjustment
noisenumber0.00.0 - 0.5Amount of noise to add
sharpnessnumber1.00.0 - 2.0Sharpness multiplier
qualityinteger9460 - 100Output image quality
flipHorizontalbooleanfalsetrue/falseWhether to flip the image horizontally
flipVerticalbooleanfalsetrue/falseWhether to flip the image vertically
deviceModelstring-See supported values aboveTarget device profile for metadata

Image Batch Example

{
  "images": [
    {
      "image_url": "https://pub-abc123.r2.dev/image-1.jpg"
    },
    {
      "image_url": "https://pub-abc123.r2.dev/image-2.jpg",
      "brightness": 0.03
    }
  ],
  "parameters": {
    "brightness": 0.02,
    "contrast": 1.05,
    "quality": 94,
    "deviceModel": "iPhone 16 Pro"
  }
}

Response Format

Success Response (200 OK)

Video

{
  "data": {
    "inputVideoUrl": "https://storage.topyappers.com/uploads/abc123.mp4",
    "result": "Video processing initiated"
  }
}

Images

{
  "success": true,
  "message": "Images processed successfully",
  "data": {
    "imageCount": 2,
    "inputImageUrls": [
      "https://pub-abc123.r2.dev/image-1.jpg",
      "https://pub-abc123.r2.dev/image-2.jpg"
    ],
    "processedImages": [
      {
        "url": "https://imgrework.topyappers.com/processed-image-1.jpg",
        "applied_params": {
          "brightness": 0.02,
          "contrast": 1.05,
          "quality": 94
        }
      }
    ],
    "processingTime": 8.42
  }
}

Error Responses

  • 400 Bad Request: Invalid media URL or parameters
  • 401 Unauthorized: Invalid or missing API key
  • 413 Payload Too Large: Video file exceeds size limit
  • 429 Too Many Requests: Rate limit exceeded

Code Examples

import requests
import json

API_KEY = "your-api-key-here"
BASE_URL = "https://www.topyappers.com"
# Video URL from Cloudflare R2 or AWS S3
VIDEO_URL = "https://pub-abc123.r2.dev/my-video.mp4"

# Optional parameters for video processing
parameters = {
    "playbackSpeed": 1.2,
    "brightness": 0.1,
    "contrast": 1.1,
    "saturation": 1.2,
    "hue": 15,
    "zoomFactor": 1.05,
    "deviceMedia": "iPhone 16 Pro"
}

def process_video():
    url = f"{BASE_URL}/api/v1/remix"

    headers = {
        "x-ty-api-key": API_KEY,
        "Content-Type": "application/json"
    }

    payload = {
        "video_url": VIDEO_URL,
        "parameters": parameters
    }

    print(f"Processing {VIDEO_URL}...")
    response = requests.post(url, headers=headers, json=payload)

    if response.status_code == 200:
        result = response.json()
        print("✅ Success!")
        print(f"Input URL: {result['data']['inputVideoUrl']}")
        if 'result' in result['data']:
            print(f"Result: {result['data']['result']}")
        return result
    else:
        print(f"❌ Error {response.status_code}: {response.text}")
        return None

if __name__ == "__main__":
    result = process_video()
    if result:
        print(f"\nFull response:\n{json.dumps(result, indent=2)}")

React Example (Complete Component)

import { useState } from "react";

export function VideoRemixProcessor() {
  const [videoUrl, setVideoUrl] = useState("");
  const [result, setResult] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!videoUrl) return;

    setLoading(true);
    setError("");
    setResult(null);

    try {
      const response = await fetch("https://www.topyappers.com/api/v1/remix", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-ty-api-key": process.env.NEXT_PUBLIC_API_KEY!,
        },
        body: JSON.stringify({
          video_url: videoUrl,
          parameters: {
            playbackSpeed: 1.2,
            brightness: 0.1,
            contrast: 1.1,
            deviceMedia: "iPhone 16 Pro",
          },
        }),
      });

      if (!response.ok) {
        throw new Error(`API error: ${response.status}`);
      }

      const data = await response.json();
      setResult(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="url"
        placeholder="https://pub-abc123.r2.dev/video.mp4"
        value={videoUrl}
        onChange={(e) => setVideoUrl(e.target.value)}
        required
      />
      <p className="hint">Enter URL from Cloudflare R2 or AWS S3</p>

      <button type="submit" disabled={!videoUrl || loading}>
        {loading ? "Processing..." : "Process Video"}
      </button>

      {error && (
        <div className="error">
          <p>❌ Error: {error}</p>
        </div>
      )}

      {result && (
        <div className="result">
          <h3>✅ Complete!</h3>
          <pre>{JSON.stringify(result, null, 2)}</pre>
        </div>
      )}
    </form>
  );
}

Media URL Requirements

Your media must be uploaded to cloud storage (Cloudflare R2, AWS S3, etc.) before processing. The URL must meet these requirements:
  • Publicly Accessible: The media URL must be publicly accessible (no authentication required)
  • Cloud Storage: Must be hosted on Cloudflare R2, AWS S3, or similar cloud storage
  • Direct Links: URL must point directly to the media file (not a webpage)
  • Video Formats: MP4, MOV, AVI, WebM
  • Video Max File Size: 150MB
  • Image Formats: JPG, PNG, WebP, GIF
  • Image Batch Size: Maximum 20 images per request

Error Handling

400 Bad Request

{
  "error": "Invalid media URL or parameters"
}

401 Unauthorized

{
  "error": "Invalid API key"
}

429 Too Many Requests

{
  "error": "Daily limit exceeded. Upgrade your plan or try in 24 hours.",
  "retryAfter": 86400,
  "limit": 100
}

413 File Too Large

{
  "error": "Video file too large. Maximum size is 150MB"
}

Retry Logic Example

async function processVideoWithRetry(
  videoUrl: string,
  parameters: object,
  apiKey: string,
  maxRetries = 3,
) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await processVideo(videoUrl, parameters, apiKey);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}

Best Practices

  1. Valid URLs: Ensure media URLs are publicly accessible and point directly to media files
  2. File Size: Keep video files under 150MB and image batches at 20 images or fewer
  3. File Formats: Use supported formats for the media type you are processing
  4. Error Handling: Always implement proper error handling for network and API errors
  5. Rate Limits: Be mindful of rate limits and implement retry logic with exponential backoff
  6. API Keys: Keep your API keys secure and never commit them to version control

Rate Limits

Please refer to the Rate Limits documentation for information about API rate limits and best practices.

Upload Video for Remix

Process a video from a provided URL. The API will download the video, apply transformations, and remove invisible watermarks.

Upload Images for Remix

Process one or more images from provided URLs. The API will download the images, apply transformations, and remove invisible watermarks.