Privacy and cookies
This notice covers two separate things: the FoxSDR application you install, and this website. They collect different data, for different reasons, and are described separately below — the application first, because that is the part that runs on your own machine. It is written to be complete rather than short: every field either of them stores is listed, including the ones most notices leave out.
The application: what it sends
There is no account, no licence key and no activation, and FoxSDR never reports anything about what you listen to. It makes exactly four kinds of network request on its own account: an update check; an anonymous usage report, with a small “still running” beat while the application is open; a crash or freeze report after a fault; and — only when you open the plugin store or press CHECK NOW in it — a request to the plugin catalogue. Each is described below, field by field, and each can be switched off. Three switches govern them: SYSTEM → Updates, SYSTEM → Usage reporting and SYSTEM → Diagnostics. No feature depends on any of them being on, and nothing nags you for turning one off.
What stays on your machine
Your recordings, both audio and raw I/Q, the images SSTV and weather-satellite decoders build, everything the decoders decode, your bookmarks, band plans, settings, your receiver position and your installed plugins are files on your own disk. Nothing uploads them, and no frequency you tune to leaves your machine.
The update check
Once per launch the application asks this site whether a newer version exists. The entire
request is GET /api/update?v= followed by the version you are running — no
identifier, no install id, no cookie, and nothing that could be tied to a later request. This
server writes no analytics record for it: only page views and file downloads are recorded, and
the update endpoint is neither. Turn it off under SYSTEM → Updates, and the
application never contacts the service again.
Nothing is downloaded or installed unless you press the button. If you do, the installer is fetched from this website over HTTPS and its SHA-256 is checked against the digest the server published before the file is given a name anything could run — and that fetch is an ordinary download from this site, so it is recorded like any other, with the IP address, approximate location, browser and operating system described in the website half of this notice.
Usage reporting
From version 0.53.0 there is an anonymous usage report, under SYSTEM → Usage reporting. It is on by default, and you can turn it off — untick that box and reporting stops immediately. One report is sent per launch, describing the session that just finished, and this is the whole of it:
| Sent | Example | Why |
|---|---|---|
| Install identifier | 32 random hex characters | Tells 100 users apart from one user launching 100 times. Generated at random on your machine on first run, deleted when you turn reporting off, and never derived from your hardware, network or name. |
| Application version | 0.99.39 | Whether people update. The Android alpha reports its own build as 0.98.1-android.4 — an -android.N suffix on the release number it was built from, so its reports are never confused with the Windows installer's. |
| Operating system | Windows 10.0.22631, Linux 6.8.0 or Android 14 | Which platforms are actually used. The operating system and its build, kernel or release number, never your machine's name or your user account. The Linux build (0.99.39) and the Android alpha (0.98.1-android.4) send the same fields under the same switch. |
| Architecture | x64 or arm64 | As above. |
| Launch count | 12 | Whether the software gets used more than once. |
| Crash count | 1 | How often it fails. |
| Session length | 3600 seconds | Whether sessions are minutes or hours. |
| SDR model | uhd b200 | Which radios to prioritise. Serial numbers are stripped before sending. |
| Demodulators used, and for how long | WFM: 3000s | Which modes justify further work. |
| Panels opened | map, decoded | Which features are used. |
| Installed plugins | ADS-B 1.0.0 | Which decoders justify further work. |
That is the complete list. It ships with the application as PRIVACY.md, and an
automated test asserts the payload field by field, so a new field cannot be added without that
test failing and both documents being updated. Turning reporting off deletes the install
identifier, so if you ever switch it back on you get a new one that cannot be linked to the old.
The report is sent at start-up, describing the session that has already finished, and never at exit — a network call on the way out can hang an application somebody is trying to close, and a report written at exit would be lost by the one event most worth counting. Nothing in the reply is read or acted on.
The “still running” beat
A report that arrives when the application starts can say who launched it and never who still has it open. So, while FoxSDR is running — and only while usage reporting is on — it also sends one very small message every five minutes, carrying three fields and nothing else:
| Sent | Example | Why |
|---|---|---|
| Install identifier | the same 32 hex characters as above | So twelve beats from one copy count as one running copy, not twelve. |
| Application version | 0.99.39 | So “running now” can be split by version. |
| Beat marker | 1 | Tells the receiving end this is a beat and not a session report. |
Nothing from the session rides along: no modes, no panels, no radio model, no durations, no counters. Beats are written to a dataset of their own, kept apart from the session reports, so no usage figure changes meaning. The same switch stops both: the sender refuses to arm without a valid install identifier, and switching usage reporting off deletes it, so off means no beats at all. A beat still in flight when the next one is due is skipped rather than queued.
Where the usage reports go
To a Cloudflare Worker operated by this project at
https://telemetry.foxsdr.com, which writes the counters above to a Cloudflare
Workers Analytics Engine dataset. Cloudflare processes it on our behalf and stores it for three
months, after which it is gone. Nobody else receives it, it is not sold, rented or shared, and
the only thing read back out of it is aggregate counts, through the same password-protected
dashboard described further down. The Worker's source is published with the application, so you
can read what the receiving end does. Crash reports do not go here — they go to
this site's own server, described next.
Crash and freeze reports
If FoxSDR crashes, or stops responding, it writes a report describing the fault to
%LOCALAPPDATA%\FoxSDR\crashes\ on your own machine, and sends the report
text on the next start — never from inside the failure itself, because a
program that has just faulted cannot safely open a network connection. It goes to
POST /api/crash on this website — not to Cloudflare, and not to any third
party — and it is anonymous: there is no account, no licence key and nothing to
sign in with.
The switch is SYSTEM → Diagnostics, and it governs the writing and the sending equally: with it off no report is written, no directory is created, and no connection is ever made. It is a different switch from usage reporting. Turning usage reporting off does not stop a crash report — it empties the install-identifier field in one, because then no identifier exists and a crash report never mints one (see the last row of the table below). Until this release the notice above named the wrong switch; the software has always used Diagnostics, and the two now say the same thing.
This is the whole of what a report contains:
| Sent | Example | Why |
|---|---|---|
| What happened | crash or hang | A freeze and a crash are different faults. |
| Fault signature | cascade.exe+0x1a2b/adsb.dll | Groups the same fault reported by many people into one entry, so a hundred reports of one bug are one thing to fix rather than a hundred. |
| Application version, commit and build id | 0.61.0, 28fa1c2 | Which build it happened in, and which symbols match it. |
| Faulting module and offset | cascade.exe, 0x1a2b | Where in the program it went wrong. |
| Operating system and architecture | Windows 11, Linux or Android 14, x64 or arm64 | Faults are often specific to one platform. A Linux or Android report carries the same fields; the stack frames name the faulting library's GNU build id instead of a PDB id, since neither platform builds with MSVC. |
| What kind of failure it was | access violation, 0xC0000005 | The report's own reason line and the Windows exception code. In particular this is what says a fault was absorbed — the application survived it — rather than a crash; without it the two look identical. A code and a fixed sentence, never content. |
| Loaded plugins and their versions | ADS-B 1.1.0 | “Only crashes with the ADS-B plugin loaded” is a fault description; “crashes sometimes” is not. |
| Thread stacks | cascade.exe+0x1a2b per frame | The stack is the fault. It is module names, build ids and numeric offsets only — no source paths, no variables, no memory contents. |
| The tail of the session log | opened rtlsdr | The last lines the application logged, which is usually what it was doing when it failed. It is the application's own log: it records state changes — source opened, rate set, plugin started — never signal content, and never the name or path of a file you opened. It also carries what the radio driver said and what its libraries printed to the standard error stream. Before any line of it leaves your computer, the application's own lines as well as the driver's, it is scrubbed: serial numbers and the device-specific part of USB device identifiers are replaced by <stripped>, the account name in a file path by <user>, and anything in single quotes, such as the names you give patch nodes and speakers, by '<name>'; on any line that mentions hertz, a frequency, tuning, a centre, a range, an offset, a carrier, a preset or transmitting, every number is replaced by # unless it is marked as a sample rate, a time, a level, a size or a count, is a version, an identifier or an error code, or is part of a name such as R820T; and lines in which the USB driver lists the devices plugged into your computer are left out, with one line saying how many. |
| Context notes | mode: WFM, sampleRate: 2400000 | A few key/value notes the application attaches: the mode, the source (generator, I/Q file or a real radio), the sample rate, whether a device was open, the SDR model with serial numbers stripped, how many seconds the application had been running, and whether the faulting thread was running FoxSDR's own code or a radio driver's. sampleRate is the sample rate, not a tuned frequency. |
| Install identifier | 32 random hex characters, or empty | Used to rate-limit, and then discarded: the install identifier is not stored. A machine stuck in a crash loop must not be able to flood the server, and telling one machine from a hundred is the only thing this is ever read for. It is never written to disk here. If usage reporting is off it is sent empty — there is no identifier then, and a crash report never creates one. |
Corrected in FoxSDR 0.99.33. Before 0.99.33 the scrubbing described above was applied only to the radio driver's lines, not to the application's own, and a few of the application's own lines could therefore reach a crash or freeze report carrying the frequency you had asked for or were transmitting on, a patch radio's label (which can include its serial number), the names you gave patch parts, the first line of text a decoder on the patch page had produced, and the list of USB devices the USB driver printed, including their serial numbers. That contradicted this notice. From 0.99.33 every line is scrubbed before it leaves your computer, and those log lines no longer contain those values in the first place.
A crash report carries no frequency, nothing decoded, no file path, no user name, no machine name and no location. Reports are held on this site's own server, behind the same password-protected dashboard as everything else, and are kept for 90 days after the fault was last seen, then deleted — the same three months the usage reports are kept for. The first report of any one fault is kept in full, along with one further report per build the fault survives into, up to three; every other report of that same fault is counted rather than stored. An automated test holds both what the endpoint accepts and what it writes to disk to the table above, in both directions, so a field cannot be added to either without this table changing too.
A full memory dump is never sent, under any setting. A memory dump is a copy of the
program's memory and can contain file names, window titles and received signal data. It is off
by default; if you switch it on under SYSTEM → Diagnostics a .dmp is written
beside the text report, locally only, and the uploader opens files named
crash-*.txt and hang-*.txt and nothing else.
How often. At most five reports a day from one machine, and the same fault only once a day however many times it happens — both limits are kept in your own settings file, so a machine in a crash loop stops sending on its own rather than being told to, and a report that fails is retried on later starts at most three times and then left alone. Turning an offset in a report back into a function name needs the debug database from that exact build, which stays on our own machines and is never uploaded anywhere: the resolution happens locally, not on the server.
What the application never sends
- Frequencies you tune to. What somebody listens to is the most sensitive thing this software knows, and it is never collected. In the United Kingdom, intercepting a message you are not authorised to receive, or disclosing its contents, is an offence under section 48 of the Wireless Telegraphy Act 2006.
- The names or paths of files you open. A recording's file name is your own data — it can name a service, a place or a frequency. When an I/Q file fails to reopen, the log records that it did not reopen; the name stays on screen, where you already know it.
- Anything decoded — pager messages, aircraft, vessels, images, satellite traffic.
- Your position, or the position of anything you receive — including the receiver position you set, which is never transmitted in any report. See below.
- Your IP address, or any location derived from it. A request necessarily reaches a server from an address, because that is how the internet works; the usage endpoint reads no connection information and writes no request logs.
- Hardware serial numbers. The radio model is useful; the serial identifies your individual radio, and is removed before sending.
- Your name, your machine's name, your user account, or any file path.
- A full memory dump.
The receiver position, and the GPS
FoxSDR needs to know where the receiver is, because every range and bearing on the map and the radar scope is measured from it. You can type it, click it on the map, or read it from a GPS receiver on a serial port.
The position stays on your machine. It is stored in your own settings file and is never transmitted — not in the usage report, not in the beat, not in a crash report, not anywhere. Reading it from a GPS is something you start: you name the port and press “Read position from GPS”. The port is held only until the first fix arrives, and for at most 60 seconds. The diagnostic log records the port name, the baud rate, sentence and satellite counts and any error — never the position, and never the text of an NMEA sentence. A port field containing something that is not shaped like a port is logged as its kind and length (“a typed device path, 27 chars”), so a file path with your user name in it cannot ride into a report. Two automated tests hold this: one against the log ring, and one against the log file the real application wrote.
The plugin catalogue
The catalogue is contacted when you open the plugin store window (the first time in a
session, since FoxSDR 0.99.16), whenever you press CHECK NOW in it, and when you choose
to install something. Nothing is fetched at startup, the window does not reopen by
itself, and no plugin ever updates itself. The catalogue is a file published
on GitHub (raw.githubusercontent.com), so that request reaches GitHub's servers,
which — like any web request — see the address it came from. No identifier of yours is sent
with it: no install id, no cookie, nothing that could be tied to a usage report. Every download
is HTTPS, size-capped, refused on a cross-host redirect, and verified against the sha256
published in the catalogue before it is allowed to become a file. The source is a setting: you
can point it at a different catalogue, or at an index.json on your own disk, in
which case no network request is made at all.
Satellite element sets
The satellite plugin keeps its orbital element sets current by fetching them from the sources
named in its satellite.cfg, every twelve hours while it is loaded. This site keeps a
copy of those element sets at GET /tle/all.tle — CelesTrak’s stations,
amateur and weather groups plus NOAA 15, 18 and 19, refreshed here every twelve hours — and
Satellites 1.0.4 and later fall back to this file on their own whenever every source in
satellite.cfg fails, so that a machine CelesTrak refuses can still track them. The
file does not have to name this site for that to happen; a line reading
fallback-url none in it switches the fallback off, and refresh-hours 0
switches off all fetching. The request carries no identifier, no install id and no cookie, and
this server writes no analytics record for it — as with the update check, only page views
and file downloads are recorded, and the mirror is neither. The element sets themselves are
CelesTrak’s (celestrak.org) and every response says so.
Aircraft registry lookups
The optional Aircraft Info plugin shows who each aircraft on the map is — its
registration, type and operator. The application never makes this request; installing that
plugin is what enables it. From version 1.1.0 the plugin asks this site first, at
GET /api/aircraft/<address>, and sends only the aircraft’s
six-hex-digit ICAO address — the number the aircraft itself broadcasts — with no
identifier, no install id and no cookie. Each airframe is asked about once and the answer is kept
on your own machine, so it is not asked again. Only when this site does not know an aircraft, or
cannot be reached, does the plugin ask api.adsbdb.com, a free third-party service, as
earlier versions always did. The set of aircraft a receiver hears is a rough indication of where
it is, which is why the plugin is optional and says so before you install it.
What this server keeps about a lookup: nothing per request. No analytics record is written, and neither the aircraft address nor the address the request came from is logged. The only record is five running totals since the server last started — lookups, found, not found, malformed and rate-limited — which the dashboard shows. To stop anyone copying the table wholesale, each connecting address has a lookup allowance held in memory, exactly as the other endpoints here do, and never written to disk; it is forgotten when the server restarts or when more than ten thousand addresses are being tracked, whichever comes first.
The answers come from the OpenSky Network aircraft database (opensky-network.org): for each airframe its registration, type designator, manufacturer, model and, where recorded, its operator. OpenSky offers that database as is and asks users to cite: Matthias Schäfer, Martin Strohmeier, Vincent Lenders, Ivan Martinovic and Matthias Wilhelm, “Bringing Up OpenSky: A Large-scale ADS-B Sensor Network for Research”, in Proceedings of the 13th IEEE/ACM International Symposium on Information Processing in Sensor Networks (IPSN), April 2014. The registered owner recorded there is not copied to this site or served by it, because for a private aircraft it is a person’s name; only the operator, which is an airline, air force or company, is.
The browser interface
FoxSDR can serve its interface over HTTP to other machines on your own network. It is off by default and bound to your own machine until you change it; a password is required for any binding beyond that, and without one the wider bind is refused rather than opened. Passwords are stored hashed (PBKDF2-HMAC-SHA256) and sessions are revoked whenever the settings change. There is deliberately no TLS, because the application links no crypto library and will not claim transport security it cannot provide — put a reverse proxy or a private tunnel in front of it, and never port-forward it directly. Anyone you give access to can see and control what the receiver is doing.
Feature requests sent from the application
The application has a “Request a feature” box, on its main page, where you can type what you would like it to do and press Send. Nothing is sent until you press that button, it never happens automatically, and a request that fails to reach us is not queued or retried in the background — what you typed stays in the box, in memory only, for you to press Send again, and it is never written to the configuration file or the log. This is the whole of what one request carries:
| Sent | Example | Why |
|---|---|---|
| What you typed | Please add a squelch control to the FLEX decoder | The request itself: 10 to 100000 characters. Control characters are removed before it is stored; line breaks are kept. |
| Contact, if you gave one | [email protected] or a callsign | Optional, up to 120 characters, so we can ask a follow-up question. Leave it blank and the request carries nothing that could identify you. |
| Application version | 0.99.39 | Which build the request came from. |
| Operating system | windows, linux or android | Which platform sent it. |
| Architecture | x64 or arm64 | As above. |
| Schema number | 1 | The wire contract version, so a future change to the format cannot be mistaken for one of the fields above. |
It goes to POST /api/feature-request on this website. Your IP address is used only
to hold the sending rate to something reasonable, and it is never written to disk — the
record actually kept is your message, your contact address if you gave one, the application
version, the platform, the architecture, and your approximate country when our lookup can supply
one from the connection, and nothing else. It is read by the project maintainer on the admin
dashboard behind the same password as everything else here, and is kept until it is deleted
from that dashboard, or until you ask. A request that has been dealt with — added to
FoxSDR, or answered some other way — may be archived there rather than deleted, so the
project can keep track of what was asked for and what was built; an archived request is still
held, with everything listed above. If you gave a contact address and want the request deleted,
write to the address below and quote enough of what you sent for it to be found.
Bug reports and dislikes sent from the application
Directly under “Request a feature” the application has a “Report a bug / dislike” box, where you say either that something is broken or that something is there you do not like, and press Send. It works exactly like the feature-request box: nothing is sent until you press that button, nothing is queued or retried in the background, and what you typed stays in memory only — never in the configuration file, never in the log. It is not a crash report and carries nothing a crash report does. This is the whole of what one report carries:
| Sent | Example | Why |
|---|---|---|
| Whether it is a bug or a dislike | bug or dislike | The choice you made at the top of the box: something that does not work, or something that works as designed and that you would rather it did not. |
| What you typed | The waterfall freezes when I change the sample rate | The report itself: 10 to 100000 characters. Control characters are removed before it is stored; line breaks are kept. |
| Contact, if you gave one | [email protected] or a callsign | Optional, up to 120 characters, so we can ask a follow-up question. Leave it blank and the report carries nothing that could identify you. |
| Application version | 0.99.39 | Which build the report came from, so a bug already fixed is not chased again. |
| Operating system | windows, linux or android | Which platform sent it. |
| Architecture | x64 or arm64 | As above. |
| Schema number | 1 | The wire contract version, so a future change to the format cannot be mistaken for one of the fields above. |
It goes to POST /api/problem-report on this website. Your IP address is used
only to hold the sending rate to something reasonable, and it is never written to disk
— the record actually kept is whether it was a bug or a dislike, your message, your
contact address if you gave one, the application version, the platform, the architecture, and
your approximate country when our lookup can supply one from the connection, and nothing else.
It is read by the project maintainer on the admin dashboard behind the same password as
everything else here, and a report is kept until it is deleted from that dashboard, or until
you ask. A report that has been dealt with — fixed in FoxSDR, or answered some other
way — may be archived there rather than deleted; an archived report is still held, with
everything listed above. If you gave a contact address and want the report deleted, write to
the address below and quote enough of what you sent for it to be found.
The website: what is recorded when you visit
A record is written for each page view and each download whether or not you accept cookies. This is first-party analytics: the data stays on the server that serves this site, it is not shared with an advertising network, and there is no third-party script on the page.
| Recorded | Where it comes from | Needs consent |
|---|---|---|
| Date and time, page requested, HTTP method and protocol | The request | No |
| Your IP address, and a salted hash of it | The connection | No |
| Approximate location: country, region, city, postcode area, timezone, and the coordinates of that city — not of you | IP address, looked up via ip-api.com | No |
| Your network: internet provider, organisation, AS number, and whether the address is a known VPN, datacentre or mobile network | The same lookup | No |
| Browser and version, operating system and version, device type, and whether the request looks like a bot | User-Agent header | No |
Which page sent you here, and any campaign tags on the link
(utm_source and friends) | Referer header and URL | No |
| Preferred languages | Accept-Language header | No |
| Which file you downloaded, its version, how many bytes were sent and whether the transfer finished | The download itself | No |
| Screen and window size, pixel ratio, colour depth | Your browser, reported by this page's script | Yes |
| CPU core count and approximate device memory | The same script | Yes |
| Timezone, language list, dark-mode preference, touch support, platform | The same script | Yes |
| Connection type, estimated downlink speed and round-trip time | The same script | Yes |
| How long the page was visible, how far you scrolled, how many clicks, and which buttons you pressed | The same script | Yes |
What is deliberately not done
- No browser fingerprinting: no canvas, audio, font or WebGL probing, and nothing that tries to re-identify you after you have declined.
- No third-party trackers, advertising pixels, social widgets or analytics services. Nothing on this page loads from another domain.
- No attempt to read your clipboard, your battery, your camera, your microphone, your saved passwords or your browsing history — none of which a download page has any business with.
- Your data is not sold, rented or shared with anyone. The only outbound request the server makes about you is the IP-to-location lookup described above.
Interface designs you publish
This site can keep a FoxSDR interface design — a .foxui package — that you
choose to publish. Nothing is sent until you press Publish, and it goes to
POST /api/gui/publish. What is kept is what the package holds: the design itself, the
name, version and description you typed, an author name if you typed one, the time it was
published and a random identifier. Your IP address is used only to hold the publishing rate to
something reasonable, and it is never written to disk. A published package is not listed
anywhere; anyone who has its link can download it. It is kept until it is deleted from the admin
dashboard, or until you ask — write to the address below and quote its link.
If you sign up as a beta tester
Apart from publishing an interface design (above), the beta form and the news sign-up are the only places this site asks you for anything. Submitting it stores your email address, and whichever of these you chose to give: a name or callsign, your platform, the radio you plan to use, your notes, and the list of features you volunteered to test. Alongside it we keep the same visit context described above — approximate location, network, browser and operating system — because a bug report reads very differently depending on the setup it came from.
- The address is used for one thing: contacting you about beta builds and what to test. No newsletter, no marketing, and it is never passed to anyone else.
- Nothing happens until you confirm. Signing up sends one email with a six-digit code, which you type into the page to confirm the address is yours. The code works for 30 minutes and is refused after five wrong tries. Until it is entered, the entry is inert: you are not on the tester list, you are not counted, and nothing further is ever sent. If somebody else typed your address in, ignore that email and the entry never becomes real — there is nothing to unsubscribe from and no action you have to take. That one message is the only automatic mail a sign-up can produce.
- If you wrote to us, we may invite you. Somebody who has written to us and left an address — through the application's feature box, for instance — may get one personal invitation from us, with a one-time link that opens this site's Confirm key. That invitation is held as a pending entry exactly like an unconfirmed sign-up: you are not a tester and not counted unless you press Confirm, and if you ignore it we do not write to you again. A pending entry does not expire on its own; it is deleted when we clear it from the list or when you ask, by one email to the address below.
- After you confirm you get your private management link, and we write when a build lands that needs what you offered to test. That is a person writing to you, not a mailing list. If you lose the link, we can issue you a new one: the old link stops working at once, the new one is emailed to you, and we keep the time that was done and whether the email went.
- That email goes through Apple. Mail for
foxsdr.comis carried by Apple's iCloud Mail service, so your address and the message pass through their servers on the way to you, under their terms as our mail provider. Nothing else about you is sent to them. - It is kept apart from the analytics. Sign-ups live in their own file, readable only by the account running the server; the analytics log records that a sign-up happened and how many features were picked, never who. An automated test fails the build if an address ever reaches the analytics log.
- Signing up again with an address already on the list does not change that entry. Changes are made from your own tester page. Instead, the address is sent one email: its private link if it has confirmed, or a new code if it has not, and never more than once in 15 minutes.
- We keep a copy of what we sent you. Every message this site sends a tester — the confirmation, and each message about a build — is kept with its text, so we can see what was said and whether it arrived. The copy is filed against your internal id, not your address, and the personal parts of it (the confirmation code or link, and your own management link) are removed before it is stored, so a kept message can never be used to act as you. These copies are deleted with the rest of your entry when you leave.
- Messages between you and us are kept. The Messages box on your tester page is a conversation with the person building FoxSDR: what we write to you and what you write back, each with the time it was written and, if you chose one, which of your reports it is about. It is filed against your internal id, not your address, and only you (with your private link) and we can read it. We also note when you have had our messages on screen, so we know they reached you. While your page is open it asks for new messages every few seconds, so they appear as they are written, and it says how long ago you last used it; while it keeps asking, and half a minute after, and only if you used it in the last five minutes, the server knows you are there. That is held in its memory only, never written down. We do not email you for each message: when we write while you are away, you get one short email saying a message is waiting, with your link and without the message itself. No other such email follows while that message is unread, for up to 12 hours, nor within half an hour of the last; and if you were on the page when we wrote but have not seen the message ten minutes later, the email goes then. A copy of that email is kept as described above; when you write, no email is sent anywhere. The conversation is kept until you leave or ask us to delete it, and leaving deletes all of it.
- Kept until the beta programme ends, or until you ask. One email to the address below removes you and deletes the entry — you do not have to give a reason.
- The lawful basis here is your consent, given by ticking the box; the form does not submit without it.
If you sign up for news by email
The news page asks for one thing: your email address. It is kept so we can email you when there is a new version of FoxSDR, and now and then about what is being built. It is used for nothing else and never passed to anyone.
- Nothing happens until you confirm. Signing up sends one email with a six-digit code to type into the page. Until it is entered, nothing else is sent, and an address that has not confirmed within a week is deleted - by code that runs on the server every day. If somebody else typed your address in, ignore that email.
- Every email carries a link that takes you off the list in one press. Leaving deletes the address from the server's file, together with the copies we kept of what it was sent; nothing about it is kept.
- It is its own list. A news subscriber is not a beta tester: the address is kept in a separate file, readable only by the account running the server, and is not counted or shown as a tester. If you are also a tester you get each message once.
- We keep a copy of what we sent you, filed against an internal id rather than your address, with the confirmation code and unsubscribe link removed, exactly as for testers.
- That email goes through Apple, as described for testers above.
- The analytics log records that a sign-up happened, never who.
- The lawful basis is your consent, given by ticking the box; the form does not submit without it.
Cookies
| Cookie | Purpose | Life |
|---|---|---|
fox_consent | Remembers whether you accepted or declined, so you are asked once | 1 year (accepted) / 6 months (declined) |
fox_vid | A random identifier so a return visit is recognised as the same browser. Set only if you accept. | 400 days |
fox_sid | Groups one sitting into a session. Set only if you accept. | 30 minutes of inactivity |
fox_beta | Holds your beta-tester link so you can get back to your own entry. Set only if you sign up as a tester, and only because that is the thing you asked for — it does no measuring, so it is not part of the analytics choice above. Removing yourself clears it. | 400 days |
foxsdr_lang | Remembers the language you picked for this site, so the next page is in it too. Set only when you choose a language yourself — with the language selector or a link carrying ?lang= — and it holds nothing but that language's code, such as es. It does no measuring, so it is not part of the analytics choice above. | 1 year |
fox_news_joined | Not a cookie: a flag in your browser's own storage, never sent to us. After a download the site asks whether you would like the news by email; once you have signed up and confirmed from this browser it stops asking. It holds nothing but 1, and only if you signed up. | Until you clear this site's data |
If you decline, no identifying cookie is set. Visits are then grouped by a daily-rotating hash of your address and browser, which distinguishes visitors for counting purposes and is not usable to follow you between days or between sites. You can change your mind by clearing this site's cookies and reloading.
Which language you see
The pages can be shown in languages other than English. Which one you get is decided on the
server for each page you ask for, in this order: a language you picked yourself (the
foxsdr_lang cookie above, or ?lang= in the link); otherwise the
languages your browser says you prefer, from its Accept-Language header; otherwise
the main language of the country your connection comes from, which Cloudflare, the network in
front of this site, passes along with the request as a two-letter country code
(CF-IPCountry); otherwise English. Nothing is stored to make that choice: the
header and the country code are read for that one response and not kept for it. They are the
same two things the table above already lists as recorded with every page view, where the
country code is used when our own address lookup has no answer. The translations are made by
machine, and on this notice and the licences the English text is the one that binds.
Why, and on what basis
The purpose is narrow: knowing how many people find this project, roughly where they are, what they run it on, and how many go on to download it. That is what decides whether the work continues and what gets built next.
The server-side records are kept on the basis of legitimate interests in understanding and securing the site. The browser-reported detail and the identifying cookies are kept on the basis of your consent, which is why they are behind the banner and why declining costs you nothing on this site.
How long it is kept, and who sees it
Records are held for 24 months and then deleted. They sit in a file on the server behind a password-protected dashboard that only the project maintainer can open. There are no other recipients and no transfer to a third country beyond the IP lookup already described.
Two things are kept for less. Crash and freeze reports are deleted 90 days after the fault they describe was last seen, and the usage reports Cloudflare processes are deleted after three months. Each of those periods is enforced by code that runs on the server every day, not by anybody remembering to do it.
Your rights
If you are in the UK or the EU you can ask for a copy of what is held about you, ask for it to be corrected or erased, or object to it being collected at all — including the server-side records that do not depend on consent. The practical identifier for finding your records is your IP address at the time you visited, so please include it and roughly when you visited.
For the application, the controls are in the software itself, and there are three:
- SYSTEM → Usage reporting stops the usage report and the five-minute beat, and deletes the install identifier. Turn it back on later and you get a new identifier that cannot be linked to the old one.
- SYSTEM → Diagnostics stops crash and freeze reports being written or sent.
- SYSTEM → Updates stops the update check.
The reports hold nothing that can be connected to you, so there is nothing to request access to; if you want an install identifier removed from reports already sent, write to the address below and quote it, and it will be deleted.
Children. FoxSDR is a technical instrument for radio hobbyists. It is not directed at children, it collects no personal information from anyone, and it therefore collects none from children.
Write to [email protected]. You can also complain to the Information Commissioner's Office (ico.org.uk) if you think this has been handled badly.
Last updated 24 September 2026, against FoxSDR 0.99.39 — the build this site
currently offers, and the one every statement above was checked against in its source.
FoxSDR is published by Steven Fox; write to the address above with any question about
this notice or to have an install identifier deleted from reports already sent.
If this notice ever stops matching what the software does, the
software is wrong — the website's collection is implemented in store.go and
app.js, both readable in the site's own source, and the application's own list
ships with it as PRIVACY.md with a test holding the payload to it.