Fluffer by MotorbunnyDevelopers

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

  1. The user turns on Remote control in the Fluffer app (Profile → Remote Control) and creates an API key.
  2. Your code sends commands to https://api.fluffer.app/v1 with that key.
  3. 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.

  1. In the Fluffer app, open Profile → Remote Control.
  2. Choose a mode: Tips + control to let keys move the toy, or Tips only for tips and fuel.
  3. Pick the key’s scopes (device.control, tips.publish, device.fuel, device.status) and tap Create new key.
  4. 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

ScopeLets a key
device.controlvibrate, rotate and play patterns
tips.publishsend tip events (they add fuel; games may react)
device.fueladd fuel to the user’s Tip4Fuel tank directly
device.statuscheck whether the user’s app is listening, their toy and its motors, and the result of any of their commands
any keystop 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