Legal
Privacy Policy
tipeerQR stores as little as it can. This page lists what it keeps about accounts, links, scans and reports, who handles it, how long it stays, and how to delete it.
Effective
On this page
The short version
- We store your email address, your links and settings, and statistics about scans of your links. If you sign in with Google, we also store your name, your profile picture and your Google account ID.
- A scan records the device type, the country, region and city that Cloudflare reports, the referring site, UTM tags and a bot flag. Our database never stores IP addresses or full user agent strings.
- We show no ads, we do not sell personal data, and we set no analytics or advertising cookies.
- Vercel, Convex, Cloudflare, Google and Resend handle data for us. They process it outside Malaysia, including in the United States.
- We delete individual scans after 365 days. Deleting your account removes your links, scans and settings. We keep reports and the administrator log.
- To see, correct or delete your data, email support@tipeer.com.
Who we are
tipeerQR is a free service run from Malaysia by Tipeer. Tipeer decides what personal data tipeerQR collects and why, so under Malaysia's Personal Data Protection Act 2010 (PDPA) Tipeer is the data user. This policy describes the personal data we handle. It is written in English.
We do not publish a company name or a postal address. To reach us, email support@tipeer.com. That mailbox forwards to the person at Tipeer who handles privacy requests.
What we collect and why
What you must give us
You need an email address to make an account, and a password if you do not use Google. Without them you cannot have an account. Your display name, a Cloudflare connection, the email address on a report and domain status emails are optional. You can use the QR code generator and open any link without giving us anything. The sections below say where each kind of data comes from. Most of it comes from you. Your name and profile picture come from Google when you sign in with Google. The facts about a scan come from Cloudflare and the visitor's browser.
Your account
We store your email address and, if you sign in with Google, the name, the profile picture and the account ID that Google shares. The Google account ID is a stable identifier for your Google account, and we keep it until you delete your account. If you use a password, we store a hashed form of it and never the password itself. We also store your sign-in sessions, when you verified your email, your display name if you set one, your role, your choice about domain status emails and whether an administrator has disabled the account. We use this to sign you in and keep your account secure.
When you change your email address, we also keep the new address and a hash of the confirmation code until the change finishes, you cancel it or the code expires. A job that runs every 15 minutes then deletes expired requests, so an address you typed goes within about 30 minutes of the request.
We create an account record when you submit the sign-up form, before you enter the code we email. If you never enter the code, we still hold the address you typed, a hash of the password you chose and a hash of the last code. We delete such an unverified sign-up once 24 hours have passed since we last sent a code, and an hourly job does it, so it goes within about 25 hours. The job never deletes a verified account or a Google account.
Your links and settings
We store link slugs and private names, destination addresses, QR code styles and any logo you upload, and the apps you add for Open in app (team ID, bundle ID, package name, certificate fingerprints and any association file you paste). We store your domains and the records tipeerQR needs to check them. For each API key we store a label, a prefix and the time it was last used, plus a SHA-256 hash of the key and never the key itself. We use this to run the service you asked for.
Scans of your links
Each scan stores the time, the link, the device type (iPhone, iPad, Android, Huawei, Windows, a Mac or iPad that cannot be told apart, or other), which destination slot answered, the outcome, and the country, region and city that Cloudflare reports for the visit. It also stores the host name of the referring page, the utm_source, utm_medium and utm_campaign values if the link carried them, and whether the visit looked like a bot. We never store IP addresses or full user agent strings in our database. We use scans to show link owners their statistics.
If you only scan or open a link, you have no account with us, and this is everything tipeerQR records about the visit. The link owner sees counts and breakdowns, and can export the scan rows for their own links.
Your Cloudflare connection
Custom domains may not be open when you read this. This part applies from the day they open. If you connect Cloudflare, we store your Cloudflare account ID and name, the permissions you granted, and the access and refresh tokens Cloudflare gives us. We encrypt the tokens with AES-256-GCM. We use them only to list your zones and to create and delete the DNS records for your custom domain. If you add a domain by hand instead, we look up its DNS records over DNS-over-HTTPS to check that you own it.
Rate-limit keys
To limit sign-up and report abuse, our server computes a keyed hash (an HMAC) of the visitor's IP address and counts attempts against that hash. We do not store the IP address. The limit counts attempts in a fixed one-hour window. We delete the hash within about two hours of the last attempt: the window lasts one hour, and an hourly job then removes every record whose window has ended. Without our secret key the hash cannot be turned back into an IP address.
To limit how many sign-up and password reset codes we email, our server computes a keyed hash (an HMAC) of the email address and the purpose of the code, and counts requests against that hash. This covers any address typed into those forms, including one that never became an account. We do not store the address in this record, and without our secret key the hash cannot be turned back into one. The limit allows 3 codes per address in a fixed 15-minute window. We delete the hash within about 30 minutes of the first request: the window lasts 15 minutes, and a job that runs every 15 minutes then removes every record whose window has ended. Deleting your account does not change this, because the record holds no account data.
When you ask to change your account email, we count requests per new address the same way, with a keyed hash of the address and the purpose, and not the address itself. This covers an address that belongs to someone else or to no account at all. The limit allows 3 requests per new address in a fixed one-hour window. We delete the hash within about two hours of the first request, because the window lasts one hour and the same 15-minute job then removes every record whose window has ended.
Our sign-in library, Convex Auth, keeps its own record of failed attempts. A wrong emailed code is counted against the email address typed, even when no account uses that address, and a wrong password is counted against your internal account ID. The record that counts a wrong code holds the address in plain text, not as a hash. A job that runs every 15 minutes deletes each record once the last failed attempt is an hour old. Deleting your account removes the records that hold your address or your account ID at that moment.
Apart from that record, no limiter keeps an email address in plain text. The remaining limiters count requests per account for password checks, email-change requests, link edits and logo uploads, and per API key and per account for API requests, plus one site-wide counter for reports. Their records hold only your internal account ID or API key ID, or no identifier at all. They stay while your account exists. Deleting your account removes the ones that hold your account ID or the ID of one of your API keys. The site-wide counter holds no identifier.
Reports
When someone reports a link, we store the address they gave, the reason, any details, the optional email address they chose to share, and what the administrator decided. We use reports to enforce the Abuse Policy.
Administrator logs
When an administrator disables or enables a link, a domain or an account, or closes a report, we log who did it, when, and the reason. We use the log to show that enforcement was fair and to review mistakes.
Emails
We send email through Resend from notifications@theraw.com.my. The Raw (theraw.com.my) is a business related to Tipeer, and we use its verified sending domain. We send sign-up and password reset codes, change-email codes and a notice to your old address when the change completes, domain status emails, and emails that tell a waitlisted owner a domain spot is free. We also email report alerts to administrators. You can turn domain status emails off in Settings. We do not send marketing email.
Our providers' logs
The companies that carry web traffic for us, listed below, process IP addresses to deliver pages and keep their own security logs under their own policies.
How we use it
We use your data to run tipeerQR. That means signing you in, redirecting visitors, showing you stats for your links, connecting your domains, checking destinations for harm, reviewing reports and sending the emails listed above. We also use it to enforce the Abuse Policy, protect the service and meet legal duties. We do not use it for anything else.
We process your data because it is needed to give you the service you signed up for, because you chose to give it to us, or to protect the service and meet our legal duties. Where you choose, such as signing in with Google, connecting Cloudflare or adding an email to a report, you can change your mind. See your choices and rights.
We do not sell personal data, and we do not use it for advertising or profiling. You can read scan statistics only for your own links. Administrators see accounts, links and reports when they need them to handle abuse.
Who handles data for us
- Convex stores our database and runs our backend. It processes data in the United States.
- Vercel hosts the website and dashboard.
- Cloudflare runs the Worker that answers every link scan at its nearest location, keeps a short-lived cache of link answers, hosts DNS records you ask us to create, issues the certificates for custom domains, and answers the DNS-over-HTTPS lookups we use to check domains you add by hand.
- Google provides sign-in with Google. Its Safe Browsing service receives the http and https destination addresses of your links when you save a link and in a daily check. We do not send it your account details.
- Resend sends our emails and sees the recipient address and the message.
These providers process data outside Malaysia, including in the United States, and Cloudflare handles a scan at the location nearest the visitor. They host and deliver the service, and we picked them for that reason. We share data with them only to run tipeerQR. We also share data when the law requires it, such as for a valid request from a court or an authority, and we may pass details of serious abuse to the authorities. We do not share personal data with anyone else.
How long we keep it
- Individual scans stay for 365 days, and then a daily job deletes them.
- Daily totals and counters, which hold counts and no individual visits, stay for as long as the link exists. Deleting a link deletes its scans and its totals.
- Your account details, links, domains, apps, saved QR styles, logos, API key records and Cloudflare connections stay until you delete them or delete your account.
- Emailed codes expire after 15 minutes.
- Rate-limit hashes go within about two hours, as described above. The hashes kept by the code limiter go within about 30 minutes, and those kept by the email-change limiter within about two hours. The account and API key ID records of the other limiters stay until you delete your account. The failed-attempt records of Convex Auth go an hour after the last attempt.
- A sign-up that is never verified goes about 24 hours after we last sent it a code. An email change you never confirm goes within about 30 minutes of the request.
- The Google account ID stays until you delete your account.
- Reports, including the optional email address a reporter gave, and the administrator log stay for as long as we keep them to enforce the Abuse Policy. We have not set a deletion date for either, and deleting an account does not delete them.
- Our providers keep their own backups and logs under their own policies, so a copy can outlast a deletion for a short time.
Deleting your account
Open Settings and choose Delete account, then type your email address to confirm. The account stops working at once. We then remove your links, your click history and statistics, your saved QR styles and logos, your apps, your API keys, your domains, the custom hostnames and the DNS records tipeerQR created in your Cloudflare zone, your Cloudflare connections, your sessions, the rate-limit and failed-attempt records that carry your account ID or your address, and the account itself.
The removal runs in the background. If removing a custom hostname or a route fails, it retries until it succeeds. It can take a while when Cloudflare is slow, but it does not stop. We try to delete the DNS records we created in your zone. If you have revoked our access to your Cloudflare account, we cannot reach your zone, so those records stay and you remove them yourself.
A report you sent keeps the email address you gave for as long as we keep the report, including after an administrator resolves it. The administrator log also stays. Email us if you want the address or the whole report deleted.
Your choices and rights
You choose what you give us. Sign-in with Google, a Cloudflare connection and the email on a report are all optional. You can turn off domain status emails in Settings, remove a Cloudflare connection in Settings, and revoke our access in your Cloudflare account.
Under the PDPA you can ask us for a copy of the personal data we hold about you, ask us to correct it, ask us to delete it, or withdraw a consent you gave. You can change your display name, password and email address yourself in Settings, and you can download the stats for your own links as a CSV file. For anything else, email support@tipeer.com from the address on your account, so we can check the request is yours. We answer as soon as we can and within the time Malaysian law sets. If you are not happy with our answer, you can complain to the Personal Data Protection Commissioner of Malaysia.
Giving us accurate details keeps your data correct. Tell us if something we hold about you is wrong.
Security
The website and the link domains use HTTPS. We encrypt Cloudflare tokens with AES-256-GCM, store passwords and API keys only as hashes, hash IP addresses with a secret key before we count them, and keep our secrets out of the code. Our backend checks that you own a link, domain or key before it lets you read or change it. No system is perfectly secure, so we cannot promise absolute security. If we learn of a breach that affects you, we will tell you as the law requires.
Children
Accounts are for people 18 and over, and we do not knowingly open an account for anyone younger. If you think a child has given us account data, email us and we will delete it. A scan of a link records the same facts for every visitor, and we cannot tell a visitor's age.
Changes to this policy
We may update this policy. We will change the effective date above, and for a material change we will tell account holders by email or on the site.
Contact
Questions, requests and complaints about personal data go to support@tipeer.com, which reaches the person at Tipeer who handles privacy requests.