Privacy

The short version: Heimdall3D connects to the internet only when you press Send, when a script asks for a library model, or when you have turned crash reports on, and nothing about you is sold or shared. This site is hosted by two companies, Hetzner and OVH, and a payment goes to Paddle; each is named below with what it sees. The site counts its own page views without storing your address. Page views need no script; views of a model, a picture or a forum thread are counted by one small script from this site. Reading these pages sets no cookie. Cookies are set when you sign in, to the forum or to the admin area, when you recover a forum account, and when you work in an organisation's account. The personal data here is what you typed in yourself. That is an email address, given to buy, to be told about a release, to join the forum, or to ask for a quote on the tours page. A reply to a report goes to the forum account's address. For a forum member it is also the handle you chose, a display name if you gave one, a password hash if you set a password, and a record of each passkey you register. Only the handle is shown to anyone. Several records hold the address your computer connects from: a download of the build, a sign-in, a failed sign-in, the web server's log, and the storage provider's log when you view a large capture. All are described below.

The plugin

Heimdall3D connects to the internet in exactly three cases. Each one starts only from something you do or chose. Nothing connects in the background, on opening a file, or on a timer. It does not check in, does not look for updates and does not report what you opened.

Every connection goes to heimdall3d.com over HTTPS and identifies itself as "Heimdall3D". The site sees the IP address the request comes from, as with any web request.

Windows' own networking library, WinHTTP, is not in the plugin DLL's import table. The plugin loads it only at the moment one of the three cases above happens. The DLL's import table lists GDI32, KERNEL32, USER32, SHELL32 and two parts of Windows' core, NTDLL and a synchronisation API set, and it loads BCRYPT, Windows' cryptography library, when it is first needed. Anyone can check the import table with a dependency viewer.

Your licence key is checked on your own machine against a key embedded in the plugin. No activation, no machine fingerprint, no account. Apart from the three cases above, nothing about the files you browse leaves your computer.

This page was corrected on 7 October 2026. Earlier versions of it said the plugin makes no network connections at all. That stopped being true in 1.1.0, when Send was added.

A crash report is sent only if you turned crash reports on. It contains the Heimdall3D version, the name of the program it ran in (such as dopus.exe or explorer.exe), the Windows version, the graphics card and its driver version, the module and the offset where the fault happened, the call stack as module names and offsets, and the extension and size in bytes of the file being previewed. It never contains a file name, a path or a memory image. It is posted once and deleted from the machine before it is sent.

Separately, whether or not reports are on, a crash makes the plugin write one short text file on your own machine. It holds the fault, the call stack, the name and size of the file being previewed and how far the preview had got. It goes to %LOCALAPPDATA%\Heimdall3D\crash, or to the LocalLow folder of the same name when the Windows preview pane is the host. The newest five are kept and older ones are deleted. That file is never sent, and you can delete the folder at any time. A full memory image of the process is written only if you set HEIMDALL_CRASH_DUMP=1, and it also stays on your machine.

This website

Reading these pages sets no cookie. This site can set seven, and each is set by one thing you do. Signing in to the forum sets heimdall_member. It holds a session token and nothing else, and it goes with every request to this site, because every forum page has to know who is reading it. It lasts at most 90 days from the sign-in, however often you visit, and then you sign in again. Signing in to the admin area sets heimdall_admin, which also holds a session token and nothing else. Its path is /admin, so your browser does not send it with a request for a public page. Following the link in a forum account recovery mail sets heimdall_recover, a session token for the page on which you register a new passkey; its path is /account and it is sent nowhere else. A passkey ceremony, which is a sign-in or the adding of a passkey, sets heimdall_ceremony when it starts and clears it when it finishes, and that one is also sent only under /account. A passkey sign-in to the admin area does the same with heimdall_admin_ceremony, which is sent only under /admin and cleared when the sign-in finishes.

A member who works for an organisation in Exhibitions, such as a museum, can switch between their own account and the organisation's. Switching to an organisation, making one, or accepting an invitation to one sets h3d_act. It holds the number of the organisation's account and nothing else, so the pages know which one you are working in. It lasts a year, and switching back to your own account clears it.

The seventh is described under Counting visits below. It is set only in the admin area, only by me, and its only effect is to leave a browser out of the count.

No analytics service, no tracking pixels, no fonts from anywhere else. Nothing on this site reports to anyone else about you, and the counting described below is done by this server alone. The site's own content-security policy names every place a page may load from, so this is enforced by your browser rather than left to good behaviour. Most pages load nothing from anywhere but this server. There are two exceptions.

The first is payment. The buy page and the storage page of a member's account load Paddle's checkout script. That is described under When you buy below. They are the only pages that load a script from anyone else.

The second is storage. Files that members and organisations upload, such as 3D models, scans, pictures and sounds, are kept with OVH, described below. An upload page sends the file from your browser straight to that storage. A large 3D capture may be read by your browser straight from that storage too, as described under Exhibits on this and other sites.

Besides the page view record described below, the site software writes only a log. It writes startup messages, errors, and a few lines saying what it did: that a report was stored, how long it was and which country it came from, that a download was asked for under a filename this build does not publish, that a sign-in used a recovery code or a code that was already spent, how many expired sessions were deleted, that a request for a quote was stored with its spam score and country. No line carries an email address, an IP address, or the text of a report.

The site runs on a server in Nuremberg, Germany, rented from Hetzner. No content delivery network sits in front of it and no request is routed through a third party. Hetzner is my processor for the hosting itself and does not read the data.

Files are kept in object storage rented from OVH, in its region in Germany. That holds the files members and organisations upload, the storage's own access log described under Exhibits on this and other sites, and the database backups. OVH is my second processor. Like Hetzner, it stores the data and does not read it.

The database is backed up once a day. Each backup is encrypted with AES-256 on the server before it is copied to OVH, and the key is not kept with it. Backups are kept for 14 days on the server and for 90 days at OVH, and then deleted. So something deleted from the site can still exist, encrypted, in a backup for up to 90 days. Backups are used only to restore the site after a failure.

The web server in front of the site writes one ordinary log line per request: your IP address, the time, the page or file requested, the response status, the address of the page that linked to it, and the browser's user agent string. That is what any web server writes. No figure on this site is taken from it: page views are counted as described above and downloads as described below, both by the site software itself. Those lines stay on that machine, are not joined to anything else, and are not sold or shared.

Those lines are kept for no more than 15 days: the server starts a new log each day, compresses the old ones, and deletes each day's log 14 days after it was closed.

On the machine itself, the operating system records service start and stop events, as any Linux system does. Nothing there identifies a visitor.

Counting visits

This site counts its own page views, so that I know how many people read it. Nothing on the page does this count: there is no script, no pixel and no third party for it. The count is made by the site software while it answers the request, and it is not sent to anybody. Views of a model, a picture or a forum thread are counted separately, by one small script from this site, and that is described under Counting views below.

One row is written per page request. It holds the time, the page that was asked for, the status the server answered with, the host of the site you followed a link from if you followed one, the country your address is in, and one identifier. The page is recorded without anything after the question mark. The referring site is recorded as a host and never as a full address, because a full one can carry a search you typed or the title of a private page. The country is looked up on this server against a database held here, so no lookup goes anywhere. Files a page pulls in, such as images and video, are not counted separately from the page that pulled them.

Your IP address is not stored, and neither is your browser string. What is stored instead is the identifier, and it is what makes the figure people rather than requests. It is a hash of your address and your browser string together with a random value generated fresh for each day and held only in this database. Your address cannot be read back out of it. That random value is deleted the day after the day it belongs to, so only the last two or three days of them are ever held here, depending on how long it is since the hourly sweep last ran. Once a day's value has gone there is nothing left with which to turn that day's identifiers back into an address, and nothing with which to tell that an identifier from that day and one from another day belong to the same person. So your visits on any day whose value has gone cannot be traced back to you, and cannot be linked to each other. Today's value has to exist in order to count today, which is why this says older days rather than every day.

Each row is filed as one of four kinds, and it is worth knowing why, because most requests to this site are not people. A row is a person; or me; or a client that says it is not a person, which covers search engine crawlers, command line tools, monitors and the services that fetch a page because somebody pasted the link into a chat; or a request for a page this site does not have, which is what probing for somebody else's software looks like. On the traffic this site actually receives, the last of those is most of it. All four kinds are kept and all four are shown to me, because a figure that quietly threw traffic away would be a figure nobody could check.

My own visits are the second kind and they are left out of the first. Signing in to the admin area is enough on its own, and when I do, the identifier my browser produced that day is marked as mine so that the visits I make signed out that day are left out too. That mark is a hash of the same sort, it means nothing once the day's random value is gone, and it is kept and deleted on the same schedule as everything else here.

That leaves the seventh cookie. It is named heimdall_not_counted, it holds the single word excluded and no identity of any kind, its only effect is to keep the browser holding it out of the first figure, and it lasts a year. It can only be set from inside the admin area, so reading this site will never give it to you. It is named here because it is a cookie this software is able to set, not because it can reach you.

These rows are kept for 400 days and are then deleted. That is a year, so that a month can be compared with the same month a year before, and a margin on top of it. The random values are not kept anything like that long, as above: a row spends all but its first two days with nothing in this database that could reverse it.

Counting views

A page that shows a 3D model, a picture on its own page, or a forum thread also counts how many people viewed it. This one does use a script: a small one, served from this site, and it talks to this server and nobody else. The page carries a signed token naming what it shows. The script sends that token back once: when the model has drawn after you pressed play, when the picture has loaded and the page is on screen, or when the thread has been on screen for a few seconds or you touched the page. A browser that runs no script is not counted, and neither is a request that says it is a crawler.

The server then writes one mark: what was viewed, the day, and the same daily identifier described above, made from your address, your browser string and that day's random value. The mark exists only so that one person counts once a day, however often they reload. Marks are kept for 2 days and then deleted by the hourly sweep, so a mark lives two to three days. What stays is a number: how many times each thing was viewed, and for a piece in a portfolio, how many times on each day. Nothing in that number says who.

If you are signed in, the server checks who you are only so that the owner of a piece, or the author of a thread, is not counted viewing their own. That is not stored.

Exhibits on this and other sites

Museums, archives and other organisations show 3D exhibits from this site, here and on their own web pages. If you view one on their page, your browser loads it from this site. Viewing an exhibit sets no cookie. Its view is counted as described under Counting views, and the request for it is one row in the visit count described under Counting visits, where the host of the site it was shown on is the referring site.

When an exhibit opens inside another site's page, your browser tells this server the address of that page. Only its scheme and host are kept, for example https://museum.example, and one is added to a count for that exhibit and that day. The first such site, and when it was seen, is also noted on the exhibit. That tells the exhibit's owner where it is being shown. It holds nothing about you, and it is kept until the exhibit is deleted.

Some exhibits are large 3D captures. Your browser may read those in pieces straight from the storage at OVH, on a link that names the exhibit and stops working after 20 minutes. This is switched on or off on the server, and it is on today; when it is off, the capture comes through this site instead. OVH writes a log line for each read: your IP address, the time, what was read, the status, how many bytes were sent, the address of the page that asked, and the browser string. Every five minutes this site reads the new lines, adds up the bytes sent for each exhibit and day, keeps only those totals, and deletes the lines. The log is kept in a store of its own that deletes anything still there after 60 days. The name of each log file read is kept for 30 days, so that no file is counted twice; the name says nothing about you.

What is kept in your browser

Some pages keep a little in your browser's own storage for this site. None of it is a cookie, none of it is sent to this server, and none of it says who you are. You can clear it at any time in your browser's settings for this site.

The 3D viewer remembers a setting after you change it, so it is the same next time: invert look, head motion, the walking ring, the frame meter, the map's sun, clouds and life, the minimap's step, an exhibit's captions, markers and sound, and whether a point cloud shows its points, its surface or both.

If a large capture runs your graphics card out of memory, the viewer notes a smaller budget for the rest of that tab's life, so a reload does not fail the same way. That note is gone when the tab closes.

If a model has to be converted in your browser before it can be shown, the result may be kept so the next visit does not convert it again. Only conversions that took a noticeable time are kept, none over 64 MB, and the oldest go once they pass 256 MB in all. They hold the model and nothing about you.

On the upload pages, an upload that stops part way is remembered so it can be continued: its number on this site, and the file's name, size and when it was last changed. Where your browser allows it, it also keeps a handle to the file, so continuing asks only for permission to read it again.

Portfolios and organisations

A member can keep a portfolio here: 3D models, scans, pictures, posters, sounds, the collections and exhibits made from them, and earlier versions of an exhibit. Who sees a piece is set by its owner.

A portfolio also holds what its owner writes about themselves for its column: their shop, Patreon, own site and the platforms they post on, what they offer, where they are based, since when and what they work in, and their theme with its banner and portrait pictures. All of it is shown on their portfolio and goes with it. The pictures are kept exactly as sent, including any location a photo carries.

An organisation, such as a museum, has an account of its own with the same, and a brand logo shown in the corner of its exhibits. It also holds who belongs to it and in which role, the invitations it has sent (the address invited, the role, who invited, when, and whether it was used), and a log of what was changed in it, by whom and when.

Deleting a member account deletes that member's portfolio and the files only it held. An organisation is deleted on request, by the site's administrator, who deletes it with all its content: its pieces and their files, its collections, brand and logo, invitations, keys and links. Its members keep their own accounts and lose only their membership. To ask, write to quark@heimdall3d.com. Backups are kept as described under This website.

When you download the build

Asking for a build writes a row, and this record is not like the page view record above: it keeps your IP address rather than a hash of it. One row per request. It holds which file and which version was asked for, the time, the status the server answered with, how many bytes actually reached you and whether the transfer finished, whether it was a resumed or partial request, your IP address, the country that address is in, your browser string, the address you came from if you came from one, and the language preference your browser sends.

It is kept in that detail because a download figure means nothing without it. Most requests for a large file are not somebody taking the build: they are crawlers, transfers that stopped part way, and clients asking for the first few bytes to see what is there. Telling those apart from a real download needs a record of what happened to each one. The same details are mailed to me when a build goes out, which is how I see that the machinery is working.

These rows are kept for 90 days and are then deleted, the address with them. That is the whole of it: the record is not joined to a purchase, to an email address, or to the page view record above, and it is not sold or shared.

When you buy

The payment is handled by a reseller acting as merchant of record. Card details go to them and never reach this server or me. I could not see them if I wanted to.

The buy page loads one script from cdn.paddle.com, which is the reseller's own. Opening that page fetches it, so Paddle's servers see the request: your IP address, the time, and the browser string, the same three things any server sees. The only other page that loads it is the storage page of a member's account, where a storage plan for a portfolio is bought the same way. The script is not on the pages you read before deciding to buy.

For a storage plan, what I keep is Paddle's references for the plan and the customer, which account it belongs to, its size and term, its state and dates, and for each payment the same figures as for a sale below: the currency, the amounts, the tax, Paddle's fee and any refund.

That script tries to load a second one, an analytics library at public.profitwell.com. This site's content-security policy names Paddle's own domain and nothing else, so the browser refuses that request and it is never fetched. The claim above that nothing on this site reports to an analytics service holds on the buy page too.

Pressing the buy button opens Paddle's checkout in a frame over the page. Everything typed into it goes to Paddle and not to this server: your name, your address, your card number and your VAT ID if you give one. Their frame is theirs, and this site cannot read what is in it. What comes back to me is the outcome, described in the next paragraph.

What I receive is your email address and the order reference, and those exist for exactly two purposes: to issue your licence key, and to send it to you again if you lose it. Your address is also written inside the key itself, which is how the key stays personal to you and why a shared key is not anonymous.

That reseller is Paddle. They are a separate controller for the payment data, not my processor: they decide what they collect to take a card payment, to meet their own anti-fraud obligations, and to charge and remit the VAT in your country. Their policy governs that data, and this one cannot speak for it.

The order records I keep are your email address, the order reference, what was bought, the time the merchant billed it, and the time your key was sent. Beside those I keep the figures Paddle reports for the sale, so a year can be totalled without asking them for every transaction one at a time: the currency, the amount before tax, the tax, the total, Paddle's fee and what reaches my bank.

I also keep the country Paddle holds for you, your name as Paddle holds it, the language the checkout was taken in, and how it was paid: the method, and the card's network where there was a card. Never a card number and never an expiry date. Those are not sent to this server and are not asked for.

Last, I keep the site that referred you and the page you first landed on. That is taken from this site's own visit records and nothing is sent to Paddle for it. The referrer is the site's name only, never the full address of the page you came from, so a search you typed somewhere else does not reach me. No IP address is stored against an order.

Those are business records under German law, so they are kept for the statutory retention period set by § 147 AO and § 257 HGB. That period is longer than most people expect, and it is not mine to shorten: an invoice I am required to be able to produce is not something I may delete on request. Everything outside those records is deleted when it stops being useful.

When you send a report

A report is sent from your forum account and stores the email address of that account, so a stored report identifies the person who sent it. With each report I also store the description, the version of the plugin page, the country the request came from, a spam score, and how close the description is to the nearest spam already received. The country is looked up from the IP address when the report arrives; the IP address itself is not stored.

A language model on my own server, in my own code, turns the description into a list of 384 numbers that describe its meaning. The list is stored with the report and deleted with it. Its only use is to recognise messages that repeat spam already received, in any language. The text never leaves the server and no outside AI service is used.

The address is checked against a block list I keep of addresses that sent spam. A blocked address's report is filed as spam, and that is recorded as the report's state. The address is also checked against earlier reports from it that were filed as spam; if there is one, it adds a point to the stored spam score. Only a block files a member's report as spam; the score never does.

A reply goes to your account's email address. The address is never added to a mailing list. A report is deleted when the fault it describes is fixed or judged not to be a fault.

The release list

If you give your address to the release list, that address is stored so a confirmation request can be sent to it. Nothing is sent to an address that has not answered that request, which is the double opt-in that § 7 UWG requires. An address that never confirms is deleted rather than kept.

The list carries one message per release and nothing else. It is not shared and not sold. Every message carries an unsubscribe link, which opens a page with one button and needs no reply and no account. The address is kept after that, and kept for one purpose: so that it stays off the list. You can also ask to have it erased outright by mailing quark@heimdall3d.com.

When you ask for a quote

The tours page has a form for asking for a quote. What you send is stored: your name, your organisation if you gave one, your email address and your message. With it the server stores the time, the country your address is in, a spam score, and whether the request was filed as spam. The country is looked up on this server, as for page views; your IP address is not stored.

It is kept so I can answer you and prepare an offer. That is a step taken at your request before a contract, which is the legal basis for it under Art. 6(1)(b) GDPR. Unless it is filed as spam, a notice is mailed to the address the tours page shows. The notice carries no personal data: not your name, organisation, address or message, only that a request came in. The request itself is read in this site's admin area and deleted there after the periods below.

The request is checked for spam on this server: the address against the block list I keep, and the message for the usual signs of spam, such as links to messaging apps or a sales pitch. No outside service is asked. No notice is mailed for a request filed as spam, and it is deleted after 30 days. Every other request is deleted 24 months after it arrived. It is not shared and not sold.

When you email me

Support email lands in an ordinary mailbox and stays there until it is no longer useful. If you send a file so I can reproduce a bug, it is used for that and deleted afterwards.

Key recovery

The recovery page emails your key to the address that bought it, and never displays it. That is a privacy decision as much as a security one: a page that showed a key to whoever typed an address would let anyone find out what someone else had bought.

Accounts

There are two kinds of account here, and they do not hold the same things. One is a forum member's account. The other is my own admin account, and there is one of it.

A member account holds the email address, whether and when it was confirmed, the handle you chose, a display name if you gave one, the account's role, when it was made, and when it was deleted if it has been. A member can sign in with a password, a passkey, or both. A password is stored only as an Argon2id hash, from which the password cannot be recovered. The account also holds one opaque identifier: a random value that your browser presents during a passkey ceremony in place of the address, so the address itself is never what the ceremony is about. The handle is public. It is the name your posts appear under.

The admin account always holds a password hash, from which the password cannot be recovered, and one thing more: the secret behind its second sign-in factor. That secret is stored encrypted under a key that lives in the server's environment and never in the database, which is named here because it changes what a copy of this database would contain.

A passkey is a pair of keys made on your own device. What this server holds is the public half, together with an identifier for the credential, the algorithm it uses, a counter the device advances each time it signs, an identifier for the make of authenticator, a hint about how it connects, whether the device reports the passkey as backed up, a name you gave it if you gave one, and when it was added, last used and removed. The private half never leaves your device and this server never receives it. A public key can check a signature and cannot make one, so what is held here cannot be used to sign in as you.

Signing in records the address and the browser string the sign-in came from, so the account holder can see their own sessions and end one they do not recognise. That is the same row for both kinds of account. A session row is kept until it expires or you end it, whichever happens first, and the row is deleted within an hour of that.

Deleting a member account clears every column that names a person: the address, the display name, the handle, and the passkey identifier above. Your passkeys are deleted and your sessions are ended. The row itself stays, and so do your posts. They are shown as written by a former member, and every reply and quote that pointed at them still resolves, which is why the row is kept rather than removed. The handle is retired: it goes on a list of names that will not be issued again, dated to the day and holding no link back to the account, because posts under that name stay readable and a name quoted and linked for a year should not become somebody else. After that the account holds nothing that names you. Records kept for another reason, such as an order, are kept under the section that describes them.

A member whose confirmed address is the address on a purchase is shown a licence badge on the forum. The badge is not stored and it is not something you claim: it is a lookup, made when it is needed, joining the address on the account to the address on the order records described under When you buy. It is not a code anybody types. The plugin plays no part in it: your licence is checked on your own machine, and the plugin never asks this site anything.

Actions on an account are recorded in one trail: which account acted, what it did, when, and the address it acted from. For a member that includes confirming the address, each passkey sign-in, a recovery request, and the deletion itself. Deleting the account does not remove those lines; they keep the account's number, which after deletion identifies nobody. That record is kept rather than pruned, because it is itself a security control. None of this is passed on to anyone.

A failed sign-in to the admin area is recorded the same way, and that one can be about somebody with no account here. The record holds the email address typed into the form, the IP address it was sent from, the time, and a short reason the attempt failed. That reason says which step failed, so it records whether an account exists at that address. It is written whether or not one does, so typing an address into the sign-in form puts it in that record even if it has never been used here for anything else.

Those rows are kept indefinitely. An attempt to get into the admin area is the thing an audit trail exists for, and a trail that expires before the attempt it describes is found is not one. The admin area is not linked from any page and its form is not the one the forum asks you to sign in with, so a row here is either mine or somebody probing the form. A member's passkey sign-in writes a line to the trail when it succeeds and nothing when it does not.

A member's password sign-in writes a line to the trail either way. A failed one is recorded like a failed admin sign-in: the email address typed, the IP address it was sent from, the time, and a short reason. It is written whether or not an account exists at that address, and it is kept in the same trail, for the same reason.

Your rights

You can ask what I hold about you, ask for it to be corrected, or ask for it to be deleted, subject to the retention periods above. Email quark@heimdall3d.com. You also have the right to complain to a data protection supervisory authority.