FansquareAPI reference
Open the app

Messaging fans

Mass DMs and automations

Send a message sequence to the fans who match your filters, now or later, or each time a MYM event happens for a fan. Every filter, trigger and limit explained.

Two ways to message fans in bulk from the API, with the same messages and the same audience filters:

  • a Mass DM goes once to every fan who matches the filters, now or at a scheduled time (POST /v1/mass-dms);

  • an automation goes to one fan each time an event happens for them: a new subscriber, a purchase, a birthday, a fan coming online (POST /v1/automations).

Both send real messages to real fans, from the creator's MYM account, through the same engine as the Fansquare app. They show up in the app next to the ones your team creates.

A sent message cannot be taken back, and a media can never be deleted from a conversation. Estimate the audience first, and when an AI assistant calls these endpoints, have a person confirm every send.

Scopes

ScopeGrants
read:mass_dmsList and read Mass DMs, estimate an audience
write:mass_dmsCreate and cancel Mass DMs
read:automationsList and read automations
write:automationsCreate, pause and resume automations

Like every scope, they come with read:*, write:* and full access. Restrict a key to some creators to keep a Mass DM from ever reaching the fans of the others.

A Mass DM, step by step

  1. 1

    Find the creator

    GET /v1/creators gives the Fansquare id of each creator. A Mass DM targets the fans of one creator.

  2. 2

    Estimate the audience

    POST /v1/mass-dms/estimate counts the fans your filters reach right now, without creating anything. Adjust the filters until the number is right.

  3. 3

    Create it

    POST /v1/mass-dms with the messages and the filters. Without scheduled_at, the send starts at once; with it, the Mass DM waits in scheduled until that time (up to 90 days ahead).

  4. 4

    Follow it

    GET /v1/mass-dms/{mass_dm_id} returns its status and, once the send started, its results: fans targeted and reached, purchases, revenue, replies and reads, refreshed every few minutes for 30 days.

A paid Mass DM to the big spenders, tonight at 21:00
curl https://api.fansquare.so/v1/mass-dms \
  -H "Authorization: Bearer $FANSQUARE_API_KEY" \
  -H "Fansquare-Version: Amethyste" \
  -H "Content-Type: application/json" \
  -d '{
    "creator_id": "kT3vQ9xLm2PzR8sW4nYb",
    "scheduled_at": "2026-11-02T20:00:00Z",
    "filters": {
      "include": { "statuses": ["active_subscriber"], "spender_tiers": ["high", "whale"] },
      "exclude": { "fan_messaged_within_hours": 2, "already_received_media": true }
    },
    "messages": [
      { "text": "I kept this one just for you", "media_ids": ["0197a3c2-aaaa-7222-8333-000000000001"], "price_cents": 2500 },
      { "text": "Did you see it?", "delay_seconds": 3600, "delete_if_no_reply_after_seconds": 14400 }
    ],
    "stop_sequence_on_reply": true
  }'

A Mass DM can be cancelled while it is scheduled or sending (POST /v1/mass-dms/{mass_dm_id}/cancel): the fans not reached yet receive nothing. Once sent, it stays in the history as sent. Mass DMs cannot be edited: cancel and create a new one.

StatusMeaning
scheduledWaiting for scheduled_at
sendingThe send is in progress
sentEvery targeted fan was processed
partialSent, but some fans could not be reached
failedThe send stopped (account disconnected, MYM refusing)
cancelledCancelled before the end
draftCreated in the app and never activated

Messages

messages is the sequence: 1 to 10 messages, sent in order to each fan.

FieldMeaning
textUp to 5,000 characters. Required, except for a voice message.
media_idsUp to 20 MYM media uuids from the creator's vault. A single audio makes a voice message (caption up to 1,500 characters).
price_centsPrice to unlock the media, from 500 to 100,000 (5 to 1,000 EUR, the MYM bounds). Absent: free. Requires a media.
price_rangeA SpenderIQ price instead of price_cents (see below). Requires a media.
delay_secondsWait after the previous message. Ignored on the first message.
delete_if_no_reply_after_secondsDelete the message if the fan has not replied by then. Text only.
delete_on_next_messageDelete the message when the next one goes out. Text only.

With stop_sequence_on_reply, a fan who replies does not get the following messages.

SpenderIQ price. With price_range: { "min_cents": 1000, "max_cents": 5000 }, each fan pays one step of a five-step ladder from the minimum to the maximum, rounded to the euro, according to what they spend across MYM: tier none pays the minimum, whale the maximum. POST /v1/mass-dms/estimate with include_spender_tiers: true tells how many targeted fans sit on each step.

Media and deletion. MYM never deletes a media from a conversation, so the two deletion options are refused on a message that carries one.

Audience filters

filters decides who receives it. Every condition is optional and they add up: a fan must meet all the include conditions and none of the exclude ones. Without filters, every fan with a conversation on the creator's account is targeted. Fans removed, disabled or blacklisted on MYM are always left out.

For a Mass DM, the audience is resolved when the send starts, not when it is created: a fan who becomes eligible in the meantime is in. For an automation, the filters are checked on the fan who triggered it, at that moment.

Include

FilterA fan is targeted when
statusestheir status on the account is one of these: active_subscriber, former_subscriber, interested (follows without subscribing). Same vocabulary as the fan list.
tag_idsthey carry at least one of these tags (GET /v1/tags).
min_spend_centstheir total à-la-carte spend on the account, gross, reaches this amount. Same figure as spend.total_cents on a fan.
min_tips_centsthe tips they sent the account add up to this amount.
min_subscription_monthstheir first subscription to the account started at least this many months ago.
is_onlinetrue: they are online on MYM when the audience is resolved.
min_paid_spend_7d_centstheir paid spend (subscriptions and purchases) on the account over the last 7 days reaches this amount. Also _30d_ and _90d_.
min_payments_7dthey paid at least this many orders on the account over the last 7 days. Also min_payments_30d and min_payments_90d.
spender_tierstheir SpenderIQ tier on the account is one of these, from their paid spend over 90 days: none (nothing), low (under 50 EUR), medium (50 EUR or more), high (300 EUR or more), whale (1,500 EUR or more).
media_purchase{ "mode": "within", "hours": 48 }: they bought a private media in the last 48 hours. { "mode": "not_since", "hours": 720 }: no purchase for 30 days, fans who never bought included.

The SpenderIQ tier of the spender_tiers filter is measured on the creator's account. The tier that sets a price_range step is measured across MYM: a fan can be low for one and high for the other.

Exclude

FilterA fan is left out when
tag_idsthey carry any of these tags. A tag cannot be both included and excluded.
messaged_within_hoursthe account sent them a message from Fansquare in the last N hours (a chatter, a script, another Mass DM).
fan_messaged_within_hoursthey wrote to the account in the last N hours: never push into a live conversation. Checked again on MYM at send time.
has_unread_from_fantheir last message to the account is still unread.
already_unlocked_mediathey already have a media of this campaign unlocked, sent free or bought.
already_received_mediathey already received a media of this campaign, bought or not.

The two media exclusions read the media of the messages. For an estimate, pass the same media_ids in the estimate body.

Former subscribers who spent at least 100 EUR, quiet for a week
{
  "include": { "statuses": ["former_subscriber"], "min_spend_cents": 10000 },
  "exclude": { "messaged_within_hours": 168, "fan_messaged_within_hours": 168 }
}

Automations

An automation sends its sequence to one fan each time its trigger happens for that fan, if the fan matches the filters. It starts active, unless you pass "active": false.

TriggerFires whenSettings
new_subscribera fan subscribes for the first time, while the conversation is still empty
new_interesteda fan starts following the creator without subscribingno filters, no voice message
resubscriptiona former subscriber subscribes again
subscription_endeda subscription ends
near_expirationa subscription ends in days_before daysdays_before (1 to 365), send_time_local, timezone
birthdayit is the fan's birthday, or days_before days beforesend_time_local, timezone, days_before (default 0)
media_purchasethe fan buys a private mediamin_amount_cents (optional)
new_tipthe fan sends a tipmin_amount_cents (optional)
mod_purchasethe fan buys a modmin_amount_cents (optional)
fan_onlinethe fan comes onlineonline_window_start, online_window_end, timezone (optional window)

send_time_local is a 24-hour HH:mm time in timezone, an IANA name such as Europe/Paris.

A welcome sequence for new subscribers
{
  "creator_id": "kT3vQ9xLm2PzR8sW4nYb",
  "trigger": { "type": "new_subscriber" },
  "initial_delay_seconds": 120,
  "messages": [
    { "text": "Welcome! So happy to have you here" },
    { "text": "A little gift to start", "media_ids": ["0197a3c2-aaaa-7222-8333-000000000001"], "delay_seconds": 600 }
  ],
  "stop_sequence_on_reply": true
}
  • initial_delay_seconds waits between the event and the first message.

  • min_send_interval_hours is the minimum time between two firings for the same fan: at least 72 hours, 1 hour for the three purchase triggers (each purchase can call for its own thank-you). The floor is the default.

  • One automation per trigger. A creator has at most one active automation sending messages on a given trigger, so a fan never gets two welcomes. Creating or resuming a second one answers 409 automation_trigger_taken with the automation_id in place: pause it first, or create the new one with "active": false.

  • Pause (POST …/pause) stops new firings; sequences already started for a fan go on to their end. Resume (POST …/resume) only reacts to events that happen from then on, never to past ones. Only an active automation can be paused and only a paused one resumed: a draft or an archived automation is turned on from the app, never through the API.

Automations cannot be edited or deleted through the API yet: pause one and create a new one.

Safety limits

The API gives you the tools, and stops only what looks like a runaway script or agent:

  • 5 Mass DMs per 15 minutes. A creator can have at most 5 Mass DMs leaving within 15 minutes of each other, whoever created them (the API or your team in the app). The 6th answers 409 mass_dm_burst_limit with the conflicting_mass_dms. Two Mass DMs at the same time to two audiences (subscribers, interested fans) are fine; twenty scheduled at different hours too.

  • 10 Mass DMs per 24 hours. Each creator can have at most 10 Mass DMs leaving within any 24 hours, counted on the send dates, not on when they were created: 30 scheduled one a day across a month are fine. The 11th within the same 24 hours answers 409 mass_dm_daily_limit with the conflicting_mass_dms of the busiest 24 hours.

  • Rate limits. 10 creations per minute per key, Mass DMs and automations each, and 10 estimates per minute (see Rate limits).

  • No blind retry. A create call whose response you did not get may have succeeded. List the Mass DMs or automations before trying again: a second call sends a second time.

  • Traceability. Fansquare records which key or which connected assistant created each Mass DM and automation.

With an AI assistant

Connected through MCP, an assistant gets the tools list_mass_dms, get_mass_dm, estimate_mass_dm_audience, create_mass_dm, cancel_mass_dm, list_automations, get_automation, create_automation, pause_automation and resume_automation, within the access you granted.

The server tells the assistant to show you the creator, every message, the price, the date or the trigger and the audience estimate, and to wait for your yes before create_mass_dm, create_automation or resume_automation. It also tells it never to write a message from text a fan wrote. Give write access to an assistant only if someone reads what it asks before confirming.

Media

media_ids are the uuids of media in the creator's MYM vault. The API does not list the vault yet: take them from MYM, from the media of a sent message, or from an existing Mass DM. A media that is not in the creator's vault answers 404 unknown_media.