megaloop
Sign in

On this page

  • Who we are, and what megaloop does
  • The short version
  • Requests and responses
  • What we collect, and why
  • The legal basis for each of these
  • Your provider credentials, and how they are encrypted
  • Third parties
  • Retention
  • Your rights, and how to exercise them
  • Where your data lives
  • Security
  • Cookies, browser storage, and Do Not Track
  • Children
  • Changes to this policy
  • Contact

Policy

Privacy Policy

Effective: 2026-08-28 Last updated: 2026-08-28

What changed on 2026-08-28. We now record when a response FINISHED (completed_ms), and we corrected what the row above it claims. latency_ms was described here as "how long the whole request took"; it is not, and cannot be for a streamed reply — it is stamped when the response starts, before any of the answer has been generated. Nothing new about you is stored: both are timings of a request we already timed. What changed on 2026-08-22. Keeping a copy of your requests is now off unless you turn it on. New accounts start with it off and nothing is stored until you choose otherwise. When it is on, a copy of each request and response is kept for seven days, encrypted, so that a failed request can be diagnosed from what was actually sent. Requests and responses sets out what is kept, for how long, who can read it, and what is never kept. Earlier versions of this policy are preserved in full — write to support@megaloop.dev for a copy.

Who we are, and what megaloop does

megaloop is operated by AI PWRD Inc., a Delaware corporation ("megaloop", "we"), the controller of everything described here. This policy covers the megaloop service at megaloop.dev — the website, the dashboard, the management API, and the inference gateway. Write to us about any of it at support@megaloop.dev.

megaloop is a gateway. You link the AI subscriptions you already pay for — your own accounts, your own credentials — and megaloop gives you one endpoint and one key. Each request goes to one of your linked accounts, using your credential, and the answer streams back. So we hold your provider credentials, encrypted, and your prompts pass through us on the way to a provider you chose. What we keep of them — and what we never keep either way — is set out below.

The short version

  • We keep nothing of what you send unless you switch it on. New accounts start with it off. With it on, your requests and the responses to them are kept for seven days, encrypted, and then deleted permanently. Nothing renders them and no API returns them; they are readable only by us, on the server, and only to diagnose a problem.
  • We still never write them to a log or to disk in the clear. Of the headers sent on an inference request we store exactly two — the address your request came from and the user-agent your client sent — and nothing else.
  • We do store one row of metadata per attempt on an account, and one for a request we turn away before reaching any account, kept for ninety days. Every column of it is listed under What we do keep instead, the authoritative list — section 11 of the Terms (/terms) points at it rather than repeat it.
  • To read the provider's token counts we read a bounded head and tail of the response body, in memory, looking for nothing but its own usage figures.
  • Your provider credentials are encrypted with AES-256-GCM before they are written, and decrypted only to serve a request or refresh a token.
  • There is no password anywhere in the system.
  • Since 2026-08-19 we do store the IP address a request came from, on the same metadata row and under the same ninety-day deletion. We did not before that date, and this document said so; it changed because a runaway client sent 34,121 failing requests and nothing we held could say which machine they came from. It is operational, not commercial: see What we do keep instead.
  • We run no analytics, no tracking, no advertising, and no third-party scripts, and we do not sell or share personal information.

Requests and responses

Off unless you turn it on

We keep nothing of what you send unless you switch this on. A new account starts with it off, and while it is off no request or response of yours is stored at any point — there is nothing to delete, because nothing was written.

With it on, a copy of each request and response is kept for seven days. After that they are deleted permanently, by a job that runs every five minutes. There is no archive and no backup of them that outlives the seven days beyond the encrypted backups described under Retention.

The setting is in Settings → Privacy and takes effect on your next request. It changed to off-by-default on 2026-08-22; accounts created before that date keep whatever setting they already had, and can change it in the same place. Earlier versions of this policy are preserved in full and we will send you a copy on request.

Why. A request that fails records a status code and, where the provider gives one, a one-line reason. That is often not enough to tell a broken request from a request for something that does not exist — and the difference decides whether anyone needs to do anything. Keeping what was actually sent is how that question gets answered in minutes instead of not at all.

Exactly what is kept:

WhatThe body of your request as you sent it, and the body of the response as the provider produced it, framing included — with credentials removed before anything is written. Text matching a key, token, private key or password-in-a-URL is replaced with [redacted:…] and is never stored. This is pattern-matching, not a guarantee: treat it as a safety net, not a licence to paste secrets
WhenOnly while you have it switched on. Nothing is written when it is off
How longSeven days from the moment the request finished. Enforced by a sweep, not by a promise — see Retention
How it is storedEncrypted with AES-256-GCM before it is written, in one table used for nothing else, bound cryptographically to your account and to that one request. A copy of our database, without the key, is ciphertext. This is the same protection your provider credentials get
Who can read itUs, on the server, with the key — and an admin of your account, through one API endpoint that returns a stored request. Nothing in the dashboard shows it. A member cannot read one, and an API key cannot either: it takes a signed-in admin. Every read is recorded in your account's audit log, with who read it and which request
Turning it offYours to do, in Settings → Privacy. Takes effect on the next request, and deletes every copy already stored, immediately
Size limitBounded. A very large request or response is stored as a prefix, and the row records that it was cut

What is still never kept, and this has not changed:

  • Your API key is never stored as a header, and neither is anything else you send — with two named exceptions, both added 2026-08-19 and both on the metadata row: the address the request came from, and your client's user-agent. Nothing else you send is kept. Your browser's User-Agent is also stored off the inference path, on a sign-in session and on the record of your acceptance of these documents. All of them appear under What we collect, and why.
  • Nothing is written to a log file. Our logger is not handed request or response content, and no call site on the serving path passes it a value taken from your prompt or the model's reply.
  • Nothing is used to train anything, sold, shared, or given to any third party. We run no analytics over it and no automated reading of it of any kind. It is read by a person, deliberately, when something has gone wrong — and by nothing else.

If you would rather we did not keep it, turn it off yourself. Settings → Privacy, in the dashboard. From that moment nothing is written for your account — not "written and hidden", not "written and deleted sooner". Everything already captured is deleted at the same moment, rather than waiting out the rest of its seven days. You will lose nothing except our ability to diagnose a failure you report from what was actually sent.

This was a request to support@megaloop.dev until 2026-08-17, which meant a privacy commitment whose only mechanism was somebody remembering. Writing to us still works; you no longer have to.

How it reaches storage without slowing you down

Your response is still handed straight back to you, unchanged and undelayed — each chunk is delivered to you first and copied for storage afterwards, so the capture cannot sit between the provider and you. The copy costs memory on our side, never time on yours.

  • Your response is never held back. The provider's own stream, each chunk passed along and then copied — you receive the byte before storage does, so nothing you wait for is our doing. The copy stops at 1 MiB and the row records that it stopped (CAPTURE_MAX_BYTES in packages/gateway/src/handler.ts).
  • Two further bounded windows are read for the token counts, and only for those: the first 4,096 bytes of the first chunk, and a rolling last 16,384 bytes. The two sizes are PEEK_BYTES and TAIL_BYTES in the same file.
  • Your request body is read for one field — which model you asked for. It is also modified before it is forwarded, and every modification is set out under What megaloop changes about your request. Nothing you wrote is removed or reordered.
  • The request bytes stay in memory for the life of the request, so a rate-limited account can be retried on the next one. They go when it ends, and a response abandoned on rotation is cancelled, not read.
  • Our logger is not handed your prompts. Its type signature accepts only strings, numbers and booleans as named fields, so a request or response body cannot be passed to it whole — and no call site on the serving path passes it a value taken from your prompt or the model's reply. (This bullet previously said a body "is not expressible as an argument". That overstated what a type can promise: a prompt is a string, so the type alone does not prevent it. The constraint that actually holds is the one above, and it is the one we check.)

What we do keep instead

One metadata row per attempt on an account, and one for a request we turn away before reaching any account, tied to your account. This table is the authoritative list of what a request leaves behind — all nineteen columns of request_events in packages/db/src/schema.ts. Section 11 of the Terms points here rather than restate it, because a second, shorter list in another document is how a wrong one survives.

RecordedWhat it is
idthe row's own identifier
tenant_idyour megaloop account — every read of the table is scoped to it
created_atwhen the request finished
account_idwhich of your linked accounts served it
api_key_idwhich of your own API keys made the call, so you can tell your own apps apart
pool_idwhich pool the key was limited to, if any — empty when it could use every account
request_idwhich of your requests this attempt belonged to — one request that tried several accounts writes a row each, and this is what makes them one request again
providerwhich provider that account belongs to
modelthe model name you asked for
paththe endpoint path, e.g. /v1/messages
status_codethe HTTP status the provider returned
response_classwhether it served, rotated, paused, failed, or was refused before reaching an account
upstream_reasonwhen a request was refused, the provider's own one-line reason for refusing, truncated — never your request or its content
latency_mshow long until the response started — not the whole request, which it cannot be for a streamed reply
first_token_mshow long until the first generated token arrived, on a streamed response
completed_mshow long the whole request took, once the response has finished
overhead_mshow much of that was us rather than the provider
input_tokensprompt tokens the provider reported, apart from the two cache figures
output_tokensthe tokens it generated
cache_read_tokensprompt tokens it served from its own cache
cache_write_tokensprompt tokens it wrote into that cache
resolved_modelthe model it says it actually served — left unfilled on this path
client_ipthe address the request came from, as Cloudflare reported it to us. Never taken from a header your client can set
user_agentthe user-agent your client sent, truncated. The only other header we keep

There is no column in that table for a request body or a response body. The bodies live in one separate table, encrypted, and only when you have switched storage on — see Off unless you turn it on.

The last two rows above are the only headers we keep, and they were added on 2026-08-19. We take the address from Cloudflare's own reading of the connection, never from a X-Forwarded-For or similar header, because a header your client sets is a value your client chooses. Both are kept for ninety days and deleted with the rest of the row. They are used to tell one machine's traffic from another's when something goes wrong, and for nothing else: no profile is built from them, and they are not shared.

The four token columns are the provider's own figures about its own response — how much was sent and generated, nothing about what any of it said. They are kept to show you what the same traffic would have cost at that provider's list price. A count the provider did not report stays null rather than becoming a zero, so a total is never inflated by a figure nobody measured.

Where your prompt does go

To the provider whose account served it: api.anthropic.com, the Codex backend at chatgpt.com, or your own self-hosted endpoint. Those providers receive the full prompt and produce the full completion, and what they retain is governed by their policy, not ours. Your request also passes through Cloudflare on the way in — see Third parties.

What we collect, and why

CategoryWhat is storedWhy
Your accountYour email address; your account's name, set to that address at signup; your theme preferenceYour login. There is no password column in this system, in any table
Signing in, and changing your addressYour address on each code request, or the address you are moving to — mailed before it is yours, on a row you may never complete; a keyed hash of the six-digit code — HMAC-SHA256 with a server-side secret, never bare and never the code itself; attempt count and used flagSending a code and checking the one you type. A code lasts 10 minutes and allows 5 guesses
Your browser sessionA hash of the session token, your browser's user-agent, expiry and revocation timestampsChecking a session without being able to reproduce your token, and letting you recognise one before revoking it
Your acceptance of these documentsThe version accepted, a sha-256 of the text of the documents it covers, which ones those were, the date, your user-agentA record of what you agreed to and what was disclosed to you. Append-only
Your API keysA hash of each key, its visible prefix, the name you gave it, last useAuthenticating your requests. A database read yields no usable key
Your linked provider accountsThe name you gave it, provider and link mode, a base URL for a self-hosted endpoint, access and refresh tokens as ciphertext only, health state, the provider's overage verdictMaking the request on your behalf, and routing around an account that is paused or failing
Your subscription headroomThe window label the provider minted (5h, 7d), the fraction used, the reset time, when we saw it — from response headers onlyAnswering which account has room. A snapshot, not a history
Your settingsRouting strategy and weights; a notification switch, a threshold, five per-event togglesRunning the pool the way you asked
BillingThe customer and subscription id our payment provider gives us, status, price id, renewal date, plan tier, trial endCharging for a subscription. Card details never reach us — checkout is on the payment provider's own pages
Email delivery recordsWhich alert, which account, whenSo the same alert is not sent twice. With notifications off, nothing is recorded
Security audit trailCode requested, failed code, rate-limited request, account created, session created or revoked, address change requested, completed or refused, account linked, unlinked or resumed, account deleted, and other security-relevant events. Several carry an email address. The code-request and account-creation rows hold the raw email address, there being no account to reference yetMaking abuse of the sign-in path countable
Support messagesThe name, address and message you type into the contact form, and whether it is answeredAnswering you. The form is public, so the row is tied to no account. It is emailed to us, acknowledged to you, and readable in full on our internal console
Your requests and responsesThe body you sent and the body you received, off unless you switch it on; with it on, encrypted for seven days, then deleted. Never a header, never in a logDiagnosing a failure from what was actually sent, when you have asked us to keep it — see Off unless you turn it on
Where a request came fromThe IP address the connection arrived from, as our CDN reported it, and your client's user-agent, truncated. On the same metadata row, deleted with it at ninety days. Added 2026-08-19Telling one machine's traffic from another's when something is wrong. A client looping on a misconfiguration is otherwise indistinguishable from your application working normally

What we never collect: passwords, card numbers or any payment instrument data, any header sent on an inference request other than the two named above, and analytics, behavioural tracking, session recording, device fingerprinting or advertising identifiers. There is no such software development kit in this product and no third-party script on any page, so no third party collects anything about you across sites through megaloop.

The legal basis for each of these

ProcessingBasis
Your account, signing in, routing and serving requests, billingArticle 6(1)(b) — performance of the contract you entered
Audit rows, rate limits, and the abuse bounds on sign-in and the contact formArticle 6(1)(f) — our interest in keeping the service, and the accounts you linked to it, from being abused
Usage alertsArticle 6(1)(b) — a feature of the service, switchable at any time
Answering a support messageArticle 6(1)(b), or 6(1)(f) where you are not a customer
The record of what you acceptedArticle 6(1)(f) — being able to show what was agreed, and when

Nothing here rests on consent, so there is no consent to withdraw. Two things above did not come from you: your headroom readings come from your provider — carried on the responses to your own requests where the provider publishes them that way, and otherwise fetched by the background job described above — and your subscription status from our payment provider. Both are named where they appear.

Your provider credentials, and how they are encrypted

  • AES-256-GCM, applied before anything is written. No plaintext column exists — the only columns hold ciphertext, so there is nothing to read in the clear even with full database access.
  • Each ciphertext is bound to your account and to its own row. A credential copied into another customer's row fails to decrypt rather than quietly working.
  • A provider credential is decrypted by exactly three callers in production. Two are on the serving path: forwarding your request, and refreshing an expiring token. The third is the background job that asks a provider how much of your subscription is left, for providers that publish that figure only when asked rather than on every response; it runs on a timer, roughly every five minutes per linked account, and it sends nothing of yours. No management endpoint, no dashboard page and no API response decrypts one — the record type used for listing accounts does not carry the ciphertext at all.

The limit: anyone who can read the service's environment can decrypt stored credentials. There is one key for all customers, held in that environment — no hardware security module, no per-customer key, no split-knowledge scheme. That is the honest state of key custody today, and our disclosure page says the same.

Third parties

The AI providers you linked

They receive your full prompt and produce your full completion. They also receive an OAuth bearer token or key for your own account with them; most of the headers your client sent, plus headers megaloop sets and minus the ones it removes; and a stable pseudonymous identifier per linked account — a session id and a device id derived from an HMAC of your tenant id and account id, keyed with a server-side secret, so each of your accounts looks like one consistent client rather than a stream of strangers. They cannot be reversed to the key.

What a provider retains is their policy, not ours. Read theirs. This is the largest disclosure in this document and it is inherent to what megaloop is.

What megaloop changes about your request

Forwarding is not byte-for-byte. This is done on your behalf and to your account, so you should know exactly what it is before you agree to any of it.

Removed: your megaloop credential, replaced by your own provider token; forwarding and caller headers (x-forwarded-*, x-caller-id), so a provider does not learn your network path from us; and the hop-by-hop and encoding headers that would otherwise corrupt a proxied request.

Added or replaced, including things you did not send:

  • A session id, always. The account-derived session id is set, not filled in: if your client sent its own, ours replaces it. A fresh per-request id is added as well.
  • A pseudonymous user id in the request body, only if you sent none. Unlike the header, this one defers to your client — a body already carrying a user identifier is left untouched.
  • A synthesised client identity, when your client presents none. The provider APIs expect the platform block a first-party client sends; when your request carries none, megaloop supplies a complete one — platform headers, a direct-access flag, and, only if you sent no User-Agent, a command-line user-agent. On the Anthropic path a client presenting its own block keeps both it and your user-agent.
  • A fixed first line on your system prompt, on the Anthropic path. megaloop prepends one sentence to the system field: You are Claude Code, Anthropic's official CLI for Claude. Your own system prompt is kept and follows it, unchanged and in full — nothing deleted, edited, reordered, or moved into the message list, and a block array keeps its blocks and their cache settings behind one new block. If your client already sends that line first, nothing is added; if you sent no system field, megaloop creates one containing only that sentence. The upstream refuses premium-model requests on a subscription credential whose system prompt does not begin with that exact line. The code is packages/providers/src/anthropic/body-marker.ts.
  • A replaced client identity on the Codex path, unconditionally. megaloop drops your client's user-agent, originator and version headers and sets the Codex command-line tool's own values in their place: originator codex_cli_rs, and a codex_cli_rs/<version> user-agent carrying the same version as the version header. This happens on every Codex request, sent or not, because the backend gates which models an account may reach on the client version it is told. The code is packages/providers/src/codex/forward.ts.

Assume your provider treats the last two as outside what it permits. Both exist because the upstream checks for a first-party client and refuses or downgrades a request that does not look like one, and both make your request look like one. megaloop does not represent that either provider allows this, and it cannot indemnify you if they do not — the account and the subscription the request lands on are yours. Section 3 of the Terms (/terms) says the same, as something you promise us about the accounts you link; section 5 is the acceptable-use half of it.

Everyone else in the path

WhoWhat they receive
Cloudflare — delivery and tunnelmegaloop.dev is fronted by a Cloudflare Tunnel, which terminates TLS, and the inference endpoints route through it. Cloudflare sits between you and our gateway for every prompt and completion, and sees them in plaintext at their edge while the request is in flight. We strip Cloudflare's own headers before forwarding upstream, which stops a provider learning your network path; it does not take Cloudflare out of the path
Cloudflare R2 — backupsEncrypted database backups, in Cloudflare's Eastern North America region on the unrestricted jurisdiction. Encrypted client-side with AES-256 on top of the AES-256-GCM already applied to every credential, so credentials are double-encrypted in backup
Resend — emailThe live six-digit sign-in code; usage alerts, containing your own account names, utilisation percentages, window labels and reset times; and support messages, both our copy and your acknowledgement
Stripe — paymentsOur internal account id as metadata, and the price id. We do not send your email address to Stripe. Card data never touches megaloop
Microsoft Azure — hostingThe machines and the disk the database sits on. See Where your data lives

That is the whole list: no analytics vendor, no error-reporting service, no performance monitor, no tracing service, no customer data platform, no advertising network. Checked against the source — the dashboard makes no request to any external host.

Retention

We do not have a retention policy yet. Three tables are pruned on a schedule; the rest are not.

DataRetention today
Email delivery records90 days by default, pruned automatically
Request metadata rows90 days, deleted automatically by a background job that runs every few minutes. Rows older than that are removed permanently, not archived
Your requests and responses7 days, deleted by the same job on the same five-minute schedule. Removed permanently, not archived. This is the shortest window in this table and the one we hold ourselves to most tightly. Switch it off in Settings → Privacy and nothing further is written at all
Security audit rowsKept indefinitely, and not removed when an account is deleted
Sign-in code rows24 hours. The row is deleted outright, address and all, the next time a code is issued — not merely marked used. Rows from an address change are tied to your account and go when it does
Support messagesKept indefinitely, and tied to no account. Nothing in the service deletes one
Your acceptance recordsNever edited. Removed with the account
SessionsExpire after 30 days, revoked when you sign out. Marked revoked, not deleted
API keysRevoked, never deleted, so an audit can account for every key that existed. The row keeps a one-way hash and the visible prefix. While a key is live it also keeps the key itself, encrypted, so you can copy it again from its row — readable only by someone signed in to your account, never by an API key, and every read is written to your audit log. Revoking destroys that copy. Keys minted before 27 August 2026 never had one
In-flight account-link recordsSingle-use, 10-minute expiry. Expired rows are not swept; they accumulate
Subscription headroom snapshotsOverwritten by each reading; deleted when you unlink the account
Linked provider accountsHard-deleted the moment you unlink, ciphertext included
Encrypted backupsUp to 14 days, kept by our own expiry pass rather than by a rule the storage provider enforces

Three of those hold your details and mostly do not cascade when an account is deleted, because they are not tied to one: audit rows and sign-in code rows for a login are written before we know who you are, and a support message can come from someone with no account. The exception is a code issued to change your address — that one names your account and goes with it. Removing any of them is a manual step — see Deleting your account.

Your rights, and how to exercise them

Which statutory rights you have depends on where you live; AI PWRD Inc. is established in Delaware, United States, with no establishment in the EU or the UK. Where the law gives them to you, you have rights of access, rectification, erasure, restriction of processing, data portability, and objection to processing, all exercised by writing to support@megaloop.dev. What you can do without asking:

See what we hold

Signed in, the dashboard and the management API return your identity and settings, your linked accounts and their health, your headroom readings, your usage totals and the individual request metadata rows, and your API keys by name and prefix. There is no one-click export file today — email support@megaloop.dev and we will assemble one.

Correct something

Account and key names, routing and notification settings, and your theme preference are editable in the dashboard. Your email address is too, in Settings: we send a code to the new address to prove you can read it.

Changing it moves your login and your sign-in identity, and no further. Copies of the old address stay on your account's display name, on sign-in code rows already issued, and in the security audit trail. Ask us if you want those removed too.

Delete specific things yourself

  • Unlink an account — a real delete: the row and both ciphertext columns go. Revoking megaloop's access at the provider is a separate thing you do on their site.
  • Revoke an API key — stops authenticating on the management API at once. On the inference gateway it can still be accepted for up to 60 seconds, because the gateway caches a resolved identity per key rather than reading the database on every request. The row is kept for audit; only a one-way hash and the prefix are left in it: revoking destroys the encrypted copy that let you copy the key again.
  • Sign out — the session is revoked server-side.
  • Switch off notifications — the global switch silences every alert, checked before anything is recorded.

Unlinking does not erase the request-metadata rows for requests that account already served. Those outlive it deliberately, so the history of what ran stays readable to you.

Deleting your account

You can do this yourself, immediately — Settings → Account → Close account, or POST /v1/tenant/delete with the address you sign in with as confirmation. Any live subscription is cancelled first. Email support@megaloop.dev if you would rather a human did it.

  • What goes: your account and user records, sessions, API keys, linked provider accounts and their credentials, headroom snapshots, routing and notification settings, request metadata, email delivery records, and acceptance records. All cascade from the account row.
  • What does not go, unless separately removed by hand: security audit rows, sign-in code rows, and any support message you sent. The first two carry your email address; the third carries your name, your address, and what you wrote. That removal is a manual database step, not a button, and we would rather say so than imply one exists.

We complete a deletion request within 30 days of confirming it is really you. A deletion does not reach the backups, and it cannot — your rows stay in the encrypted backup set until that copy ages out, up to 14 days later. Restoring a backup to edit it is a larger risk to every other customer's data than waiting fourteen days out.

Object to email

Sign-in codes are not optional — they are how you log in. Every usage alert is controlled by the global switch and the five per-event toggles beside it. We send no marketing email.

What we do not do

  • We do not sell or share personal information, and have not in the preceding twelve months. There is nothing to opt out of.
  • No automated decision-making here produces legal or similarly significant effects, and we do not profile. Choosing which of your own accounts serves a request is routing, not a decision about you.
  • Exercising a right costs you nothing — no different price, no different service.

Complain, or appeal a refusal

If we refuse a request, reply to the refusal and a person reconsiders it.

If you think we have handled your data badly, email support@megaloop.dev first — one person reads it and it will be faster. You are not obliged to come to us first, and nothing here asks you to waive that. We have no establishment in the EU or the UK, so there is no lead supervisory authority for us, which does not close the route to your own regulator. In the EU, the data protection authority of the country you live in, work in, or where you think the problem happened. In the UK, the Information Commissioner's Office. In the United States, your state attorney general takes consumer privacy complaints, and several states give you a direct route under their own statute.

Where your data lives

  • Region: Microsoft Azure, eastus2 (United States).
  • Database: PostgreSQL on a separate machine, reachable only from the application machine's private address.
  • Encryption at rest: every disk is encrypted by Azure with a platform-managed key. That protects a disk which leaves the datacentre, not a process that can read the running machine; what protects your credentials from anyone who reaches the database is the AES-256-GCM applied above it.
  • Backups: encrypted, in Cloudflare R2, up to 14 days, with a restore path tested end to end.

If you are in the EU or UK, read this rather than skim it. Your data is stored and processed in the United States — the one qualification being the backup copy, in a Cloudflare region spanning the eastern United States and eastern Canada, which is all Cloudflare tells us. The AI provider you linked may then process your prompts somewhere else again.

We operate no standard contractual clauses, we have not certified to any transfer framework, and we have no binding corporate rules — so if you are looking here for the name of a safeguard, there is not one to name. What there is instead: a US service, in a US region, that you send data to directly.

Security

  • Nothing that authenticates a caller is stored in the clear. Sign-in codes, session tokens and API keys are held as hashes; code hashes are keyed with a server-side secret, so they are not brute-forceable from the database alone, and both issuance and guessing are rate-limited.
  • Customer isolation is structural, not a coding convention. Every database method requires an account identifier and will not compile without one, and that identifier is always read from the stored key or session row — never from a header, query parameter or body field the client controls.
  • No port on either machine is reachable from the public internet. Traffic arrives through an outbound-only tunnel rather than an open listener, and the gateway binds to loopback.

What our own staff can see. One internal console reads across all customers, and it is the only thing in the product that does. It returns aggregates — counts, timestamps and percentiles — plus two identifying lists: the support queue in full, including the name, address and message on every ticket, because that is what lets a person answer you; and a directory of up to 200 accounts, each row carrying the sign-in address, account name, plan, trial end, signup date and how many provider accounts are linked. It reaches no prompt, no completion, no credential, no API key, and no individual account's usage figures. Access is a list of addresses in the server's configuration, not a permission an account could be granted, and every view is logged before the read happens. Separately: an administrator with shell access to the application machine can read the encryption key, and therefore decrypt stored credentials.

No third-party audit. None of this has been reviewed by anyone outside the project. It is a description of the code, offered so you can check it rather than trust it. Our disclosure page names the source file behind each claim.

Cookies, browser storage, and Do Not Track

megaloop sets no advertising, analytics, or tracking cookies of any kind. There are two cookies and one local-storage key, and this is all of them.

NameTypeWhat it is forLifetime
gw_sessionCookie — HttpOnly, Secure, SameSite=LaxYour signed-in session. Holds the session token; HttpOnly means no script on the page can read it30 days, or until you sign out
ml_gateCookie — HttpOnly, Secure, SameSite=LaxPre-launch only, while the site sits behind a password gate: it stops your browser re-prompting on every tab. It holds an expiry timestamp and a signature over it — no personal data — and goes with the gate at launch30 days
ml-themeBrowser local storageYour light/dark choice, so the page does not flash the wrong colours as it loads. Signed in, the same choice is stored on your accountUntil you clear it

The session token is never placed in local storage; it is held server-side and handed to the browser only as the HttpOnly cookie above.

There is no cookie banner, and that is a conclusion rather than an omission. The two cookies are strictly necessary, and ml-theme holds one word, set because you asked for it. None of the three tracks you across sites, profiles you, or feeds an advertiser, so a banner would have nothing to ask about.

Do Not Track. megaloop does not read the DNT header or any other cross-site opt-out signal — no code in the service looks at one. It also does not track you across sites or over time, and no third party collects personal information about you through megaloop, so there is nothing such a signal would switch off.

Children

megaloop is a developer tool sold on a paid subscription, not directed at children and not intended for anyone under 18 — the same floor section 4 of the Terms (/terms) sets for holding an account. We do not knowingly collect personal data from anyone under that age. If you believe a child has given us personal data, email support@megaloop.dev and we will delete the account.

Changes to this policy

This policy describes the behaviour of a specific version of the software; when the code changes, the policy changes with it.

  • For a material change — a new category of data, a new third party receiving your data, a change to the prompt-and-completion answer above — we email you at your account address before it takes effect, and update the date at the top.
  • For a correction or clarification, we update the date at the top.

Old versions are recoverable from the repository history.

Contact

support@megaloop.dev

AI PWRD Inc., a Delaware corporation.

For the technical, file-by-file version of these disclosures, see the "What we store" page at /trust. It names the source file behind each claim so you can check it.

Back to megaloopTermsWhat we store