Remote API
Remote APIBeta
Control a Fluffer user’s connected toy from your own code: personal API keys, simple JSON endpoints, consent and safety built in.
The Fluffer Remote API lets people drive their own toy (or their phone’s vibration) from code they write or tools they trust: a home automation, a script, a stream bot, an AI assistant. Every request goes through the Fluffer app on their phone, which applies their power limits and can stop it at any moment.
#How it works
- The user turns on Remote control in the Fluffer app (Profile → Remote Control) and creates an API key.
- Your code sends commands to
https://api.fluffer.app/v1with that key. - Fluffer delivers each command to the user’s phone, which plays it on their toy, within their limits, while the app is open.
Nothing reaches a phone whose owner hasn’t turned Remote control on, and the owner can stop or pause it from a banner in the app.
#Get an API key
API keys are personal: each one belongs to one Fluffer user and only controls that user’s toy.
- In the Fluffer app, open Profile → Remote Control.
- Choose a mode: Tips + control to let keys move the toy, or Tips only for tips and fuel.
- Pick the key’s scopes (
device.control,tips.publish,device.fuel,device.status) and tap Create new key. - Copy the key (it starts with
flk_). It’s shown once.
Keys don’t expire. A key stops working only when its owner revokes it in the app. To rotate a key, create a new one, switch your code over, then revoke the old one. Treat a key like a password: keep it on your server or device, never in a public repository or a web page anyone can open.
#Your first request
curl -X POST https://api.fluffer.app/v1/vibrate \
-H "Authorization: Bearer $FLUFFER_KEY" \
-H "Content-Type: application/json" \
-d '{"strength": 0.6, "duration_ms": 3000}'
{
"id": "6f1c0d7e-3a52-4c09-9b1e-0a6f2d1c9e44",
"action": "vibrate",
"kind": "motors",
"payload": { "m1": 0.6, "m2": 0.6, "m3": 0.6, "m4": 0.6, "duration_ms": 3000 },
"received_at": "2026-10-05T18:21:04.512Z"
}
A 202 response means the command was accepted for the user’s phone. Their toy vibrates at 60% for three seconds, then stops by itself.
#Scopes
| Scope | Lets a key |
|---|---|
device.control | vibrate, rotate and play patterns |
tips.publish | send tip events (they add fuel; games may react) |
device.fuel | add fuel to the user’s Tip4Fuel tank directly |
device.status | check whether the user’s app is listening, their toy and its motors, and the result of any of their commands |
| any key | stop the toy, and check the result of the commands it sent |
#Check the toy’s status
With the device.status scope, ask whether the app is listening before you send anything:
curl https://api.fluffer.app/v1/status -H "Authorization: Bearer $FLUFFER_KEY"
{
"listening": true,
"paused": false,
"last_seen": "2026-10-13T18:21:04.512Z",
"toy": { "type": "Buck 2", "battery": 80 },
"motors": [{ "index": 1, "kind": "vibe", "on": true, "level": 0.6, "until": "2026-10-13T18:21:07.512Z" }],
"app_version": "3.1.0"
}
listening is true only while the app is open with Remote control on and reported in within the last 90 seconds. Then, with the id from a 202, see what the app did with a command:
curl https://api.fluffer.app/v1/commands/6f1c0d7e-3a52-4c09-9b1e-0a6f2d1c9e44 -H "Authorization: Bearer $FLUFFER_KEY"
{ "id": "6f1c0d7e-…", "action": "vibrate", "created_at": "…", "result": "partly", "reason": "motor_off", "handled_at": "…" }
The user can switch any motor off with its power button in the app; a command that needs it then comes back partly or refused with reason motor_off. Details in the API reference.
#Next
- API reference: every endpoint, its parameters and responses.
- Limits and safety: what Fluffer enforces for every request.
- MCP server: let an AI assistant use the same commands.