One button, your own workflow

Use Stream Deck, HTTP or WebSocket to run a saved Event Flow workflow.

Complete Stream Deck controls, gestures and icon guide

Build a workflow that can be called

  1. Named triggerStream Deck / API
  2. Conditions and actionsYour saved Event Flow
  3. DestinationFlow Actions, OBS or another integration
  1. Open Event Flow from SSN. Create a dedicated flow or choose the Stream Deck / API button template.
  2. Add Run from Stream Deck / API in the Stream Deck & API trigger group.
  3. Give it the name intermission. Names match exactly and are case-sensitive; use a short descriptive name.
  4. Connect its output to Show Text. Set the text to Back in five minutes, and choose the desired duration and layer.
  5. Save the flow, then enable it. An unsaved flow exists only in the editor; a disabled flow cannot be called. The starter template is intentionally disabled until you finish setup.
  6. Open your Flow Actions overlay using SSN's generated link. For your audience, add that URL as an OBS Browser Source. The editor itself is not the overlay.

Flows without this named trigger are not callable through the workflow API. Calling a workflow does not inject fake chat into the dock. Existing OBS events and normal chat continue to use their existing triggers.

A flow can combine its named trigger with filters through logic nodes. Keep unrelated automations in separate flows: all the trigger/logic branches in the selected flow are evaluated with the API event. Repeated presses start separate runs; put a Rate Limiter state node after the trigger if you want a cooldown.

Connect a Stream Deck key

  1. Configure the plugin's Setup action with your SSN session and optional password. Use Test Connection.
  2. Drag Preset Command onto a key.
  3. Select Event Flow workflows → Run workflow.
  4. Choose Refresh workflows, then select your saved flow and trigger. The key stores its flow ID as well as its trigger name.
  5. Press once and watch the Flow Actions overlay. The key's check mark means SSN accepted the run.

The workflow picker preserves missing selections. After renaming, disabling, deleting or importing a flow, refresh and reselect it. A workflow imported as a new flow has a different ID. Use the Value field to target by name across several flows instead.

Custom Command: set Action to triggerWorkflow, leave Target blank, enter {"trigger":"intermission"} as Value, and enable Wait for response. The preset offers guided selection and capability filtering.

Multi Actions: each workflow request acknowledges acceptance quickly. The next Stream Deck step can start before delayed workflow actions finish. Put sequencing and delays inside Event Flow when order matters.

Pass custom values

In the key's Value field or your API request:

{
  "trigger": "intermission",
  "flowId": "YOUR_SAVED_FLOW_ID",
  "data": { "name": "Back in five minutes", "minutes": 5 }
}

Set Show Text to {meta.workflow.data.name}. Compare Property can read meta.workflow.data.minutes. Data is an optional JSON object; it stays in meta.workflow.data and cannot replace the event's identity or grant chat privileges.

Omit flowId to call every enabled flow with that exact trigger name. Multiple matching trigger nodes in one flow still evaluate that flow only once. To run only one flow, keep its ID from the picker or discovery response.

The event used inside the selected flow has type: "api", event: "workflow_trigger", chatname: "Stream Deck / API", an empty chatmessage, and the data above. Ordinary chat that copies those fields cannot activate the named API trigger.

API examples

Keep SSN enabled and running. These are Social Stream remote-control calls; they do not use SSApp's separate local AI/MCP API. Keep your real session ID private.

Discover available triggers

{"action":"getWorkflowTriggers","get":"list-1","apiid":"YOUR_SESSION"}

The callback contains result.payload.triggers:

{"triggers":[{"flowId":"flow-123","flowName":"Intermission","trigger":"intermission"}]}

Run a named workflow

{
  "action": "triggerWorkflow",
  "value": {"trigger":"intermission","flowId":"flow-123","data":{"name":"Back shortly"}},
  "get": "run-1",
  "apiid": "YOUR_SESSION"
}

Use a unique get string for each request. A successful callback has result.ok: true, result.status: "accepted", and result.payload.matchedFlows. Acceptance means the enabled flow was found and scheduled. It does not mean every delayed action, webhook, OBS call or media playback has completed.

WebSocket

Enable remote API control of extension in SSN. Connect to wss://io.socialstream.ninja. Join with {"join":"YOUR_SESSION","out":1,"in":2}, then send the request above. Channel 1 carries controls; channel 2 carries callbacks. You do not need to enable the chat channel for workflows.

HTTP

Enable the same remote API control setting. Replace the session placeholder before use:

POST https://io.socialstream.ninja/YOUR_SESSION
Content-Type: application/json

{"action":"triggerWorkflow","value":{"trigger":"intermission","data":{"name":"Back shortly"}}}

For a simple named trigger you can also use GET https://io.socialstream.ninja/YOUR_SESSION/triggerWorkflow/null/intermission. The fourth path segment can contain URL-encoded JSON for structured values. Encode the entire JSON value with encodeURIComponent(JSON.stringify(value)). Custom send channels use ?channel=N.

P2P

The plugin's default P2P mode sends the same payload through SSN's existing VDO.Ninja data-channel transport. The hosted WebSocket API toggle is not required for P2P. Existing P2P clients should send this request through their established SSN control connection; opening the local AI API is not required.

Errors and compatibility

  • WORKFLOW_NOT_FOUND: no saved, enabled flow matches the trigger/flow ID.
  • INVALID_VALUE: missing/invalid trigger, malformed JSON, invalid flow ID or non-object data.
  • CONTROL_UNAVAILABLE: SSN or remote host control is disabled.
  • TARGET_UNAVAILABLE: Event Flow is still loading.
  • Older Social Stream assets may not advertise these actions. Check getCapabilitiesssn.actions.triggerWorkflow and getWorkflowTriggers. The new trigger and updated plugin must both be installed; SSApp's version number alone does not identify the remotely loaded Social Stream assets.

Do not automatically retry a mutating call after a lost acknowledgement: the workflow may already have started. Check its output first. This API does not provide an execution-status queue.

What each integration needs

Workflow actionRequired destination/setupWhat to check
Show Text, media, audio, layer clearingConnected Flow Actions overlay, same session; OBS Browser Source for audience output.Visible output, layer, duration and audio routing. A successful command does not establish OBS scene visibility.
OBS controlsFlow Actions connected to OBS with the configured address/password; matching scene/source names.Actual OBS state. See the OBS guide.
Pin/feature messageConnected default dock; choose a real message ID or full message payload.Dock pinned list and featured overlay. An API trigger's empty chat text is not itself useful chat.
Call WebhookURL, method and JSON body in the action.Receiver response and Event Flow error fields; the Stream Deck acknowledgement arrives before delayed/external results.
Send Message / relayWritable, connected source and explicit destination.Actual destination chat. A workflow request is not permission to bypass platform limits.
Products & SupportSaved/enabled products and the commerce overlay.SSN selected/hidden/scheduled state. See product controls.
Giveaway, tickets, pointsConfigured giveaway/economy and a suitable actor. A named API event has no viewer identity.Use host-level giveaway presets for host controls; do not treat the API event as a viewer purchase. See giveaways and points.
TTS, Spotify, printing, MIDIEach integration's own connection, permissions, device or account setup.The actual destination/device. Installing Stream Deck does not configure these integrations.

Full Event Flow guide · Recipes · API reference

Timer and chat gestures

Timer: turn one click for ±10 seconds by default; hold the dial down while turning for ±1 minute (6× the configured step). Press/release without turning to start/pause. Tap the timer display to refresh; hold the display to reset. Holding the physical dial alone does not reset.

Chat Review: turn left for older chat, right for newer; press the dial to pin the reviewed message. Tap the display to feature the next pinned message; hold the display to unpin the reviewed message. Keep the default dock open. In WebSocket mode enable chat relay on channel 4.

Open Help and diagnostics → Controls, icons and workflow guide in the plugin for the complete offline guide, all five action types, every preset/icon, reset behavior, defaults and troubleshooting.

Event Flow palette reference

The palette has 45 triggers, 67 actions, five logic nodes and four state nodes. Each entry has a text label alongside its symbol. Select a node to see its settings and integration prerequisites; a palette icon does not establish that a destination is connected.

Triggers decide when a flow starts. Connect conditions with AND/OR when required. Actions execute in connected order. State nodes remember values between events. For a button cooldown choose Rate Limiter (THROTTLE), not a Delay action: Delay postpones every run and does not suppress repeated presses.

Triggers: Stream Deck & API (1)
  • ▶ Run from Stream Deck / API — apiTrigger
Triggers: 📣 Stream Events (9)
  • 👋 New Follower — eventNewFollower
  • ⭐ New Subscriber — eventNewSubscriber
  • 🔄 Resub/Renewal — eventResub
  • 🎁 Gift Sub — eventGiftSub
  • 💰 Donation / Tip — eventDonation
  • 🚀 Raid — eventRaid
  • 💎 Cheer/Bits — eventCheer
  • 📋 Other Event... — eventOther
  • ✏️ Custom Event — eventCustom
Triggers: OBS Studio (7)
  • OBS Stream Started — obsStreamStarted
  • OBS Stream Stopped — obsStreamStopped
  • OBS Recording Started — obsRecordingStarted
  • OBS Recording Stopped — obsRecordingStopped
  • OBS Scene Changed — obsSceneChanged
  • OBS Media Ended — obsMediaEnded
  • OBS Replay Buffer Saved — obsReplaybufferSaved
Triggers: 💬 Chat Messages (6)
  • 💬 Any Message — anyMessage
  • 🔍 Message Contains — messageContains
  • ▶️ Message Starts With — messageStartsWith
  • ⏹️ Message Ends With — messageEndsWith
  • 🟰 Message Equals — messageEquals
  • 🔤 Message Regex — messageRegex
Triggers: 📊 Message Properties (7)
  • 📏 Message Length — messageLength
  • 🔢 Word Count — wordCount
  • 😀 Contains Emoji — containsEmoji
  • 🔗 Contains Link — containsLink
  • 💰 Has Donation — hasDonation
  • ⚖️ Compare Property — compareProperty
  • ⚙️ Message Properties Filter — messageProperties
Triggers: 👤 User & Source (6)
  • 📡 From Source — fromSource
  • 📺 From Channel Name — fromChannelName
  • 👤 From User — fromUser
  • 👑 User Role — userRole
  • 🧠 User Is Remembered — userMemoryContains
  • 🎁 Channel Point Redemption — channelPointRedemption
Triggers: ⏰ Timing & Random (4)
  • 🎲 Random Chance — randomChance
  • ⏰ Time Interval — timeInterval
  • 🎤 When I say... — voicePhrase
  • 🕐 Time of Day — timeOfDay
Triggers: 🎹 MIDI (3)
  • 🎹 MIDI Note On — midiNoteOn
  • 🎹 MIDI Note Off — midiNoteOff
  • 🎛️ MIDI Control Change — midiCC
Triggers: 📦 Advanced (2)
  • 📣 Event Type (Advanced) — eventType
  • Custom Code — customJs
Actions: 💬 Message Actions (14)
  • 🚫 Block Message — blockMessage
  • ✅ Return Message — returnMessage
  • ⚡ Continue Async — continueAsync
  • ✏️ Modify Message — modifyMessage
  • ⬅️ Add Prefix — addPrefix
  • ➡️ Add Suffix — addSuffix
  • 🔄 Find & Replace — findReplace
  • ✂️ Remove Text — removeText
  • 🎨 Set Property — setProperty
  • 🌟 Feature Message — featureMessage
  • Pin Message — pinMessage
  • 💬 Send Message — sendMessage
  • 📢 Relay Chat — relay
  • 🪞 Reflection Filter — reflectionFilter
Actions: 🔌 Integrations (6)
  • Execute Custom Code — customJs
  • 🖨️ Print Thermal Label — printThermal
  • 🌐 Call Webhook — webhook
  • ⬆️ Add Points — addPoints
  • ⬇️ Spend Points — spendPoints
  • 🎁 Giveaway / Tickets — giveawayControl
Actions: 🎨 Media & Effects (7)
  • 🖼️ Display Media Overlay — playTenorGiphy
  • 👤 Show Avatar — showAvatar
  • 🛍 Products & Support — commerceControl
  • 📝 Show Text — showText
  • 🗑️ Clear Layer — clearLayer
  • 🔊 Play Audio Clip — playAudioClip
  • ⏱️ Delay — delay
Actions: 🎬 OBS Studio (14)
  • 🎬 Change Scene — obsChangeScene
  • 👁️ Toggle Source — obsToggleSource
  • 📝 Set Text Source — obsSetText
  • ⏯️ Control Media Source — obsMediaControl
  • 🔊 Set Source Volume — obsSetVolume
  • 🔄 Refresh Browser Source — obsRefreshBrowser
  • 🎨 Toggle Filter — obsSetSourceFilter
  • 🔇 Mute/Unmute Audio — obsMuteSource
  • 🔴 Start Recording — obsStartRecording
  • ⏹️ Stop Recording — obsStopRecording
  • 📡 Start Streaming — obsStartStreaming
  • ⏹️ Stop Streaming — obsStopStreaming
  • ⏺️ Control Replay Buffer — obsReplayBufferControl
  • 💾 Save Replay Buffer — obsReplayBuffer
Actions: 🎵 Spotify (10)
  • ⏭️ Skip Track — spotifySkip
  • ⏮️ Previous Track — spotifyPrevious
  • ⏸️ Pause — spotifyPause
  • ▶️ Resume — spotifyResume
  • ⏯️ Toggle Play/Pause — spotifyToggle
  • 🔊 Set Volume — spotifyVolume
  • 📋 Add to Queue — spotifyQueue
  • 🎵 Announce Now Playing — spotifyNowPlaying
  • 🔀 Toggle Shuffle — spotifyShuffle
  • 🔁 Set Repeat Mode — spotifyRepeat
Actions: 🔊 Text to Speech (5)
  • 🗣️ Speak Text — ttsSpeak
  • 🔇 Toggle TTS — ttsToggle
  • ⏭️ Skip TTS — ttsSkip
  • 🗑️ Clear TTS Queue — ttsClear
  • 🔊 Set TTS Volume — ttsVolume
Actions: 🎹 MIDI (2)
  • 🎹 Send Note — midiSendNote
  • 🎛️ Send Control Change — midiSendCC
Actions: 🧠 User Memory (4)
  • 🧠 Remember User — rememberUser
  • 👋 Forget User — forgetUser
  • 🧹 Clear All Users — clearUserMemory
  • 🎟️ Pick Random User — pickRandomUser
Actions: 🔧 State Control (5)
  • 🚦 Set Gate State — setGateState
  • 🔄 Reset State Node — resetStateNode
  • 🔢 Set Counter Value — setCounter
  • ➕ Increment Counter — incrementCounter
  • Check Counter — checkCounter
Logic and state nodes
  • 🔀 AND Gate — AND
  • 🔄 OR Gate — OR
  • 🚫 NOT Gate — NOT
  • 🎲 RANDOM Gate — RANDOM
  • 🚫 Check Bad Words — CHECK_BAD_WORDS
  • 🚦 On/Off Switch — GATE
  • 🔢 Counter — COUNTER
  • ⏲️ Rate Limiter — THROTTLE
  • 🧠 User Memory — USER_MEMORY

Message filters, viewer points and remembered-user actions need meaningful message/user data. A host button supplies neither a real viewer nor a source reply target. Choose host controls or an explicit configured destination; do not use a named workflow to impersonate a viewer.

For detailed wiring, see the Event Flow guide, state-node guide, user-memory guide, and OBS guide.

Work through a failure

  1. Use a simple Show Text flow first and verify its output.
  2. Save and enable; refresh the Stream Deck workflow list. Confirm both the trigger name and flow ID.
  3. Verify SSN is enabled, connection is Online and the destination overlay is connected to the same session.
  4. Check the API callback or plugin diagnostics for lookup/validation errors. For failures after acceptance, inspect the destination and Event Flow's runtime logs.
  5. Add further integrations one at a time. Test repeated presses, a disabled flow and a reconnect before using it live.

The editor's normal chat test panel sends a chat event. It does not impersonate a named API trigger. Test this trigger through Stream Deck or the API to verify the complete path.