# Txxx Video Downloader (`automation-lab/txxx-video-downloader`) Actor

Download authorized public Txxx videos to Apify storage with duration, dimensions, thumbnails, provenance, and exact file metadata.

- **URL**: https://apify.com/automation-lab/txxx-video-downloader.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 88.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Txxx Video Downloader

Download authorized, anonymously reachable public Txxx videos into Apify storage and export a clean metadata record for every successful file.

The Actor accepts supplied `txxx.com` video page URLs.
It resolves each public source-quality MP4, optionally copies the file into the run key-value store, and writes provenance and media metadata to the default dataset.
This makes recurring archival jobs easier to audit than a list of short-lived direct media links.

> Use this Actor only for content you are legally allowed to access, copy, and retain.
> It does not bypass login, payment, DRM, private-video controls, or access restrictions.

### What does Txxx Video Downloader do?

For each supported public video URL, the Actor:

1. validates that the URL belongs to `https://txxx.com`;
2. verifies that the source reports the video as public and available;
3. extracts the video ID, title, description, duration, thumbnail, publication time, and categories;
4. resolves a fresh source-hosted MP4 URL;
5. looks up source dimensions when available;
6. optionally streams the MP4 into the run key-value store;
7. records exact stored bytes and a stable Apify storage link;
8. emits one typed dataset row; and
9. deduplicates repeated video IDs within the run.

The default behavior stores files.
Set `saveVideos` to `false` when you need a metadata inventory before deciding what to archive.

### Who is it for?

- **Authorized archivists** preserving public media with source provenance.
- **Content owners** backing up their own public uploads.
- **Compliance teams** collecting permitted evidence with a retrieval timestamp.
- **Researchers** inventorying supplied public URLs before a bounded download.
- **Automation teams** scheduling recurring URL batches and exporting results to a data pipeline.

This is a URL-driven downloader, not a site search crawler.
It processes only the videos you explicitly supply.

### Why use this Actor?

A direct source URL alone can expire and says little about the archived item.
This Actor pairs the saved file with:

- the stable Txxx video ID;
- the canonical source page;
- title and description;
- source duration and pixel dimensions;
- thumbnail and categories;
- resolved media MIME type;
- key-value store record key;
- exact copied byte count; and
- the time the record was produced.

Files are streamed with a configurable byte limit.
An oversized or unavailable source is skipped rather than saved partially.
Successful records are not charged twice when the same ID appears more than once.

### What data does it return?

| Field | Type | Meaning |
| --- | --- | --- |
| `videoId` | string | Stable numeric Txxx video ID |
| `title` | string | Public source title |
| `description` | string or null | Public description when available |
| `duration` | string or null | Source-formatted duration |
| `durationSeconds` | number or null | Duration normalized to seconds |
| `width` | number or null | Source width in pixels when available |
| `height` | number or null | Source height in pixels when available |
| `thumbnailUrl` | string | Public source thumbnail |
| `sourceUrl` | string | Canonical Txxx video page |
| `mediaUrl` | string | Fresh source-hosted MP4 URL; it may expire |
| `contentType` | string | Resolved media MIME type |
| `videoFileKey` | string or null | Run storage key when file saving is enabled |
| `videoFileUrl` | string or null | Apify API URL for the stored MP4 |
| `videoSizeBytes` | number or null | Exact number of stored bytes |
| `publishedAt` | string or null | Source publication time when available |
| `categories` | string\[] | Public source category labels |
| `scrapedAt` | string | ISO 8601 retrieval timestamp |

Nullable fields remain `null` when the source does not expose them.
The default dataset always contains the primary result records.
Downloaded MP4s are stored under keys such as `video-3436969.mp4`.

### How to download public Txxx videos

1. Open the Actor in Apify Console.
2. Add one or more public `https://txxx.com/videos/...` URLs to **Txxx video URLs**.
3. Keep **Save video files** enabled to copy each MP4 into run storage.
4. Set **Maximum video size (MB)** to a limit appropriate for your authorization and storage budget.
5. Set **Maximum videos** to bound successful results.
6. Click **Start**.
7. Open **Video metadata** for dataset rows.
8. Open **Saved video files** for stored MP4 records.

Start with one known URL.
Then increase the batch only after confirming file size and retention requirements.

### Input parameters

#### `startUrls`

Required array of public Txxx video page URLs.
Each URL must use HTTPS and match this shape:

```text
https://txxx.com/videos/{numericVideoId}/{slug}/
```

`www.txxx.com` is accepted and normalized to `txxx.com`.
Other sites, direct CDN links, search pages, private pages, and malformed paths are rejected.

#### `maxItems`

Maximum number of unique successful rows.
Allowed range: 1–100.
The default is the number of supplied URLs, capped by schema defaults in Console.
Failures do not consume this success limit.

#### `saveVideos`

When `true`, the Actor copies MP4 bytes into the run key-value store.
When `false`, it emits metadata and a fresh source media URL without storing the file.
The default is `true`.

#### `maxVideoSizeMb`

Per-file limit from 1 MB to 10 MB.
The default is 10 MB.
A source that exceeds the 10 MB safety ceiling is skipped and no partial record is retained.

### Example input

```json
{
  "startUrls": [
    {
      "url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/"
    }
  ],
  "maxItems": 1,
  "saveVideos": true,
  "maxVideoSizeMb": 10
}
```

For a metadata-only inventory:

```json
{
  "startUrls": [
    {
      "url": "https://txxx.com/videos/8780704/erin-avery-an-exceptional-example-of-instance/"
    }
  ],
  "maxItems": 1,
  "saveVideos": false
}
```

### Example output

The exact file URL and timestamp differ by run.
This shortened record reflects real current fields:

```json
{
  "videoId": "3436969",
  "title": "Example of a Female led marriage",
  "description": null,
  "duration": "04:56",
  "durationSeconds": 296,
  "width": 342,
  "height": 240,
  "thumbnailUrl": "https://tn.txxx.tube/contents/videos_screenshots/3436000/3436969/288x162/1.jpg",
  "sourceUrl": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/",
  "contentType": "video/mp4",
  "videoFileKey": "video-3436969.mp4",
  "videoSizeBytes": 5374369,
  "categories": ["Femdom", "Russian", "Slave"],
  "scrapedAt": "2026-08-17T07:00:00.000Z"
}
```

The `mediaUrl` is intentionally omitted from this documentation example because source download tokens expire.
Use the row produced by your run.

### How much does it cost to download public Txxx videos?

The Actor uses pay-per-event pricing:

- one `start` event is charged once per run; and
- one `item` event is charged for each unique successful dataset record.

Files, thumbnails, and metadata in the same row have no separate Actor event charge.
Failed, duplicate, private, removed, malformed, or oversized inputs do not receive an `item` charge.

Current pricing is a **$0.005 start fee** plus tiered item pricing.
At the BRONZE tier, the item price is **$0.0036 per successful video**.
The live pricing panel is authoritative and shows volume discounts across FREE, BRONZE, SILVER, GOLD, PLATINUM, and DIAMOND tiers.

Examples at the BRONZE rate:

| Successful videos | Actor event price |
| ---: | ---: |
| 1 | $0.0086 |
| 5 | $0.0230 |
| 10 | $0.0410 |
| 25 | $0.0950 |
| 100 | $0.3650 |

Apify platform compute and storage usage may also apply according to your plan.
Large video files consume more transfer, run time, and storage than metadata-only mode.
Use `maxVideoSizeMb` and retention settings deliberately.

### Batch and recurring archival workflow

A practical recurring workflow is:

1. maintain an authorized list of public source URLs;
2. send the current list to a scheduled Actor task;
3. use `maxItems` as a run-level safety bound;
4. store files only when the archive requires them;
5. export dataset rows to your inventory system;
6. compare `videoId`, `videoSizeBytes`, and `scrapedAt` with prior runs; and
7. apply an Apify storage retention policy matching your obligations.

The Actor deduplicates only within one run.
Perform cross-run retention and change tracking in your downstream system or scheduled workflow.

### Integrations

Connect the default dataset to:

- Google Sheets for a lightweight inventory;
- webhooks for post-run processing;
- Make or Zapier for workflow orchestration;
- a database or object catalog for provenance tracking;
- Python or JavaScript jobs using `apify-client`; or
- another Actor for authorized downstream processing.

Treat `videoFileUrl` as an authenticated Apify API resource unless your storage settings make it public.
Do not publish storage tokens or signed source media URLs.

### Run with the Apify API using cURL

Replace `YOUR_TOKEN` with an Apify API token:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~txxx-video-downloader/runs?token=YOUR_TOKEN&waitForFinish=300" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/"}],
    "maxItems": 1,
    "saveVideos": true,
    "maxVideoSizeMb": 10
  }'
```

Read items from the run's `defaultDatasetId`.
Read files from its `defaultKeyValueStoreId`.

### Run with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/txxx-video-downloader').call({
    startUrls: [
        { url: 'https://txxx.com/videos/3436969/example-of-a-female-led-marriage/' },
    ],
    maxItems: 1,
    saveVideos: true,
    maxVideoSizeMb: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Use `client.keyValueStore(run.defaultKeyValueStoreId)` to inspect stored records.

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/txxx-video-downloader').call(run_input={
    'startUrls': [
        {'url': 'https://txxx.com/videos/3436969/example-of-a-female-led-marriage/'},
    ],
    'maxItems': 1,
    'saveVideos': True,
    'maxVideoSizeMb': 10,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

The returned run object also contains the default key-value store ID.

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/txxx-video-downloader"
```

Claude Desktop, Cursor, and VS Code can use the equivalent JSON configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/txxx-video-downloader"
    }
  }
}
```

Example prompts:

- "Run Txxx Video Downloader for these authorized public URLs and save files up to 10 MB."
- "Resolve this supplied public Txxx URL in metadata-only mode and return duration and dimensions."
- "Archive this bounded list, then summarize successful file sizes and failed URLs."

Always include actual authorized URLs in the Actor input.
The Actor does not search Txxx by keyword.

### Limits and failure behavior

- Only public HTTPS `txxx.com/videos/...` pages are supported.
- A fresh media path is resolved on every run because source links can expire.
- Dimensions are best-effort and can be `null` if the source listing no longer exposes them.
- Private, removed, restricted, malformed, and non-Txxx URLs are skipped.
- Videos larger than 10 MB are rejected before storage so slow source delivery stays within the run's cost and timeout envelope.
- If every supplied URL fails, the Actor run fails with a non-zero status.
- Upstream transient requests receive bounded retries.
- No residential proxy or browser fallback is enabled.
- The Actor does not bypass DRM, authentication, payment, or geofencing.
- Maximum successful rows per run are limited to 100.

Source changes can temporarily affect availability.
A failed URL does not prove that another public URL is unavailable.

### Tips for reliable runs

- Test one URL before submitting a batch.
- Prefer canonical page URLs copied from the address bar.
- Keep a conservative `maxVideoSizeMb` until you know expected sizes.
- Use metadata-only mode to estimate a batch without copying files.
- Schedule batches with explicit URL lists rather than broad discovery.
- Keep Apify storage private unless publication is intentional.
- Configure storage retention after export.
- Store `videoId` as the cross-run deduplication key.
- Do not rely on the expiring `mediaUrl` as your durable archive.
- Use `videoFileUrl` and the run's key-value store for the retained copy.

### Responsible and legal use

You are responsible for ensuring that your use complies with:

- copyright and license terms;
- the source website's terms and access rules;
- privacy and data-protection law;
- age and adult-content regulations;
- record-retention obligations; and
- Apify's terms and acceptable-use policies.

Only process content you own or have permission or another lawful basis to copy.
Do not use the Actor to redistribute content, evade controls, harass people, or collect prohibited material.
The Actor is a technical automation tool and does not grant rights in source media.

### Troubleshooting

#### Why did my run say no videos were saved?

Check that every input is a canonical public Txxx video page.
The video may be private, removed, unavailable, restricted, oversized, or temporarily inaccessible.
Run one URL with a larger but still responsible file limit to isolate the cause.

#### Why are `width` and `height` null?

The source detail response does not always include dimensions.
The Actor performs a best-effort listing lookup by exact video ID.
The file can still be resolved and stored when that enrichment is unavailable.

#### Why is `videoFileUrl` null?

`saveVideos` was set to `false`.
Enable it and rerun with a sufficient `maxVideoSizeMb` limit.

#### Why does `mediaUrl` stop working later?

It is a fresh source-hosted URL with an expiry token.
Use the stored `videoFileUrl` for the durable run copy.

#### Are duplicate URLs charged twice?

No.
The Actor deduplicates by numeric video ID within the run and emits one successful item.

### FAQ

#### Can it search Txxx?

No.
The accepted product scope is supplied public video URLs.

#### Can it download private or paid videos?

No.
It supports only anonymously reachable public media.

#### Does it save thumbnails separately?

No.
The dataset includes the public thumbnail URL; only the MP4 is copied to run storage.

#### Can I disable file storage?

Yes.
Set `saveVideos` to `false` for metadata-only output.

#### Where are downloaded files stored?

In the run's default key-value store under `video-{videoId}.mp4`.

#### Is a successful run proof that I may reuse the content?

No.
Technical accessibility and legal permission are different questions.

### Related Automation Lab Actors

- [Snapchat Public Video Downloader](https://apify.com/automation-lab/snapchat-public-video-downloader) for authorized public Spotlight archival.
- [M3U8 Playlist Downloader](https://apify.com/automation-lab/m3u8-playlist-downloader) for user-supplied, authorized public HLS playlists.
- [Web Image Downloader](https://apify.com/automation-lab/web-image-downloader) for copying public images with source metadata.

Choose the source-specific Actor when it matches the supplied URL.
Use the generic playlist downloader only when you already have an authorized public HLS manifest.

### Support

When reporting an issue, include:

- one affected public page URL;
- whether `saveVideos` was enabled;
- the configured size limit;
- the run ID; and
- the exact error message.

Do not send credentials, private URLs, API tokens, or personal data.

# Actor input Schema

## `startUrls` (type: `array`):

Public HTTPS txxx.com video page URLs to process. Private, removed, permissioned, and non-Txxx URLs are rejected.

## `maxItems` (type: `integer`):

Maximum number of unique successful video records to emit.

## `saveVideos` (type: `boolean`):

Copy each resolved public MP4 into the run key-value store. Disable this for a metadata-only inventory.

## `maxVideoSizeMb` (type: `integer`):

Per-video safety limit. Oversized files are skipped rather than partially stored.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/"
    }
  ],
  "maxItems": 10,
  "saveVideos": true,
  "maxVideoSizeMb": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing one record per successfully resolved video.

## `files` (type: `string`):

Run key-value store containing MP4 files when saving is enabled.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/"
        }
    ],
    "maxItems": 10,
    "saveVideos": true,
    "maxVideoSizeMb": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/txxx-video-downloader").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/" }],
    "maxItems": 10,
    "saveVideos": True,
    "maxVideoSizeMb": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/txxx-video-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://txxx.com/videos/3436969/example-of-a-female-led-marriage/"
    }
  ],
  "maxItems": 10,
  "saveVideos": true,
  "maxVideoSizeMb": 10
}' |
apify call automation-lab/txxx-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/txxx-video-downloader"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/TgkV0j4tjZUb4JSCc/builds/TFQH7mDSxomcQrgfL/openapi.json
