Asteri

Privacy Policy

Last updated: 5 September 2026

Asteri is a Discord moderation bot and web panel operated by LunarcatOwO ("the operator"), one person rather than a company. This policy covers the instance running at asteri.lunarcatowo.space and the Discord bot Asteri that goes with it. It explains what the service stores, why it stores it, who can read it and how long it is kept.

Asteri is a hosted service. There is one instance, the one described here, and it is run by the operator. Any other bot calling itself Asteri is not this service and is not covered by this policy.



Two different parties are responsible for two different things.

The server's staff. Everything Asteri records inside a Discord server is recorded because that server's administrators configured it. They decide whether message logging is on, whether tickets keep transcripts, what the word filter contains and who is banned. For that data they are the ones who decide what is collected and why. Asteri is the tool they use to do it.

The operator. LunarcatOwO runs the instance, holds the database, and decides how the service as a whole works. For panel accounts, sessions and the panel audit log, the operator is responsible directly.

If you want something removed from a specific server's moderation history, that server's staff are the people who can do it, and asking them is faster than asking the operator. See Your choices for what to do when they will not.


The bot connects to Discord with the Guilds, Guild Members, Guild Messages, Message Content, Guild Moderation and Guild Voice States intents. Message Content is a privileged intent, and it means exactly what it says: Discord sends the bot the text of every message in every channel it has access to.

That is unavoidable for what the bot does — a spam rule cannot count repeated messages it is never sent, and a word filter cannot match words that never reach it. But receiving is not storing. Messages are checked in memory against the rules a server has switched on, and then discarded. In a server that has not switched on message logging, a message that trips nothing leaves no trace.

The exception is the message archive, and it is the one thing on this page worth reading twice. See Chat below.

Asteri has no access to your direct messages: the DM intent is not requested, and a bot only ever receives DMs addressed to it. It does send DMs — punishment notices, appeal decisions and ticket transcripts — when a server has configured it to.


Everything below lives in one database controlled by the operator. Nothing is sent anywhere else.

WhatWhen it is writtenHow long it is kept
Cases — the type of action, who it was against, which moderator did it, the reason, the duration, and whether it is still in effect. Both user IDs and the username at the time are stored.Every ban, kick, warning, timeout, note, role change, purge and pardon, whether it came from a command, the panel, an automatic rule, or from a moderator acting through Discord itselfUntil the server or the person is deleted from the database (see Retention)
Automod hits — which rule fired, which signals it broke, the channel, the member, and an excerpt of the offending message of up to 500 charactersEvery time a spam, invite, filter, scam or reply-ping rule firesSame
Case metadata — small structured details attached to a case, such as the invite code that was blocked or a short excerpt of what caused itWith the caseSame
Lockdowns — the channel, the moderator, the reason and the channel's permissions as they stood before it was shutWhen a channel or a server is locked downSame
WhatWhen it is writtenHow long it is kept
The message archive — author, channel, message text of up to 4,000 characters, attachment names, sizes and Discord URLs, and how many embeds a message carriedOnly when a server has the mod log switched on and has switched on message-delete or message-edit logging. With those off, nothing is written.Seven days. A sweep runs hourly and deletes everything older.
Ticket transcripts — every message sent in a ticket channel, with its author, its text, its attachment names and URLs, and whether it was later edited or deletedWhen a server has tickets and transcripts enabled, for the messages in a ticket channel onlyUntil the ticket is deleted from the database. Transcripts deliberately outlive the channel — that is the point of them. Capped at 5,000 lines per ticket.
Sticky message text, and message-request bodiesWhen a server configures a sticky or a member submits a requestUntil deleted by the server

The message archive exists for one reason: a Discord deletion event carries a message ID and a channel ID and nothing else — not the author, not the text. Without a copy already stored, a delete log can only report that a message was removed, never what it said. A server that never switches message logging on never has a single row written for it.

What the seven days does and does not cover. It is the retention on Asteri's own copy of chat — the working material the delete and edit logs are written from. It is not a promise that logs disappear. Once something has actually been logged, the record of it is elsewhere and is not on that clock:

So a server with message logging on will still have log entries from months ago. What it will not have is the underlying archive rows, which are gone after a week — which is why a deletion older than that is reported without its text.

WhatWhen it is writtenHow long it is kept
Appeals — the questions as they were asked, the answers as they were written, the appellant's ID and username, the reviewer, their reply, and the decisionWhen a member files an appeal on the panelUntil deleted
Tickets — the form answers, the opener, anybody added to the ticket, who claimed it, and how it endedWhen a member opens a ticketUntil deleted
Message requests — what a member asked to have posted, who reviewed it, and what the reviewer wrote backWhen a member uses /requestUntil deleted
WhatWhen it is writtenHow long it is kept
Levels — a member's XP, level, and how many messages earned XP. No message text.Only when a server has levels enabledUntil reset by the server or deleted
Temporary voice rooms — the channel and who owns itWhile the room existsDeleted when the room is
Server records — the server's ID, name, icon, owner ID and member countWhile the bot is in the serverSee Retention

/steam reads Valve's public store data and keeps a copy so the same question does not have to be asked twice. None of it is about you.

WhatWhen it is writtenHow long it is kept
Game names and their Steam app IDs, so the command can complete what you typeWhen somebody looks a game up, or on a scheduled refresh of the published listIndefinitely. It is Valve's public catalogue, not a record of anybody.
A game's public store page — description, price, developer, publisher, platforms, release date, review totals and the newest patch noteWhen somebody looks that game up and the stored copy has gone staleRefreshed in place; kept while the game is being looked up
Player counts — how many people were in a game at a moment, and whenWhile anybody has looked that game up in the last weekSwept after 48 hours

Asteri retrieves no Steam data about any Steam user. It never asks Valve about a profile, a library, a friends list, an inventory or a playtime, and it has no way to link a Discord account to a Steam one. Nothing is written down about who ran the command — not your ID, not the game you asked for. The stored "last looked up" time belongs to the game, and is only there to decide which games are worth keeping fresh.

The data is Valve's, presented as-is, and Asteri is not affiliated with or endorsed by Valve. It is stored in the same place as everything else — see Where the data lives.

/translate, and the Translate entry on a message's right-click menu, send the text you asked about to a translation server and show you what comes back.

The text is never written down. There is no table, no column and no log line holding the text of a translation, who asked for it, or what it said. The bot keeps identical translations in its own memory for a short while — an hour by default — so that the same message translated by five people in a row is one request rather than five, and a restart clears that.

One thing is stored, and only if you ask for it. Right-clicking a message answers in the language your Discord client is set to; /preferences language changes that, and changing it writes a row:

WhatWhen it is writtenHow long it is kept
The language you chose to be answered in, against your Discord user IDOnly when you run /preferences languageUntil you set it back, or ask for it to be deleted
The date you were shown the one-time note saying that language can be changedThe first time you use the right-click commandSame

That is the whole of it — a language code and a date. There is no row at all for somebody who has never changed the setting, and using the command does not create one beyond that single date. Nothing else about you is recorded by translating anything, and this is the only thing you can cause Asteri to store about you as a person rather than about a server. The one other place a Discord ID is held outside a server's moderation records is the operator's cooldown bypass list, which nobody is added to by using Asteri.

The translation server is part of this instance. It runs on the same machine as the bot, on a private network, and is not reachable from the internet. The text does not go to Google, DeepL, or any other translation company, and no third party sees it. An operator running their own copy of Asteri can point it somewhere else; on the instance this policy covers, it is here.

Machine translation is approximate. Every card says so, and shows the original beside the translation, because the two ways this gets read badly are treating it as what somebody actually said and quoting it back at them.

/wikipedia reads a public Wikipedia article and keeps the summary so the same question does not have to be asked twice. None of it is about you.

WhatWhen it is writtenHow long it is kept
An article's summary — its title, one-line description, opening paragraph, lead image address, canonical link and when it was last editedWhen somebody looks that article up and the stored copy has gone staleRefreshed in place, and deleted once nobody has opened it for 30 days

Nothing is written down about who asked. Not your Discord ID, not the article you looked for, not the language you read it in. There is no search history, and no way to reconstruct one. The stored count of how often an article has been opened, and the date it was last opened, belong to the article — they exist to decide which copies are worth keeping and which to delete, and they do not distinguish one person from another or from a thousand.

Wikipedia is not told who you are either. The request goes out from this instance, so what Wikimedia sees is the server, not you: not your Discord ID, not your IP address, and nothing identifying the person who typed the command.

The per-person wait between lookups is held in the bot's memory for about an hour and is never written to the database. Restarting the bot forgets it.

The article text and the summaries are Wikipedia's, contributed by its volunteers and licensed CC BY-SA; every card names Wikipedia and links back to the article. Asteri is not affiliated with or endorsed by the Wikimedia Foundation.

/search sends the words you type to DuckDuckGo and shows you the instant answer that comes back — the summary box that sits above search results, not the results themselves.

This is the only command that sends text a member wrote to a company outside this instance, so it is worth being exact about what goes and what does not.

What is sent: the query, and nothing else. What is not sent: your Discord user ID, your username, the server you ran it in, the channel, your IP address, your language, your region, or any identifier for you at all. The request is made by the bot from its own server, so what DuckDuckGo receives is this instance asking a question. There is no account behind it, no API key identifying anybody, and no cookie. DuckDuckGo cannot tell one member from another, or a member from the operator.

The question is never written down. There is no table, no column and no log line holding what was searched for, who searched for it, or what came back — not on the failure path and not for troubleshooting. The bot keeps identical answers in its own memory for a short while — fifteen minutes by default — so that the same question asked five times in a channel is one request rather than five, and a restart clears that.

WhatWhen it is writtenHow long it is kept
Nothing——

That table is not a joke and it is not an omission. Every other command that reaches outside Discord keeps a copy of what it fetched, because a Steam page and a Wikipedia article are public things about nobody. A search cache is keyed on the sentence you typed, which is a different kind of object: kept on disk and read later, a list of those is a search history, and leaving your user ID off it does much less work than it sounds like it does — questions are often self-identifying on their own. So nothing about a search reaches the database.

The per-person wait between searches is held in the bot's memory for about an hour, as a user ID and a time with no query attached, and is never written to the database. Restarting the bot forgets it.

Two things are deliberately not built. There is no autocomplete, which means a half-typed question never leaves this instance — the command sends one request when you press enter, rather than one per keystroke. And no region is sent with the query, so answers are not localised to you; doing that would mean volunteering something about where you are in order to slightly reorder a summary.

What Asteri refuses to show. One thing, and it is about the operator rather than about you: an instant answer describing the requester, such as "what is my IP". From DuckDuckGo's side the requester is this bot, so what came back would be the address of the server Asteri runs on rather than anything about you. It is dropped before it reaches a card.

Bangs are passed through, with their destination named. A !bang is DuckDuckGo's shortcut for running a search somewhere else — !g for Google, !yt for YouTube — and typing one gets you a card with a button to that site. Worth knowing what that button is: it points at the destination itself, on the destination's own address, not at DuckDuckGo. !g cats resolves to a Google search URL. DuckDuckGo chose it and is out of the picture once you click, so the card names the site in the text and again on the button, and Asteri never follows the link itself — you do, if you want to. Where you go after that is between you and that site.

Your use of /search is not governed by DuckDuckGo's privacy policy in the way visiting their site would be, because you are not the one contacting them. Their privacy policy describes what they do with API traffic; the operator has no control over it, and no agreement with them beyond using a public endpoint. What the operator can say is what leaves here, which is above.

Asteri is not affiliated with, endorsed by, or sponsored by DuckDuckGo.

/pat makes a short GIF of somebody's avatar being patted. Nothing about it is written down — there is no table, no row and no log line, for the pat, for who ran it, or for who was patted.

What happens is: Asteri downloads the avatar from Discord's own CDN, draws the frames in memory, and sends the result as a file. Two things are held in the bot's memory afterwards and nowhere else:

WhatWhyHow long
The finished GIFSo a channel patting one person eleven times is drawn once rather than eleven timesTen minutes, and at most 60 at a time. A restart clears them.
The time you last ran itThe four-second wait between patsAbout an hour, then forgotten. A restart clears it too.

Neither survives a restart, and neither reaches the database. The GIF is keyed on the avatar's address, which contains Discord's hash of the image — so a changed avatar is a different key, and no old picture of anybody can be served by mistake.

The avatar is not stored, and nothing is uploaded anywhere. The drawing happens inside the bot; no image service, no third party and no other machine sees it. The avatar used is the one already visible to everyone who can see the person in that server.

One thing does last, and it is worth being clear about: the GIF Asteri posts is an ordinary Discord message. It stays in the channel until somebody deletes it, exactly like any other attachment, and that copy is Discord's rather than Asteri's. Anybody can pat anybody — if you would rather a pat of you was not sitting in a channel, deleting the message is the fix, and any moderator can do it.

/calc works out a sum you type and posts the answer. Nothing about it is written down — there is no table, no row and no log line, for the expression, for the answer, or for who asked.

WhatWhen it is writtenHow long it is kept
Nothing——

That table is the same one /search has, and here it is easier to stand behind, because this command has no second half. There is no API, no key and no request: the arithmetic happens inside the bot, in its own process, in about the time it takes to read this sentence. Nothing you type reaches DuckDuckGo, Wikipedia, Valve, or any other company, because nothing leaves the machine at all.

There is also nothing held in memory afterwards. The lookup commands keep what they fetched for a while so that the same question asked twice is one request, and /pat keeps a finished GIF for ten minutes for the same reason. A calculation has nothing worth keeping: working it out again is cheaper than remembering it, so there is no cache, and there is no per-person timer either — /calc is the one command with no rate limit, so there is nothing about you to hold even for an hour.

The autocomplete does not send anything anywhere either. The expression box shows you the answer while you are still typing, and that preview is produced by the same calculator running on the same machine. Discord sends the bot what you have typed so far, as it does for every autocomplete in every bot; the bot works it out and sends back a label. Nothing is stored on either side of that, and no third party is involved.

One thing does last, and it is worth being clear about: the card Asteri posts is an ordinary Discord message. Unless you used quiet, the sum and its answer sit in the channel until somebody deletes them, exactly like any other message, and that copy is Discord's rather than Asteri's. A sum you would rather nobody read is a sum to run with quiet: True, which shows the answer to you alone. A sum that does not parse is always shown to you alone, whichever way you ran it.

/graph draws a picture of an expression and posts it. Nothing about it is written down either — not the expression, not the window, not the image, not who asked.

WhatWhen it is writtenHow long it is kept
Nothing——

The chart is drawn inside the bot, in its own process, out of the same calculator that answers /calc and the same image writer that draws a pat. There is no plotting service, no Desmos, no headless browser and no image host: nothing you type reaches another company, and no picture of it is uploaded anywhere. The finished image is sent straight to Discord as an attachment and is not kept here afterwards.

One thing is held in memory, and it is the same thing /pat holds: the time you last ran the command, as a user ID and a time with nothing attached, so the six seconds between graphs can be counted. It is forgotten after about an hour and a restart clears it.

As with /calc, the card Asteri posts is an ordinary Discord message and stays in the channel until somebody deletes it. quiet: True shows the graph to you alone.

/regress fits a model to points you supply and draws it over them. Nothing about it is written down — not the points, not the model, not the fitted values, not the picture, and not who asked.

WhatWhen it is writtenHow long it is kept
Nothing——

This is the one command that reads a file you upload, so it is worth being exact about what happens to it. The attachment is fetched from Discord’s own CDN, at the address Discord supplied with the command — never at an address anybody typed, so there is no way to point it at another site. It is capped at 256KB, checked both against what Discord says the file is and against what actually arrives. It is then read as text, parsed into two columns of numbers, used for the fit, and dropped.

The file is never written to disk and never reaches the database. Nothing is extracted from it but the first two numeric columns of each row; anything else in it — a label column, a header, a comment — is discarded unread into the same nothing. No fitting or plotting service is involved, because there is not one: the arithmetic and the drawing both happen inside the bot.

The uploaded file itself stays where Discord put it. An attachment on a Discord message is Discord’s copy and lives under Discord’s retention, not Asteri’s — if you would rather it were not there, deleting the message is the fix, exactly as with any other attachment.

As with /calc and /graph, the time you last ran the command is held in the bot’s memory for about an hour so the ten seconds between fits can be counted. It is a user ID and a time with nothing attached, and a restart clears it.

There is one small list of Discord user IDs, and it exists because the operator needs to be able to skip the wait between lookups while working on the bot.

WhatWhen it is writtenHow long it is kept
A Discord user ID, which command it applies to, an optional note, and who added itOnly when the operator adds an entry by hand, on the instance settings pageUntil the operator removes it

Nobody is added to this by using Asteri, and nothing you do can put you on it. It is edited only by the operator, on a page only the operator can reach. An entry waives the wait between uses of a command and nothing else — it does not grant access to anything, does not change what anybody can see, and does not affect any other person's data.

If you are on that list and would rather not be, ask and it will be removed; see Making a request.

WhatWhen it is writtenHow long it is kept
Your account — Discord user ID, username, display name and avatar hashWhen you sign inUntil deleted on request
Discord OAuth2 tokens — encrypted at rest with AES-256-GCMWhen you sign inReplaced on each sign-in; removed with the account
Sessions — a random session ID, your IP address and your browser's user-agent stringWhen you sign inSessions expire after seven days; the row is kept after that so "when did this device sign out?" has an answer
The audit log — every configuration change made through the panel, with who made it, a diff of what changed, and their IP addressOn every change, export and decision made through the panelKept indefinitely. It is the accountability record; a log that can be edited is not one.

The panel requests two OAuth2 scopes from Discord and no others: identify, which returns your account, and guilds, which returns the list of servers you are in so the panel can show you the ones you manage. It never requests your email, your connections, or the ability to act as you.



The panel sets two cookies, both strictly necessary, and neither used to track you anywhere:

It also uses two keys in your browser's own storage, which never leave your device and are never sent to the server: asteri-theme, remembering whether you chose light or dark, and asteri-arriving, a one-shot flag that plays the arrival animation after sign-in.

There is no cookie banner because there is nothing to consent to.


Nothing is sold. Nothing is shared with advertisers, data brokers or AI training pipelines. Data is disclosed to anybody else only where the law requires it.



You can:

Another server's moderation record of you will not be deleted on your say-so — a ban with a reason attached belongs to that server's history, the staff who wrote it have a legitimate interest in keeping it, and erasing it on request would make every ban list in the service worthless. If you think a record is wrong, appeal it in the server, or ask that server's staff. If you believe a server is using Asteri to break the law, say so at the address below and it will be looked at — including, if warranted, by refusing that server the service (see the Terms).


If you are in the EU or the UK, the GDPR gives you the rights set out here and the operator is bound by it. The same requests are answered for everybody, wherever you live: the UK, Canadian, Californian and Australian regimes grant much the same things, and running two standards would be more work than running one.

For panel accounts, sessions, stored OAuth tokens and the panel audit log, the controller is LunarcatOwO, reachable at [email protected].

For everything that belongs to a Discord server — cases, automod hits, archived messages, ticket transcripts, levels, and also the appeals, tickets and message requests that members submit — the server's administrators decide what is collected and why. They are the controllers of it; the operator provides the tool and acts on their configuration, in the role of a processor.

Appeals and tickets are worth calling out, because the panel is where you fill them in and that makes them look like the operator's. They are not. An appeal is a request to one server to reconsider one of its own punishments, a ticket is a conversation with that server's staff, and a request asks that server to post something — all three are read, decided and kept by the server, and the operator is only the machinery in between. So a request to delete an appeal you filed goes to the server you filed it against.

This is the split described in Who is responsible for what, and it is why some requests are answered by the operator and some have to go to a server's staff. The terms the operator processes that data under are set out in Appendix A of the Terms, which is the agreement every server administrator accepts by using Asteri.

WhatWhyBasis
Cases, automod hits, lockdowns, the message archiveSo a server can moderate itself, keep a record of what its staff did, and explain a punishment afterwardsLegitimate interests, Art. 6(1)(f) — the server's and its members' interest in a moderated, safe server
Appeals, tickets and message requestsTo handle the thing you submitted, and to give you an answerArt. 6(1)(b)/(f) — necessary to act on your own request
Panel accounts, sessions, OAuth tokensTo sign you in, to keep you signed in, and to check you manage the server whose page you openedArt. 6(1)(b) — necessary to provide the panel you asked for
Session IP addresses and the panel audit logTo know who changed what, and to investigate abuse of the serviceLegitimate interests, Art. 6(1)(f) — security and accountability
The cooldown bypass listSo the operator can work on the bot without waiting between commandsLegitimate interests, Art. 6(1)(f) — operating and maintaining the service
The text of a /search query, sent to DuckDuckGo and not storedTo answer the question you asked, which cannot be done without asking somebodyArt. 6(1)(b)/(f) — necessary to act on your own request. Nothing identifying you is sent with it, and nothing is retained afterwards
Anything handed to an authorityBecause the law required itLegal obligation, Art. 6(1)(c)

None of it is processed on the basis of consent, so there is no consent to withdraw — but the panel's access to your Discord account is an authorisation you granted, and you can take that back at any time in Discord's Authorized Apps settings.

Some punishments are applied by rule, without a person in the loop: a spam burst can end in a timeout, and a channel configured to auto-ban bans whoever posts in it. Those rules are configured by the server, apply only inside that server, and have no effect outside Discord. Where a server has appeals switched on, filing one puts the decision in front of a human, which is the route to contest anything automatic. No profiling is carried out, and nothing here is used to make decisions about you anywhere else.

Email [email protected] with your Discord user ID, and say which server the request is about if it concerns one. Requests are free.

How long it takes. The target is one month from receipt, which is what the GDPR asks for. Where a request is complicated, or where several arrive at once, that can be extended by up to two further months — three months in total, which is the longest the law allows and the longest this policy will ever take. An extension is not silent: you will be told inside the first month that it is happening and why. A request the operator is not going to act on is also answered inside the first month, with the reason and with what you can do about it.

The only identity check is the Discord account itself — confirmation may be asked for through it, because a user ID alone is not proof that you are the person behind it. A request nobody can tie to an account cannot be answered, since the alternative is handing somebody else's moderation history to whoever asks for it.

The service is hosted on Oracle Cloud Infrastructure in Canada, and Discord is a United States company. If you are in the EEA or the UK, using Discord already means your data is handled in the United States, before Asteri ever receives any of it.

Nothing is deliberately transferred anywhere beyond those two countries. /steam contacts Valve, in the United States, but sends nothing about any person — see Who can see your data. /search contacts DuckDuckGo, also in the United States, and sends the query without anything identifying who asked — see Instant answers. Translation does not leave the instance at all: the server it uses runs alongside the bot — see Translation.


No service is perfectly secure, and this one is run by one person. If you find a vulnerability, please report it privately to the address below rather than publicly.


Discord requires everybody using it to be at least 13, or older where local law sets a higher age. Asteri is used through Discord and inherits that rule. It is not directed at children, and no account is knowingly set up for anyone below Discord's minimum age. If you believe a child's data is in the database, say so at the address below and it will be removed.


The bot, the panel and the database run on Oracle Cloud Infrastructure in Canada, with the database reachable only from the instance's own private network. Everything described in this policy is stored there, including the cached Steam data under Steam lookups and the translation server under Translation. /search stores nothing anywhere — see Instant answers.

Discord is a United States company, and everything the bot receives passes through Discord's infrastructure before it reaches Asteri at all.


Material changes will be announced before they take effect, and the date at the top of this page always says when it was last revised. Continuing to use Asteri after a change means the revised policy applies to you.


One address, for everything on this page — privacy requests, access and deletion requests, GDPR questions, security reports and anything else:

Please include your Discord user ID. It is the one identifier that reliably points at a single person: usernames change, and the ones stored beside a case are snapshots of who somebody was at the time rather than who they are now.