# Dcard Full Threads — Posts & Nested Public Replies (`bakos_bence/dcard-full-threads`) Actor

Export one row per public Dcard thread with post detail, root comments, nested replies, and honest completeness metadata. Public logged-out data only. Unofficial; not affiliated with Dcard.

- **URL**: https://apify.com/bakos_bence/dcard-full-threads.md
- **Developed by:** [Bakos Bence](https://apify.com/bakos_bence) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 1,000 results

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?

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

### What does Dcard Full Threads do?

Export public Dcard discussions as one dataset row per thread, ready for bounded conversation analysis or moderation review.

- Post text, forum, timestamps, media URLs, and engagement counts
- Root comments with recursive nested replies in their original hierarchy
- Honest expected, returned, truncated, and error metadata for every thread

Only public logged-out data is read. School, department, gender, avatar, identity, nickname, and other natural-person profile fields are removed.

[Documentation](https://bakosbence.com/web-data-collection/dcard-full-threads/)

| Field | What it contains | Example |
| --- | --- | --- |
| `id` | Public thread ID | `262047730` |
| `url` | Stable public thread URL | `https://www.dcard.tw/f/mood/p/262047730` |
| `title` | Public thread title | `Public thread` |
| `content` / `excerpt` | Public post text | `Public body` |
| `forumId` / `forumAlias` / `forumName` | Public forum identifiers | `mood` |
| `topics` / `tags` | Public thread classifications | `["discussion"]` |
| `createdAt` / `updatedAt` | Post timestamps | `2026-01-01T00:00:00.000Z` |
| `likeCount` / `reactionCount` | Post engagement totals | `10` / `7` |
| `reactions` | Reaction-type counts | `{"heart": 7}` |
| `shareCount` / `quoteCount` / `collectionCount` | Other engagement totals | `2` / `1` / `3` |
| `commentCount` / `totalCommentCount` | Dcard's exposed comment totals | `2` / `2` |
| `mediaUrls` | Public post media links | `["https://..."]` |
| `nsfw` / `pinned` | Public post flags | `false` / `false` |
| `moderation` | Visible deletion and moderation state | `{"state": "visible"}` |
| `postCompleteness` | Whether full post content was available, plus its public source | `{"complete": false, "source": "public_feed_summary"}` |
| `comments` | Root comments with recursive `replies` | `[{"depth": 0, "replies": [...]}]` |
| `commentsCompleteness` | Counts, bounds, errors, and completeness verdict | `{"expected": 2, "returned": 2, "complete": true}` |

### How do I export full Dcard threads?

1. Click **Try for free**.
2. The default returns one public Mood-forum thread with comments disabled, keeping the first run quick and bounded.
3. Paste specific **Thread URLs** or other forum aliases and raise the comment limit when you need full post detail and recursive replies.
4. Click **Start**, then open the dataset and export JSON, CSV, or Excel.

### Input

| Field | Purpose | Default |
| --- | --- | --- |
| `threadUrls` | Public Dcard thread URLs or post IDs | empty |
| `forums` | Forum aliases used when URLs are empty | `mood` |
| `maxThreads` | Maximum dataset rows | `1` |
| `maxCommentsPerThread` | Combined root and nested comment bound; raise above zero to collect replies | `0` |
| `maxDepth` | Deepest retained reply level; roots are depth 0 | `8` |
| `maxRepliesPerComment` | Nested replies retained under one parent | `100` |
| `includeNsfw` | Include public threads marked NSFW | `false` |

Specific thread URLs take priority over forum feeds. The Start default uses the public Mood board. If that feed is empty or blocked, the Actor falls back to Dcard's global popular feed, then to a public topic page. Summary-only post data is marked incomplete in `postCompleteness`; it is never presented as a full post.

### Illustrative output

Each dataset item is one thread:

```json
{
  "id": 262047730,
  "url": "https://www.dcard.tw/f/mood/p/262047730",
  "title": "Public thread",
  "forumAlias": "mood",
  "likeCount": 10,
  "reactionCount": 7,
  "shareCount": 2,
  "quoteCount": 1,
  "comments": [
    {
      "id": "root-comment-id",
      "parentId": null,
      "depth": 0,
      "floor": 1,
      "content": "Root comment",
      "subCommentCount": 1,
      "replies": [
        {
          "id": "reply-id",
          "parentId": "root-comment-id",
          "depth": 1,
          "floor": 1,
          "content": "Nested reply",
          "replies": []
        }
      ]
    }
  ],
  "commentsCompleteness": {
    "expected": 2,
    "returned": 2,
    "rootReturned": 1,
    "nestedExpected": 1,
    "nestedReturned": 1,
    "complete": true,
    "truncated": false,
    "errors": []
  }
}
```

Every comment includes `parentId`, `depth`, `floor`, `subCommentCount`, like/reaction/share/quote counts, timestamps, and visible deletion or moderation state.

| Comment field | What it contains |
| --- | --- |
| `id` / `postId` / `parentId` | Comment, thread, and parent relationships |
| `depth` / `floor` | Recursive depth and Dcard floor |
| `content` / timestamps | Public comment text and timing |
| engagement counts | Likes, reactions, shares, and quotes |
| `subCommentCount` / `replies` | Expected direct children and recursively nested rows |
| `moderation` | Visible, hidden, in-review, or deleted state |

### How should I read completeness?

`commentsCompleteness.complete` is true only when pagination ended normally, no request failed, no configured bound was hit, and the returned count satisfies Dcard's expected count when one is exposed.

It is always false when:

- `maxCommentsPerThread`, `maxDepth`, or `maxRepliesPerComment` cuts the tree
- a root-comment or nested-reply request fails
- Dcard reports more comments than the Actor returned

Use `expected`, `returned`, `truncated`, and `errors` to decide whether a row is suitable for completeness-sensitive work. A bounded row remains useful, but is never mislabeled as complete.

### Privacy and access

The Actor reads public pages and public API responses without an account. It does not access member-only or login-gated content. Output intentionally excludes:

- school, department, and gender
- avatar and natural-person display/profile fields
- persona IDs, nicknames, and identity metadata

Thread and comment IDs remain because they identify public content, preserve hierarchy, and support deduplication.

### Reliability, proxy, and resume behavior

The Actor manages Apify UNBLOCKER automatically. Retries stay on a sticky session briefly, rotate on a bounded schedule, and stop at the run's HTTP-attempt budget.

Rows are pushed as each thread finishes. Resume state remembers saved thread IDs, so a migrated or resurrected run does not save and charge the same thread again. If the run's charge limit is reached, the Actor stops before processing another row.

### How much does it cost?

The Actor is designed for pay-per-result billing: one result is one thread row, regardless of the number of comments nested inside it. Current rates will appear on the **Pricing** tab after monetization is configured.

### FAQ

#### Why is a thread marked incomplete?

Check `commentsCompleteness.errors` and `limits`. The Actor either hit a configured bound, received fewer comments than Dcard advertised, or could not finish a public request.

#### Why are profile fields missing?

They are intentionally excluded. This Actor is for thread content and conversation structure, not profiling individual users.

#### Can I use this as a standing forum mirror?

No. Use bounded, customer-directed thread or forum inputs. The Actor is not designed for continuous bulk mirroring of Dcard content.

This Actor is not affiliated with Dcard.

# Actor input Schema

## `threadUrls` (type: `array`):

Paste public Dcard thread URLs or numeric post IDs. When supplied, these take priority over Forums.

## `forums` (type: `array`):

Enter Dcard forum aliases or forum URLs, for example <code>mood</code>. Used only when Thread URLs is empty. Default is the public Mood board.

## `maxThreads` (type: `integer`):

Set the maximum number of thread rows saved across all inputs.

## `maxCommentsPerThread` (type: `integer`):

Set the combined root-comment and nested-reply cap for each thread. The quick default is 0; increase it to collect comments. A thread that hits this cap is marked truncated and incomplete.

## `maxDepth` (type: `integer`):

Set the deepest nested reply level to retain. Root comments have depth 0. Hitting this bound marks the thread truncated.

## `maxRepliesPerComment` (type: `integer`):

Set the per-parent nested-reply bound. Hitting this bound marks the thread truncated.

## `includeNsfw` (type: `boolean`):

Turn on to include public threads marked NSFW. Login-only content is never accessed.

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

Use as an API-compatible alias for Thread URLs. Leave empty in the Console form.

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

Use as an API-compatible alias for Maximum threads when maxThreads is omitted.

## `maxHttpAttempts` (type: `integer`):

Bound the total request and retry budget, including failed UNBLOCKER attempts.

## `proxyConfiguration` (type: `object`):

Managed by the Actor; leave default. Apify UNBLOCKER is forced in code and user proxy changes are ignored.

## Actor input object example

```json
{
  "threadUrls": [],
  "forums": [
    "mood"
  ],
  "maxThreads": 1,
  "maxCommentsPerThread": 0,
  "maxDepth": 8,
  "maxRepliesPerComment": 100,
  "includeNsfw": false,
  "startUrls": [],
  "maxItems": 1,
  "maxHttpAttempts": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset items.

# 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 = {
    "threadUrls": [],
    "forums": [
        "mood"
    ],
    "maxThreads": 1,
    "maxCommentsPerThread": 0,
    "maxDepth": 8,
    "maxRepliesPerComment": 100,
    "includeNsfw": false,
    "startUrls": [],
    "maxItems": 1,
    "maxHttpAttempts": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bakos_bence/dcard-full-threads").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 = {
    "threadUrls": [],
    "forums": ["mood"],
    "maxThreads": 1,
    "maxCommentsPerThread": 0,
    "maxDepth": 8,
    "maxRepliesPerComment": 100,
    "includeNsfw": False,
    "startUrls": [],
    "maxItems": 1,
    "maxHttpAttempts": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("bakos_bence/dcard-full-threads").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 '{
  "threadUrls": [],
  "forums": [
    "mood"
  ],
  "maxThreads": 1,
  "maxCommentsPerThread": 0,
  "maxDepth": 8,
  "maxRepliesPerComment": 100,
  "includeNsfw": false,
  "startUrls": [],
  "maxItems": 1,
  "maxHttpAttempts": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}' |
apify call bakos_bence/dcard-full-threads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bakos_bence/dcard-full-threads"
        }
    }
}
```

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/7nXlNX3dBSRXwmLrr/builds/nT1eXMNZrsMKEKUmt/openapi.json
