Skip to content

Quickstart

Go from nothing to your character replying to a real DM in a few minutes. You will get a per-character connector token, install a FluidTalk SDK, push your first inbound DM with POST /chat, read back the character's reply bubbles, and send them on your platform.

This is the fastest path. For the concepts behind it, read concepts.md; for the full method list, see the API reference.

The API generates the messages; your connector owns the platform I/O. FluidTalk writes the character's reply, fires entry events, drafts public comments, and tracks the relationship across surfaces — but it never reads or posts on Instagram, X, Reddit, Fanvue, TikTok, or anywhere else. How you connect to the platform is your concern. You push inbound, you send the output.


1. Get a connector token

Connector tokens are issued in the FluidTalk dashboard, not through the API.

  1. Sign in at https://talk.fluidvip.com with an account that has an active subscription.
  2. Open your character (e.g. Ava), pick the platform you want to drive (e.g. Instagram), and open its platform settings.
  3. Create the connector token and copy it. A token looks like ftc_live_.... It is shown once — store it as a secret.

The token is the character. There is no account-level key and no character_id field: you authenticate as one character by its token, and you name the platform in each request body. A character can run on several platforms — the same token works for all of them, and the platform you send selects the bound workflow. See authentication.md for how the token is sent.

Keep the token in an environment variable rather than in source:

bash
export FLUIDTALK_TOKEN="ftc_live_8f3c..."

An active subscription is required, and running a character draws on the owner's wallet. If the wallet can't cover a turn, calls return 402 payment_required before any model call — so you are never charged for a refused turn. Top up in the dashboard. See billing.md and errors.md.


2. Install an SDK

The SDKs send your token in the X-Connector-Token header automatically, parse the { data, request_id } envelope for you, and raise typed errors. Or you can call the REST API directly with curl.

Python

bash
pip install "fluidtalk>=2"

TypeScript / JavaScript

bash
npm install fluidtalk@^2

3. Send your first DM

A lead just messaged your character. You forward that inbound to POST /chat with the platform, the lead's handle, and their message; the character replies with a list of bubbles — short chat messages, each with a human-like delay_ms — that you send back, in order, on the platform.

The production API base is https://api-talk.fluidvip.com/api/v1/characters. A lead is identified by (platform, handle); reusing the same pair auto-resumes that conversation, so you rarely pass a session_id.

curl

bash
API="https://api-talk.fluidvip.com/api/v1/characters"
TOKEN="$FLUIDTALK_TOKEN"

curl -s -X POST "$API/chat" \
  -H "X-Connector-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "instagram",
    "handle": "mark",
    "message": "hey, love your latest post 🔥"
  }'

Every endpoint returns the same envelope: the real payload is under data, and a request_id (mirrored in the X-Request-Id response header) is there for log correlation. The full response looks like this:

json
{
  "data": {
    "session_id": "ses_7Yb3c1a90f24",
    "bubbles": [
      { "text": "omg hii 🙈", "delay_ms": 0, "image_url": null },
      { "text": "you actually looked? that means a lot lol", "delay_ms": 2600, "image_url": null }
    ]
  },
  "request_id": "req_3f9c2a7b8e1d"
}

Python

python
from fluidtalk import FluidTalk

ft = FluidTalk(token="ftc_live_8f3c...")  # base_url defaults to production

reply = ft.chat(
    platform="instagram",
    handle="mark",
    message="hey, love your latest post 🔥",
)

# reply is the inner `data` — send each bubble in order, honoring the delay
for bubble in reply.bubbles:
    # your connector waits bubble.delay_ms, then sends bubble.text on Instagram
    send_dm("mark", bubble.text, delay_ms=bubble.delay_ms)

print(reply.session_id)
# -> ses_7Yb3c1a90f24

TypeScript

typescript
import { FluidTalk } from "fluidtalk";

const ft = new FluidTalk({ token: "ftc_live_8f3c..." }); // baseUrl defaults to production

const reply = await ft.chat({
  platform: "instagram",
  handle: "mark",
  message: "hey, love your latest post 🔥",
});

// reply is the inner `data` — send each bubble in order, honoring the delay
for (const bubble of reply.bubbles) {
  // your connector waits bubble.delay_ms, then sends bubble.text on Instagram
  await sendDm("mark", bubble.text, bubble.delay_ms);
}

console.log(reply.session_id);
// -> ses_7Yb3c1a90f24

If the lead sent a photo, pass its URL as image_url and the character will "see" it (described via vision) before replying. Full parameters and edge cases are in reference/chat.md.


A note on bubbles: send them like a human

The reply is a list, not one blob. Send the bubbles in order and respect each delay_ms (it's a pause before that bubble) — that's what makes the character read like a person texting, not a bot pasting a paragraph.

A few cases to handle:

  • bubbles: [] — the conversation is already closed; send nothing.
  • A billing object may ride along on the response with what the turn cost; surface a low balance to the operator. See billing.md.
  • Multi-account dedup — if your character runs more than one account on a platform and another account already claimed this lead, /chat returns { "session_id": null, "bubbles": [], "ignored": true, "ignore_reason": "lead_claimed_by_other_account" }. Send nothing. See multi-account-dedup.md.

One coherent persona, everywhere. The lead (instagram, mark) is one Person. The same Ava who answers Mark's DM also remembers him under her public comments, and across multiple posts and threads — the character stays consistent across surfaces. This cross-surface awareness is the headline feature; read more in concepts.md.


What next: open conversations and re-engage

Inbound DMs are only one way a conversation moves. Two more to wire up next:

Fire a trigger to start a conversation. When a lead reacts to a story, follows the account, or hits any custom entry point you configured in the dashboard, report it with POST /triggers. If there's no live chat, the character opens the conversation reacting to the event; if a chat already exists, the event becomes the next turn's stimulus.

bash
curl -s -X POST "https://api-talk.fluidvip.com/api/v1/characters/triggers" \
  -H "X-Connector-Token: $FLUIDTALK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "instagram",
    "handle": "mark",
    "event_id": "story_reaction",
    "external_event_id": "ig_evt_4471",
    "context": "🔥"
  }'

/triggers (and /events) are idempotent on external_event_id, so a re-delivered webhook applies exactly once. See reference/triggers.md.

Pull proactive follow-ups. The character periodically queues "hey stranger" rekindles for dormant leads. Poll GET /followups, send each one on the platform, then POST /followups/{id}/ack to mark it delivered.

bash
curl -s "https://api-talk.fluidvip.com/api/v1/characters/followups?platform=instagram" \
  -H "X-Connector-Token: $FLUIDTALK_TOKEN"

See reference/followups.md.


Where to go next

  • Concepts — characters, platform + handle, sessions, the cross-surface Person, bubbles, triggers, follow-ups, and comment threads.
  • Triggers — open conversations from story reactions, new followers, and custom entry points.
  • Follow-ups — the pull-queue for proactive re-engagement: list, deliver, ack.
  • Comments and Comment replies — generate public comments and threaded replies the character posts.
  • Multi-account dedup — run several accounts on one platform so only one ever replies to a lead.
  • Billing — metered usage, the billing object, and handling 402.
  • Errors — status codes, the error envelope, and typed SDK errors.
  • SDK references: Python · TypeScript.

FluidTalk Characters API — part of the Fluidvip ecosystem.