# Mastodon (`canadesk/mastodon`) Actor

Collect public posts, trends, hashtag timelines, accounts and hashtags from mastodon.social. Supports single queries, keyword lists and continuation IDs.

- **URL**: https://apify.com/canadesk/mastodon.md
- **Developed by:** [Canadesk Support](https://apify.com/canadesk) (community)
- **Categories:** SEO tools, News
- **Features:** Full permissions
- **Stats:** 32 total users, 3 monthly users, 34.9% runs succeeded, 6 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 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.

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

Collect public posts, trending conversations, hashtag timelines, accounts and hashtags from **mastodon.social**. Run one query or a list, download structured results, and continue from a saved post ID.

### Features

| **Process** | **What you get** |
| :--- | :--- |
| Get Trends | Public posts currently trending on mastodon.social |
| Get Statuses by Username | Public posts for an exact username or federated account address, excluding replies |
| Get Timelines by Tag | Public posts containing a hashtag |
| Search for Usernames | Matching accounts with profile details and available follower counts |
| Search for Hashtags | Matching hashtags and their available activity history |

Post results include the source's available text, timestamps, links, engagement counts, media references, tags and mentions. Results reflect what mastodon.social knows; they are not an exhaustive archive of every Mastodon server.

### Get started

Choose a process, enter one or more keywords, and select the maximum pages per query.

```json
{
  "process": "gt",
  "keywords": ["@Mastodon@mastodon.social", "@Gargron@mastodon.social"],
  "maximum": 2,
  "pause": 1000
}
```

For hashtag timelines, choose `gi` and enter tags such as `cats` or `photography`. For trends, choose `gr`; no keyword is needed. Existing inputs using `keyword` and `last_id` also work.

Posts and hashtag timelines return up to 40 items per page; trends return up to 20. Account and hashtag searches return up to 11 matches per keyword. The source can return fewer items. Duplicate records across queries are returned once.

### Continue from a post ID

Provide `last_ids` in the same order as `keywords` to retrieve posts newer than those IDs. Use an empty string or `1` where no starting ID is needed. IDs must be strings to preserve their full precision. `RUN_SUMMARY` records progress, continuation cursors and any unprocessed queries.

To continue older history, use the returned cursor as the starting ID and select `cursorDirection: "older"`. Without a starting ID, posts are retrieved newest first.

### Pricing

See the Pricing tab for the active rate and any scheduled changes. The pay-per-event rate is **$0.75 per 1,000 unique results + $0.01 per start**, including platform usage. Each unique returned post, account or hashtag is one result. Each valid pay-per-event run with at least one query input includes a shared minimum charge of 100 result units. The minimum also applies when fewer results are returned or no matches are found. Set a maximum run budget of at least **$0.09**.

If fewer than 100 results are available, clearly marked placeholder rows fill the difference; they contain no scraped data, so filter them out when exporting. Each separate run has its own minimum, including scheduled or API runs. Platform usage is included. Increase your maximum run budget when collecting more than the included minimum. Runs can also stop at time, request or transfer limits; check `RUN_SUMMARY` to continue an unfinished collection.

### Availability and troubleshooting

No Mastodon account is needed for the public features above. **Full-text post search requires authentication on mastodon.social** and is not available anonymously. The legacy `st` process is accepted but reports this limitation when no public results are returned.

Direct requests are used by default. You can select an Apify proxy or provide custom proxies. If requests are blocked, the run reports **"Try another proxy"**; if no usable results were retrieved, it returns labeled placeholders. Missing accounts and empty searches are reported separately. Three consecutive source errors stop further requests.

Private or deleted posts are not available. Mastodon controls result availability and rate limits. For help, open an issue and include the run URL.

#### Unsuccessful lookups

Where listed in the Pricing tab, a handled lookup problem that prevents a run from returning any real results produces one clear error record and a single $0.02 unsuccessful-lookup fee, in addition to any listed start fee.

# Actor input Schema

## `process` (type: `string`):

Choose the public data to collect. Anonymous full-text status search is unavailable.

## `keywords` (type: `array`):

Account addresses, tags or search terms. Use one type per run. Leave empty for trends.

## `keyword` (type: `string`):

Accepted for existing integrations. Used when Keywords is empty.

## `maxResults` (type: `integer`):

Shared across all queries. Your run budget can impose a lower limit. Does not reduce the minimum charge.

## `maximum` (type: `integer`):

Applies to posts, hashtag timelines and trends. Account and hashtag searches return one page per keyword.

## `last_ids` (type: `array`):

Retrieve posts newer than these IDs. Match the keyword order and count. Use an empty string or 1 to skip a starting ID.

## `cursorDirection` (type: `string`):

Newer preserves existing From ID behavior. Choose Older to continue historical pages using RUN_SUMMARY cursors.

## `pause` (type: `integer`):

Wait between page requests to reduce rate limiting.

## `last_id` (type: `string`):

Starting post ID for the legacy single-keyword input.

## `proxy` (type: `object`):

Direct requests work for public data. Select a proxy if requests are blocked.

## Actor input object example

```json
{
  "process": "gt",
  "keywords": [
    "@Mastodon@mastodon.social",
    "@Gargron@mastodon.social"
  ],
  "maxResults": 100000,
  "maximum": 2,
  "cursorDirection": "newer",
  "pause": 1000,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "keywords": [
        "@Mastodon@mastodon.social",
        "@Gargron@mastodon.social"
    ],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("canadesk/mastodon").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 = {
    "keywords": [
        "@Mastodon@mastodon.social",
        "@Gargron@mastodon.social",
    ],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("canadesk/mastodon").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 '{
  "keywords": [
    "@Mastodon@mastodon.social",
    "@Gargron@mastodon.social"
  ],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call canadesk/mastodon --silent --output-dataset

```

## MCP server setup

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

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/HaLdza5eIs7f4E2Nc/builds/KPMZ7Ky7RzyAclYpN/openapi.json
