SHUTTERPARTY

Privacy Policy — SHUTTERPARTY

Last updated: 2026-10-15

This document describes what the SHUTTERPARTY Twitch Extension actually does, checked against the source. Every retention figure below is a constant in src/ebs/src/lib.js.

Published by Noriaki Tabuchi, Japan.

Contact: tabuchin.room@gmail.com


The short version

What we receive

When you press the button, the extension sends Twitch's signed token for your session, and — if the press was paid — the receipt Twitch issued for that purchase. It also sends whether you have asked to stay anonymous; whether you want a countdown before your photograph is taken, where the broadcaster has left that to you; and — with a receipt, never on its own — the display name Twitch gave the extension when that purchase completed. From these we read:

WhatWhere it comes fromWhy
opaque_user_idTwitch's signed tokenRate limiting, and "one free credit per minute"
channel_idTwitch's signed tokenWhich channel the press belongs to
Bits amount and transactionIdTwitch's signed receiptTo move the goal bar, and to refuse the same receipt twice
Display nameTwitch's own record of the purchase, handed to the extension in your browser when the Bits go through, and passed on to us together with the receipt for that same purchase. A press that arrives without a valid receipt carries no name, whatever it claimsTo caption the photograph that was bought — the only kind that is ever captioned; while that photograph is being counted down to, to show on the broadcast whose it is; and, when that purchase is the one that fills the bar, to say who started the SHUTTER PARTY. Truncated to 25 characters, and not used at all if you have asked to stay anonymous

We do not read your real Twitch user id when you press the button or buy. The opaque_user_id is a pseudonymous identifier issued by Twitch; it differs per channel and per viewer, and nothing in this service can reverse it. (The one time we do read a real user id is described a little further down: Twitch's notice that somebody took back a permission.)

Three things we receive do contain your Twitch account, and we read it from none of them.

In each case the rest is discarded once the request has been handled. It is not stored, not used for anything, and not written to our logs — what our logs record is which fields a receipt had and whether the channel matched, never their values.

Twitch also tells us when a channel goes live and when it goes offline. These notices are about the broadcaster, not about viewers. They carry the channel's id — the same one every press already carries — and the broadcaster's login and display name. We read the channel, the id of the stream, and whether it is a live broadcast rather than a rerun or a premiere. We do not read the login or the name. This is how we know where one broadcast ends and the next begins (below).

Twitch tells us when somebody takes back a permission they gave SHUTTERPARTY. A broadcaster can pair their computer, or their Stream Deck, with our service by logging in with Twitch (see "The broadcaster's side"). If they later disconnect SHUTTERPARTY in Twitch's own settings, that pairing has to end, and we keep no Twitch token we could ask with — so we ask Twitch to tell us instead. Twitch offers that notice only for the extension as a whole: it is sent whenever anybody takes back a permission they gave SHUTTERPARTY, which can include a viewer, and it names that person by their Twitch user id, login and display name.

This is the one place where we read a real Twitch user id. We read the user id from the notice and compare it, once, against the list of channels that paired by logging in. If it is one of them, that channel's login pairing is ended. If it is not — which is every viewer — nothing is kept, nothing is written to our logs, and nothing else is done with it; all that remains is a count that a notice of that kind arrived. We never read the login or the display name in the notice.

We do not receive: your email address, your IP address as stored data, your chat messages, or anything you type.

What we store, and for how long

State lives in Cloudflare Durable Objects — one per channel, and one shared by the whole extension (described after the table). We currently ask Cloudflare to place that object in the Asia-Pacific region. That is a preference and not a guarantee — Cloudflare treats the request as a hint and puts the object in whichever of its data centres is fast to reach from there, which need not be the same country. Per channel:

StoredRetention
opaque_user_id → the times of your recent presses30 seconds, then dropped
opaque_user_id → when you last advanced the bar for free, and how many free photographs you have taken this broadcastThese share one row. It goes 60 seconds after the first, but only once the second is back to zero — so on a channel with a free allowance the row lasts the broadcast, and is cleared when the broadcast ends (see below)
opaque_user_id → that you asked for your name not to appearUntil you turn it off and press again, which clears it. Only stored for viewers who ask for it, and all it can say is that they asked
opaque_user_id → that you asked for a countdown before the photographs you buyUntil you turn it off and buy again, which clears it. Only stored for viewers who turn it on, when buying at an amount where the broadcaster left the choice to them, and all it can say is that they asked
Bits transactionId → that it was honoured — and, for a purchase Twitch told us about directly, its amount, its product and whether it reached the barFor a purchase reported by the button: until the receipt that carries it expires, which is within 24 hours of the purchase — after that no receipt bearing it can still be presented. For one Twitch told us about directly: 24 hours after the notice arrived (the notice does not say when the purchase was made). This is what stops a receipt being spent twice, or one purchase being counted once by the button and again by Twitch's notice. A purchase from Twitch's notice that we have not yet managed to deliver is kept until it is delivered — we do not give up on something you paid for
Bits transactionId → that this channel let the purchase go, because it was bought on another channel24 hours after it was let go of. It is what stops this channel counting that purchase later, after the channel it was bought on has
The identifier Twitch gives each notice it sends us1 hour. Twitch may send the same notice more than once, and this is what stops it counting twice. It says nothing about you
Display name of a buyer whose paid photo has not been drawn yet, or whose purchase has filled the barUntil that photograph is taken, or that SHUTTER PARTY is announced — normally under a second, or a few seconds when the photograph is counted down to. One still waiting when a broadcast ends is discarded when the broadcast ends (see below)
A paid photograph sent to the broadcaster's overlay whose result has not come back yet: a random id for it, the Bits from it that are not yet on the goal bar, and a random mark for the overlay page it was sent toUntil the overlay says whether it drew the photograph. If no answer comes, 2 minutes; while the overlay keeps saying it is still holding the photograph, up to 10 minutes. If it was not drawn, or no answer came, the Bits are added to the bar then. The end of a broadcast does not cut this short. It holds no name and nothing that identifies a viewer
The channel's bar total, goal, and settings — and whether it is live right now: the id of the stream on air and when it startedFor as long as the channel uses the extension
Three times, one of each: when the channel last made a new pairing code, when its Stream Deck remotes were last cut, and when Twitch last told us the broadcaster disconnected SHUTTERPARTY. Pairing and remote tokens issued before the matching time are refusedFor as long as the channel uses the extension. Each time is replaced by the next one; it says nothing about viewers

Shared by the whole extension, one record per purchase:

StoredRetention
Bits transactionId → the id of the one channel that counts itThe same as the per-channel record above: until the receipt expires (within 24 hours of the purchase), or 24 hours after Twitch's notice arrived

Every channel checks receipts with the same key, so without this one purchase could be counted on every channel its receipt was carried to. It names a channel, never a viewer.

Shared by the whole extension, one record per channel:

StoredRetention
The channel's id → when its overlay last connected to our server, and the state of the go-live and go-offline notices we asked Twitch to send us for it90 days after the overlay last connected
The channel's id → when its configuration page on Twitch last issued a pairing code90 days after the last one
The channel's id → when the setup page on the broadcaster's computer was last paired with it — by a pairing code pasted into it, or by logging in with Twitch — and when that code or pairing was issued90 days after the last one
The channel's id → which release of the overlay each of its sources in OBS last said it was running, which of the extension's newer features that release said it can play, and whether it said it had been loaded from an out-of-date cache90 days after the overlay last connected
The channel's id → when an overlay paired by a pairing code last connected, and when one paired by logging in with Twitch last did90 days after the overlay last connected
The channel's id → when something was last made for it by logging in with Twitch90 days after the last one

The first is how we ask Twitch for those notices only for channels that use the extension. The second and third exist to find out where setting up is hard to follow: the configuration page issues a code every time it is opened, and the setup page reports when a new code is pasted into it (pairing by logging in leaves the same record), so comparing the first three tells us how many broadcasters stopped before the setup page and how many stopped after it. The first and third are also used to answer the configuration page when it asks, for the broadcaster's own channel, which of its setup steps are done. The fourth is there so that, when a broadcaster asks us why something is not working, we can see whether a source in their OBS is still running an older release of the overlay — the countdown before a bought photograph, for one, stays off for as long as one of them is. It says which release of our own files is loaded, and nothing about the broadcaster's computer, their scenes or their stream. When the person who publishes this extension asks which channels use it, the answer shows this beside each channel, together with the same three things for the sources connected at that moment, and whether each of them could take a photograph just then — read off the open connections, and not kept. That last one is a yes or a no: it is what tells an older source that is merely open from one that is switching the countdown off, and it does not say which scene is on or why a source cannot. The fifth is there to count how many channels still pair with a code and how many have moved to logging in, and for nothing else. The sixth exists for one question only: when Twitch tells us somebody took back a permission (above), whether that is a channel paired by logging in — from the setup page or from the Stream Deck plugin. It appears in no list and no count. All six name a channel, never a viewer, and none is used for anything beyond what this paragraph says.

Nothing here is a profile, nothing is used for advertising, and nothing is sold or shared with any third party.

Five of these outlive the minute, each for its own reason. A receipt identifier is kept for 24 hours because that is how long a receipt can still be presented, and forgetting it sooner would let the same purchase be spent twice. Twitch's notice identifier is kept for an hour: a notice more than ten minutes old is refused whatever we remember, so an hour is comfortably past the last moment the same one could still be accepted. The count of free photographs is kept for the broadcast it was spent in, because that is what a per-broadcast allowance means — and it is let go of by the same signal as the name below. And choosing to keep your name off a photograph is a decision you made — it would be worth little if it forgot itself when you closed the tab, so it is kept until you change it back. Changing it back deletes the record rather than storing a "no". Asking for a countdown before the photographs you buy is kept the same way, for the same reason, and changing it back deletes it the same way. Everything else in the table is bookkeeping that stops meaning anything within a minute.

A buyer's name has an outer limit, and not only a typical one. It is held because a purchase that has not been photographed yet still has a photograph owed to it — the broadcaster's OBS may be restarting, or several purchases may be queued ahead of it. That is a matter of seconds while a broadcast is running. But a broadcast can also simply end with one still waiting, and a name kept "until the photograph is taken" would then be kept for as long as the channel existed. So when the broadcast ends, the waiting photographs are let go of, and the names with them. The Bits are not lost: any that a waiting photograph had not yet put on the goal bar are added to the bar then, and the bar is still there. One exception: a photograph already sent to the broadcaster's overlay when the broadcast ends is not let go of at that moment, because it may be on its way to the screen. Its name went with it when it was sent, so we hold no name for it — only the amount, until the overlay says whether it drew the photograph. If it did not, or if no answer comes within 10 minutes at most, its Bits are added to the bar then.

When a broadcast ends is the same moment for the count of free photographs above. Twitch tells us when the stream goes offline, and we wait ten minutes before treating the broadcast as over — an encoder that drops and reconnects sends "offline" and then "online" for the same stream, and that is not a new broadcast. When the ten minutes are up, or as soon as a new broadcast starts, both are cleared. On a channel where Twitch's notices are not coming through — for instance before our subscription for that channel has been confirmed — we fall back on noticing that the channel has been away for two hours and has now returned, and it is the coming back that clears both; a channel that never comes back then keeps them until it does. Nothing reads them in the meantime: a waiting name is drawn on the next photograph or not at all, and it is at most one display name per purchase that had no photograph yet.

Why we are allowed to hold it

Under the GDPR every use of your data needs a stated ground, so here are ours.

Performing what you asked for. When you press the button you are asking for a photograph to be taken on the broadcast, and for a purchase to be credited to the goal bar. Reading the token, reading the receipt, and captioning the photograph you bought are how that request is carried out. There is no separate contract to sign: the press is the request.

Our legitimate interests, kept narrow. Three things are held for reasons of our own rather than yours: the times of your recent presses, so that one viewer cannot take the channel over by holding the button down; the count of free photographs, so that a broadcaster's free allowance means what it says; and the receipt identifier — with, for a purchase Twitch told us about directly, its amount and product — so that the same purchase cannot be spent twice or counted twice — and, shared by the whole extension, which channel counts each purchase, so that one purchase is counted on one channel. Each is the smallest record that answers its question, and each is described above with the time it is kept. The question we put to Twitch about a purchase is ours too: it makes sure a purchase is credited on the channel it was paid on, and it keeps nothing. So is taking Twitch's notice of a purchase: it is how a purchase still reaches the goal bar when the button could not report it, and what we keep of it is the transaction, never the buyer. And so is taking Twitch's notice that a channel went live or offline: it is how a per-broadcast allowance knows where a broadcast ends, and what we keep of it is the stream's id and when it started. And so is taking Twitch's notice that somebody took back a permission: it is how a broadcaster who disconnects SHUTTERPARTY in Twitch's settings is actually disconnected, and of a notice that is not about such a broadcaster we keep nothing.

Your own choice. Asking for your name not to appear, and asking for a countdown before the photographs you buy, are each stored because you asked for it, and each is deleted when you change your mind.

We do not use your data for advertising, profiling, or automated decisions with legal effect, and none of it is sold or shared.

What we never store

The broadcaster's side

The setup page on the broadcaster's computer is paired with our service in one of two ways.

With a pairing code. When a pairing code is pasted into the setup page, the page sends us the channel's id and the pairing token from that code, once each time the code pasted differs from the one it already holds, so that we can record the time (above).

By logging in with Twitch. The setup page asks Twitch for a login in the broadcaster's own browser, with no permissions requested: it lets us learn which Twitch account pressed "Authorize", and nothing more. The page then sends us the access token Twitch issued, once. We ask Twitch whose token it is, read two things from the answer — that it was issued for SHUTTERPARTY, and the account's user id, which is the channel's id — and hand back a pairing token for that channel. We do not store the Twitch token and do not write it to our logs, and we do not read the login name from Twitch's answer. The setup page shows the login name on the broadcaster's own screen so they can check which account they are pairing. Once paired, the page keeps that name in the broadcaster's own browser, so that it can say which account it is paired as the next time it is opened; pasting a pairing code or erasing the page's settings removes it. The name is not sent to us. We record that the channel paired, and when (above).

Either way the page sends nothing else: not the OBS password, not the scenes, not what is on screen.

Ending a pairing. Making a new pairing code on the extension's configuration page ends every earlier pairing of that channel, whichever way it was made. Disconnecting SHUTTERPARTY in Twitch's settings (Settings → Connections) ends the pairings that were made by logging in: Twitch tells us, as described above, and we stop accepting them. It does not end a pairing made with a code, which never depended on that login. It does end every Stream Deck paired with the channel (below).

The Stream Deck plugin. A broadcaster with an Elgato Stream Deck may install the SHUTTERPARTY plugin, which puts two keys on it: one stops and restarts the viewers' shutter, the other shows how full the goal bar is and starts a SHUTTER PARTY that is waiting for the broadcaster's signal. It runs inside Elgato's Stream Deck software on the broadcaster's own computer.

We send nothing to Elgato. We hand the plugin out ourselves, as a file on the same GitHub page as the setup page and overlay; it runs inside Elgato's Stream Deck software, and what that software does is governed by Elgato's own privacy policy.

A broadcaster running SHUTTERPARTY may choose a folder on their own computer for the photographs to be saved into. That is off unless they turn it on, and those files are theirs: they live on their machine, we cannot read them, and we cannot delete them.

While a photograph is being framed, a copy of it passes through OBS's own browser storage on the broadcaster's machine. The extension deletes that copy once the photograph has been drawn, and clears anything a crash left behind the next time the overlay starts. Those copies never leave the broadcaster's computer; we cannot read them and cannot delete them either.

If a paid photograph has been drawn but the overlay has not yet heard back that we received that news, the overlay keeps a short note of it in the same browser storage — a random id for the photograph, a random mark for the overlay page, the channel, and the time — so that a page reloaded in between can tell us again. The note is deleted as soon as we answer, or after 10 minutes. It leaves the broadcaster's computer only to be sent to us again, and it names no viewer.

The photographs appear on a public Twitch broadcast, which means anyone watching can see and record them. That is what the extension is for. A broadcaster controls what can be photographed by choosing a capture scene and by choosing which scenes the button works in.

Cookies and similar technologies

The viewer-facing extension sets no cookies and stores nothing in your browser.

Children

The extension is not directed at children. Twitch's own Terms of Service require account holders to be 13 or older.

Your rights

Under the GDPR and similar laws you may ask what we hold about you, ask for it to be corrected or deleted, ask for it in a portable form, and object to processing. Where we rely on your choice rather than on the grounds above, you may withdraw it at any time, and doing so does not undo what was done while it stood.

You may also complain to a supervisory authority — in the EU or the UK, the data protection authority of the country you live in; in Japan, the Personal Information Protection Commission. You do not have to come to us first.

Practically, there is a limit worth stating plainly: we cannot identify you. The only identifier we hold is Twitch's per-channel opaque id, and we have no way to connect it to a person or an account. If you want a specific record removed, you would need to tell us the opaque id yourself — the extension's own frame is the only place it appears. In almost every case the answer is simpler: everything tied to a viewer is deleted automatically within 60 seconds, with four exceptions: a receipt identifier, which is deleted within 24 hours of the purchase (24 hours after Twitch's notice, for a purchase only that notice told us about); the count of free photographs you have taken — which is cleared when that broadcast ends (see "When a broadcast ends"), and which holds the minute-clock beside it open for as long as it lasts, since the two share one row; a request to keep your name off photographs, which your next press clears once you have turned it off; and a request for a countdown before the photographs you buy, which your next purchase clears once you have turned it off. Until then each is doing the one thing it was stored for, and it cannot say anything about you beyond that you asked.

Requests: tabuchin.room@gmail.com

Sub-processors

Twitch (Amazon)Hosts the extension, issues the tokens, processes Bits, tells us when Bits are spent on the extension, when a channel using it goes live or offline, and when somebody takes back a permission they gave it; answers which channel a purchase was made on; and, when a broadcaster pairs by logging in — from the setup page or the Stream Deck plugin — runs that login and answers whose it was
CloudflareRuns the backend service and stores the per-channel state described above

Changes

If this policy changes materially, the extension version notes will say so. The date at the top always reflects the current text.

Terms of Service · Twitch