# Dailymotion Scraper — Videos, Profiles & Search API (`funny_ground/dailymotion-scraper`) Actor

Export public Dailymotion videos from direct URLs, creator profiles, category channels and keyword search. Get titles, authors, native engagement counters and thumbnail URLs using efficient HTTP requests.

- **URL**: https://apify.com/funny_ground/dailymotion-scraper.md
- **Developed by:** [Coor Yu](https://apify.com/funny_ground) (community)
- **Categories:** Social media, Videos
- **Stats:** 3 total users, 2 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 public video results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Dailymotion Scraper — Videos, Profiles & Search API

Extract **public Dailymotion video data** from direct video URLs or IDs, creator profiles, category channels and keyword search. Export titles, descriptions, publish times, authors, source-labelled view/like/comment counters, tags and thumbnail URLs to an Apify dataset for research, reporting or content discovery.

The Actor uses **Dailymotion's native public HTTP API**. No Dailymotion login, cookies, browser, proxy, paid external API or downstream Actor is required. An Apify account/token is needed to run it through Apify.

### Quick start

For one public video:

```json
{
  "videoUrls": ["https://www.dailymotion.com/video/x3rdtfy"],
  "maxItems": 1
}
```

For a mixed batch:

```json
{
  "startUrls": [
    { "url": "https://dai.ly/x3rdtfy" },
    { "url": "https://www.dailymotion.com/NASA" },
    { "url": "https://www.dailymotion.com/search/space/videos" }
  ],
  "channels": ["travel"],
  "resultsPerInput": 5,
  "maxItems": 15,
  "maxConcurrency": 4,
  "failOnPartialFailure": false
}
```

These were working public targets during implementation tests; content and availability can change.

#### What each source means

- **Direct videos:** `videoUrls` accepts public `x`-prefixed IDs, `/video/{id}` links, `/embed/video/{id}` links and `dai.ly/{id}` links. A direct input requests one video. The returned ID must exactly match the requested ID.
- **Creator profiles/channels:** `profiles` accepts usernames, user IDs or profile URLs, such as `NASA` or `https://www.dailymotion.com/NASA`. It returns available public videos, not a standalone comprehensive profile report. A small identity request resolves the stable owner ID; every returned video must match that ID.
- **Category channels:** `channels` accepts Dailymotion category IDs such as `travel`, `news` and `music`, or `/channel/{category}` URLs. These are site-wide categories, **not creators**. Use `profiles` for a creator's channel.
- **Keywords:** `searchKeywords` runs native Dailymotion video search. Ranking is source-defined and may vary with time or region.
- **Hashtags:** `hashtags: ["space"]` runs a **broad keyword search for `#space`**, not an exact hashtag feed. Results may match ordinary keywords without containing that hashtag. This limitation is explicit in each row's `provenance.querySemantics`. Output `hashtags` are extracted from actual video text or explicitly `#`-prefixed native tags, not copied from your input.
- **Mixed URLs:** `startUrls` recognizes the routes above, `/user/{username}`, `/username/videos`, `/search/{query}/videos` and `/search?q={query}`. It accepts strings or `{ "url": "..." }` objects. Unsupported hosts, homepage/playlist/login routes, malformed URLs and empty targets are ignored with warnings. At least one usable target must remain.

Duplicate seeds are collapsed where identifiable. Videos are deduplicated globally by native ID before saving. If sources overlap, the **first successfully saved source** supplies attribution; concurrent runs do not guarantee input-order attribution. A matching video already saved by another source counts as found but is not saved or billed again.

### Pricing and budget controls

**$0.0005 per saved video — $0.50 per 1,000 results — flat across all pricing tiers. No startup fee.** The published Apify Pricing tab is authoritative.

**Running users separately pay Apify platform usage**, including compute, transfer and storage. The result price is not an all-inclusive platform-usage price. Retries and empty/failed runs can still incur platform usage.

One unique saved default-dataset video row is one result. Empty/error inputs, rejected records, duplicate videos and `RUN_SUMMARY` do not create result charges. Already-saved rows remain available and billable if strict partial-failure handling later makes the run fail.

The Apify SDK automatically charges the synthetic `apify-default-dataset-item` event on `Actor.pushData(rows)`. The Actor does **not** manually charge that event, double-charge rows or charge per HTTP request. Remaining result-charge capacity is checked through the SDK's charging manager, alongside Apify's maximum-paid-dataset-items setting. Dataset writes are serialized; concurrent requests reserve available result capacity before fetching.

#### Developer-set Free-plan cap

When Apify explicitly reports an unpaid platform account (`APIFY_IS_AT_HOME=1` and `APIFY_USER_IS_PAYING=0`), a **global cap of 50 saved rows per run** applies. This is the Actor developer's policy, not a universal Apify platform limit. Paid-plan and unknown-status runs have no developer 50-row cap. The per-result price still applies; a Free plan does not mean zero-priced results.

### Input reference

Every target array defaults to `[]`. Each array is limited to **200 entries**, and the combined total is limited to **500 entries**. Search text is limited to 300 characters. Provide at least one supported, non-empty target.

| Field | Default | Meaning |
|---|---:|---|
| `startUrls` | `[]` | Mixed supported Dailymotion URLs, as strings or `{ "url": "..." }`. |
| `videoUrls` | `[]` | Public direct video URLs or IDs; at most one matching row per direct source. |
| `profiles` | `[]` | Creator usernames, user IDs or profile URLs. |
| `channels` | `[]` | Category IDs/URLs, not creator usernames. |
| `searchKeywords` | `[]` | Native video-search queries. |
| `hashtags` | `[]` | Tag names with/without `#`, using broad keyword-search semantics. |
| `resultsPerInput` | `50` | `0–1,000` distinct valid videos examined per feed/query **before global deduplication**. `0` means up to the safety cap of 1,000, not unlimited history. |
| `maxItems` | `100` | Global unique saved-row limit, `1–10,000`; charge, platform and Free-plan caps can reduce it. |
| `failOnPartialFailure` | `false` | Make an attempted empty/error/partially failed source fail the whole run when `true`. |
| `maxConcurrency` | `4` | `1–16` lightweight HTTP sources. Output reservations reduce effective concurrency for small budgets. |
| `requestTimeoutSecs` | `25` | Per-request timeout including the body, `5–120` seconds. |
| `maxRetries` | `2` | `0–3` retries after transient transport/timeouts or HTTP/API `408`, `425`, `429` and `5xx` failures only. Permanent `400/401/403/404` responses are not retried. |
| `maxPagesPerInput` | `10` | `1–10` native pages per feed/query, at most 100 videos per page. Page size stays constant within each source. |
| `maxRequests` | `200` | `1–1,000` actual outbound requests globally, including identity requests, retries and redirects. |
| `maxRunTimeSecs` | `300` | Collection runtime bound, `10–1,800` seconds; an earlier Apify timeout takes precedence with shutdown headroom. |

Counts are **upper bounds**, not promised result counts. Empty or repeated pages stop pagination. The native catalog, page, request, runtime and charge limits mean a profile or search is **not guaranteed to return complete history**. Invalid records and cross-source duplicates can reduce delivered counts. Inputs after an exhausted output budget can be skipped; no new API requests are started after the limit is observed, although already-in-flight requests may complete.

### Output fields and numeric semantics

One dataset row is one real, explicitly public and published native video record. A numeric play count is **not required** when the API omits it.

| Field | Meaning |
|---|---|
| `platform` | Always `dailymotion`. |
| `videoId`, `webVideoUrl` | Native ID and canonical public video link. |
| `title`, `description`, `text` | Plain text; `text` combines title/description without duplicating an identical description. |
| `createTimeISO` | Native `created_time` converted to UTC ISO, or `null`; never inferred from the ID. |
| `duration` | Source-reported duration in seconds, or `null`. An explicit source zero is retained, including on live-event metadata. |
| `author` | Available stable ID, username (`uniqueId`), display name (`nickname`), URL, avatar and explicitly supplied verification boolean. Missing values are omitted, not defaulted to zero/false. |
| `stats.playCount` | Native `views_total`, or `null`. |
| `stats.diggCount` | Native `likes_total`, or `null`. The TikTok-compatible field name means Dailymotion likes here. |
| `stats.commentCount` | Native `comments_total`, or `null`. |
| `stats.shareCount`, `stats.collectCount` | `null`: reliable public share/save counters are not supplied by this implementation. |
| `statsPrecision` | `native-api` if at least one valid counter is supplied; `unavailable` if all requested counters are missing/invalid. |
| `hashtags`, `mentions` | Actual textual `#tags`/`@mentions`; mentions are not verified account identities. |
| `tags` | Native video tags, which can be phrases and are not necessarily hashtags. |
| `coverUrl` | Available public Dailymotion-CDN thumbnail URL; not a stored image file and may expire. |
| `sourceType`, `sourceInput` | `direct`, `profile`, `channel`, `search` or `hashtag`, plus normalized source attribution without URL tracking parameters. |
| `scrapedAt`, `provenance` | Collection timestamp, public native endpoint, counter-field mapping, stable profile owner ID when applicable, and search semantics. |
| `contentType` | Native `mode`, such as `vod` or `live`, when available. |

`native-api` identifies **source-reported unrounded values**, not independently audited accuracy, real-time freshness or proof that every counter is available. Explicit numeric zeroes are retained; missing, negative, invalid or unsafe counters become `null`. Generic native `tags` are never blindly relabelled as hashtags.

Music and follower totals are omitted because this implementation has no reliable supported source for them. No fabricated soundtrack, verification or follower values are added.

Export the dataset as JSON, CSV or Excel from Apify. API clients can read their run's dataset through `GET https://api.apify.com/v2/datasets/{datasetId}/items` with the real dataset ID and appropriate Apify authentication.

### Status and failure rules

`RUN_SUMMARY` in the default Key-Value Store is a **non-result** report with per-input statuses, saved-row count, HTTP request/retry totals, stop reasons and warnings.

| Situation | Run outcome |
|---|---|
| No usable input | `FAILED`, no data rows. |
| All usable inputs produce zero saved rows | `FAILED` in either strictness mode. |
| Valid data plus an empty/deleted/missing/blocked source | Platform success with `RUN_SUMMARY.status: SUCCEEDED_WITH_WARNINGS` by default. |
| Same mixed batch with `failOnPartialFailure: true` | `FAILED`; already-saved rows remain available and billable. |
| Sources intentionally skipped at an output/charge/run budget | Reported as skipped, not source failures; zero saved rows still fails. |
| Unrecoverable dataset write error | `FAILED`; ambiguous writes are not retried to avoid duplicate rows or charges. |

`SUCCEEDED_WITH_WARNINGS` is the summary's descriptive status; Apify's platform status is `SUCCEEDED` for such runs. Empty results are **not proof of deletion**: the source may be private, region-restricted, unavailable, empty or temporarily blocked. Partial failures after an earlier successful page preserve already-saved data.

### Efficiency, safety and limitations

- Feed/search pages already contain output metadata: no detail request per video. Profiles add one small stable-identity request. Memory holds at most one page per worker plus a bounded ID set; recommended allocation is **256 MB**, with 512 MB available for headroom.
- The Actor fetches only allowlisted HTTPS native API routes. User-supplied URLs are parsed into known IDs/queries, never fetched as arbitrary destinations. Credentials/nonstandard ports/lookalike hosts are rejected; every redirect is revalidated. Response bodies are capped at 4 MiB.
- Transient retries use bounded backoff and bounded `Retry-After`; all attempts consume the request budget. There is no browser or residential-proxy fallback. If Dailymotion blocks or changes its anonymous API, some/all inputs can fail.
- Metadata availability **does not guarantee current playback**, including archived live events. No login, age/region/private-content bypass or DRM bypass is provided.
- This Actor **does not download cover files or full videos**, provide raw MP4 URLs, or extract audio/music. Sending `shouldDownloadVideos: true` or `shouldDownloadCovers: true` fails explicitly instead of silently promising a download. Public thumbnail references are returned when available.

### Development and verification

Requires Node.js **22+**.

```sh
npm ci
npm test
npm audit --omit=dev
npm run smoke
npm run smoke:sdk
```

`npm test` is deterministic and offline; it does not call Apify. `npm run smoke` makes small real anonymous native-API requests and writes datasets/summaries under `.smoke/`, without invoking an Apify Actor. `npm run smoke:sdk` tests the actual SDK entrypoint using isolated **local storage**, a clean environment without inherited Apify credentials, zero-data failure, mixed warnings and simulated local PPE capacity. Local PPE simulation is not evidence of a paid user's real billing.

`npm start` runs the entrypoint with the Apify SDK. For local input, use the SDK's local default Key-Value Store `INPUT.json`; leave `APIFY_IS_AT_HOME` unset locally. Do not reuse a real cloud run/storage environment for local tests.

Collect and use public data in accordance with applicable law and platform terms.

# Actor input Schema

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

Mixed video, dai.ly, creator /username, /user/username, /channel/category and /search/query/videos URLs. Only exact Dailymotion hosts and supported routes are accepted. At most 200 entries per array and 500 across all arrays. Other URLs are ignored with warnings.

## `videoUrls` (type: `array`):

Public x-prefixed video IDs, canonical video URLs, embed/video URLs or dai.ly links. Each direct input requests at most one real public video. Private, deleted and unavailable videos produce no row.

## `profiles` (type: `array`):

Dailymotion usernames, user IDs or profile URLs. Returns available public videos, not a complete standalone profile report. This is the field for creator channels such as NASA.

## `channels` (type: `array`):

Dailymotion CATEGORY IDs such as travel, news or music, or /channel/category URLs. These are site-wide category feeds, NOT creator channels; use profiles for creators.

## `searchKeywords` (type: `array`):

Non-empty native video-search queries, at most 300 characters each. Ranking and availability depend on Dailymotion and may vary by time or region.

## `hashtags` (type: `array`):

Tag names with or without #. Each becomes a native keyword query for #tag. Results can match ordinary keywords and are NOT guaranteed to contain the hashtag. The query semantics are included in provenance. Output hashtags are extracted from actual text, independently of this input.

## `resultsPerInput` (type: `integer`):

Maximum distinct valid videos examined for each feed/query before cross-source deduplication, 0–1,000. 0 means up to the safety cap of 1,000, not unlimited history. Direct inputs always request one. Page, run, request, charge and global output limits still apply.

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

Global unique dataset-row cap across all sources. Duplicates do not consume this cap. Free-plan and Apify charge/result caps can reduce the effective limit. Collection stops making new requests when the output budget is exhausted.

## `failOnPartialFailure` (type: `boolean`):

False: successful data plus empty/unavailable/partially failed sources succeeds with warnings in RUN_SUMMARY. True: any attempted empty/error/partially failed source fails the run, even if rows were saved. Inputs intentionally skipped because a run/output/charge budget was reached are not treated as source failures. Zero saved rows always fails.

## `maxConcurrency` (type: `integer`):

1–16 lightweight native API requests. Output reservations may reduce effective concurrency for small result/charge budgets. Dataset writes are always serialized.

## `requestTimeoutSecs` (type: `integer`):

Per-request timeout, including response body. Remaining runtime can shorten it.

## `maxRetries` (type: `integer`):

Bounded retries after network failures/timeouts and HTTP/API 408, 425, 429 or 5xx responses only. Permanent 400/401/403/404 responses are not retried. Retries consume maxRequests.

## `maxPagesPerInput` (type: `integer`):

1–10 pages per profile/category/search input, at most 100 videos per page. Page size stays constant within a source. This is not a complete-history guarantee.

## `maxRequests` (type: `integer`):

1–1,000 actual outbound requests across all sources, including retries and validated redirects. Native API pages return full metadata without per-item detail calls.

## `maxRunTimeSecs` (type: `integer`):

10–1,800 seconds for collection, with additional early stop before Apify's hard timeout. Storage writes and final status handling can add a small amount of time.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.dailymotion.com/video/x3rdtfy"
    }
  ],
  "videoUrls": [
    "x3rdtfy",
    "https://www.dailymotion.com/video/x3rdtfy"
  ],
  "profiles": [
    "NASA"
  ],
  "channels": [
    "travel"
  ],
  "searchKeywords": [
    "space"
  ],
  "hashtags": [
    "space"
  ],
  "resultsPerInput": 50,
  "maxItems": 100,
  "failOnPartialFailure": false,
  "maxConcurrency": 4,
  "requestTimeoutSecs": 25,
  "maxRetries": 2,
  "maxPagesPerInput": 10,
  "maxRequests": 200,
  "maxRunTimeSecs": 300
}
```

# Actor output Schema

## `results` (type: `string`):

Unique public Dailymotion video rows; empty/error inputs are not dataset items.

## `summary` (type: `string`):

Non-billable RUN_SUMMARY with saved-row counts, errors, limits and per-input statuses.

# 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://www.dailymotion.com/video/x3rdtfy"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("funny_ground/dailymotion-scraper").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://www.dailymotion.com/video/x3rdtfy" }] }

# Run the Actor and wait for it to finish
run = client.actor("funny_ground/dailymotion-scraper").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://www.dailymotion.com/video/x3rdtfy"
    }
  ]
}' |
apify call funny_ground/dailymotion-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,funny_ground/dailymotion-scraper"
        }
    }
}
```

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/FQBcDEIZszbCvcT8C/builds/dddwGIa4ormaADcdZ/openapi.json
