Version 2026-09-16.1, last updated 16 September 2026.
This policy describes what vdaDocs actually does with your information. It was written by reading our own code and database, not by filling in a template. If you find something here that does not match what the app does, that is a bug and we want to hear about it.
1. Who we are
vdaDocs is a visa readiness tool. It tells you what a given government asks of an applicant applying from India (which forms, which documents, which pitfalls) and lets you track how ready you are before you pay a fee.
We are not a visa agency. We never file an application on your behalf, we have no affiliation with any government or consulate, and we never handle your application documents. That is a product decision, and it is also why this policy is short: we simply do not hold the kind of information a filing agent holds.
Data controller: Xdecoders Programming Services ("XPS," "vdaDocs," "we," "us," or "our"), 6142 E Berkeley Ave, Fresno, CA 93727, United States. Contact: support@vdadocs.com
2. What we never collect
We want to be as clear about the absences as about the presences, because for this product the absences are the point.
- We never collect your passport number, or any other government document number. There is no field for one anywhere in the app or the database.
- We never take your documents. The app has no camera access, no photo picker, no file picker and no upload of any kind. Our servers have no file upload capability installed at all. When your checklist says you have your bank statements, we store a tick (a boolean) and never the statement.
- We never file anything for you. Our servers make no outbound call to any government system, ever.
- We do not ask for your phone number, postal address, gender, nationality, income, employer, or marital status. There is a name field, and it is optional: nothing asks for it at signup, the service works without it, and you can set, change or clear it at any time from the account screen.
- We do not sell your personal information, and we do not share it for cross-context behavioural advertising.
- We do not use advertising SDKs, attribution or install-tracking SDKs, session replay, or ad tracking pixels. None are installed.
3. What we collect, why, and on what legal basis
3.1 Your account
| What | Why | Legal basis (GDPR) |
|---|---|---|
| Email address | It is your login and the only way to reset your password | Contract (Art. 6(1)(b)) |
| Password, stored only as a scrypt hash | To sign you in. We never store the password itself and cannot recover it | Contract |
| Date of birth | Determining whether you are under 18, so that we can exclude minors from contact; and deciding whether an announcement is addressed to your age group once notifications exist (see 3.9) | Legal obligation / legitimate interest in child safety (Art. 6(1)(c), 6(1)(f)) for the first; legitimate interest (Art. 6(1)(f)) for the second |
| A derived "is minor" flag | Excluding minors from every contact list, every export, and every notification audience | as above |
| An age band (for example 25 to 34), worked out when a notification is being addressed and not stored | Choosing who a notification goes to. Your exact date of birth is never used for this | Legitimate interest (Art. 6(1)(f)) |
| An optional name | Shown back to you on the account screen, and nothing else. Staff contact lists do not display it | Contract |
| Account creation and update timestamps | Account administration and security | Contract / legitimate interest |
Date of birth is mandatory at signup and is collected from everyone.
What this does and does not mean in practice:
- Your exact date of birth is never used to address a notification. Only the band it falls in, worked out at the moment an audience is counted.
- We do not use your age for advertising. There is no advertiser at all (section 11), and no data of any kind goes to one.
- We do not use your age to change what the app shows you. Ranking in the news feed is done on your own device from what you have read (section 3.4), and it does not use your age.
- The exclusion of minors is a rule, not a setting. No member of staff can compose an audience that includes an account recorded as under 18; the exclusion is written into the query itself and cannot be relaxed from a screen. See section 9.
3.2 Your plans and checklists
When you create a plan, we store: the country you are applying from (currently always India), the destination country, the visa category and route, the specific forms you selected, and your optional target travel date. We also store which checklist items you have ticked, as item identifiers and a true/false, never the content of any document.
Plans sync so you can use the same account on more than one device and not lose your progress. Legal basis: contract; this is the service.
If you use the app without an account, your plans live only on your device, keyed to a random per-install token, until you sign in.
3.3 Bookmarks and saved articles
These never leave your device. There is no bookmarks table on our servers.
3.4 Reading behaviour, used only on your device
The app ranks your news feed against what you have actually been reading. To do that it keeps, on your phone and nowhere else, a short list of at most 60 country codes for stories you opened.
That list is never uploaded. There is no endpoint that accepts it and no code that sends it. We built it this way on purpose: personalisation does not require a server to know you.
3.5 Usage and crash reporting, behind a consent switch
Settings → Privacy has a single switch controlling all three measurement sinks below. Turning it off stops all of them, empties any queued events on your device, and clears the account identifier we gave to crash reporting. The switch is on by default; you can turn it off at any time.
(a) Our own event log. The app sends a closed list of 77 named events (such
as plan_created, checklist_item_toggled, news_story_opened,
sign_in_completed) to our own servers, with your account id and a
per-install device token attached.
Event parameters are sanitised twice, once on your device and again on our
servers, against a strict pattern that cannot carry free text: no spaces, no
@ signs, non-ASCII dropped. This means a search box's contents, an email
address, an article headline or a URL cannot end up in an event. Search is
recorded as "did search: yes/no" and a result count. Target dates are bucketed
into a window rather than sent. Country codes and route identifiers are sent,
so our event log does know which destination you are planning for.
(b) Google Firebase Crashlytics. When the app crashes, a crash report goes to Google. These reports are not anonymous: we attach your account identifier, the opaque UUID that identifies your account in our database. It is not hashed. It means nothing to Google on its own, but it is stable across sessions and across reinstalls of the same account, and we could use it to link a crash to you. We attach it so that when someone tells us the app crashed, we can find that crash. It is cleared when you sign out, when you delete your account, and when you turn the consent switch off.
(c) Google Firebase Analytics. Enabled in the same switch. In addition to
our named events, Google's SDK automatically collects things we do not choose,
including first_open and session_start, app and OS version, device model,
platform, a Firebase app-instance identifier, and coarse geographic location
derived from your IP address at Google's end. We do not give Google your
account id for analytics (only for crash reporting), and we do not enable
Google's automatic screen tracking.
(d) Device telemetry. Platform, OS version, device model, app version, language and time zone, keyed to the per-install device token rather than your account. This is what tells us which OS versions we still have to support.
Legal basis: consent (Art. 6(1)(a)).
3.6 Approximate location: optional, and coarse on purpose
If you turn on local news, the app asks your operating system for your position and immediately rounds it to two decimal places (roughly 1.1 km) on your device, before anything else sees it. The rounded value is rounded again before it is sent, and our database column cannot store more precision. We use it to lead your news feed with stories about where you are.
- We keep only the latest position. There is no history and no movement log; the row is overwritten in place.
- It is keyed to your install's device token, not your account.
- It is refreshed at most every 15 minutes, and only while the app is in the foreground. Background location is disabled and we never request "always" permission.
- It is deleted after 90 days automatically, whether or not you do anything.
- Turning it off erases our copy, from your app's next telemetry report.
What we derive from it. The first time a plan syncs, we work out an Indian state and district (an ISO 3166-2 code, nothing finer) from that coarse coordinate and store it on the plan, so we can see which parts of India our users apply from, and so that an announcement about a route can be addressed to the places it affects (section 3.9). That derived state and district are cleared along with the position itself, whether by your turning location off or by the 90-day sweep.
Because it is rounded to about 1.1 km, this is not "precise geolocation" within the meaning of the CCPA/CPRA (which sets the line at 1,850 feet, about 564 m). Under GDPR it is still personal data and is treated as such.
Legal basis: consent.
3.7 Sessions and security
We store a hash of your session token (never the token), when it was created, when it was last used, when it expires, and the first 200 characters of your browser or app user-agent string. This is what lets you see and revoke your own signed-in devices. Legal basis: contract / legitimate interest in account security.
IP addresses. We do not store your IP address in our database. Our web server writes an ordinary request log that does include the client IP address, used for rate limiting to stop brute-force attacks. Those logs live in our hosting platform's log stream and are transient rather than kept in a database. Legal basis: legitimate interest in security.
The country your connection appears to be in. We work out, from your IP address, which of the six countries we serve as an origin you appear to be connecting from: India, Nepal, Bangladesh, Sri Lanka, Pakistan or Bhutan. We store that two-letter country code, and alongside it a truncated form of the address so we can work out why a wrong answer was wrong. For IPv4 we keep the first three parts and zero the last, which covers 256 addresses; for IPv6 we keep the first 48 bits, an allocation an internet provider hands out in bulk. Both are deleted after 90 days, the same window as the approximate location above. The lookup is a table of address ranges built into our own server from the regional internet registry's published records; your address is not sent to anyone to do it.
What it is for, and only for: choosing which passport the app assumes you are applying on before you have told us. Without it, everyone who has not yet made a plan is treated as Indian, which is wrong for most of the people we serve and means the news written for their own country never reaches them. You can change it at any time in Settings under "Applying from," and what you choose there overrides this entirely. It is a guess, and we treat it as one: the registry records where an address block was handed out, not where it is being used, so a VPN, a corporate network or a roaming SIM will often make it wrong. It never determines anything you cannot change.
Legal basis: legitimate interest in showing you news relevant to the passport you hold.
3.8 Contact about vdaDocs
By holding an account, you agree that we may contact you about vdaDocs: your plans, changes that affect a route you are applying on, your access, and occasional news about the product. This is stated here and in the Terms rather than being a switch in the app; if you would rather we did not contact you, write to us and we will remove you by hand.
Your account appears in an internal list that people at vdaDocs can use to contact you. That list shows an operator your email address, your destination country, how ready you are, how many days until your target date and how recently you were active. It does not show your name, your documents, your checklist answers or your location.
That list is gated three ways, and we are describing the gates because they are the actual protection:
- Known minors are excluded. If we hold a date of birth and it says you are under 18, you are never returned, on any screen or export.
- Only the account owner role can open or export it; no other staff role holds the permission, and it is rate-limited.
- Every single view and every export is written to an audit log with who looked and when. Caching is deliberately disabled on this screen so that no view can escape the log.
3.9 Push notifications
This feature is not yet in operation. As of this version, vdaDocs cannot send a push notification at all: there is no notification permission request, no push token anywhere in our database, and nothing capable of sending one. This section describes what will happen once it is built, so that nothing here is something you find out about only after it ships.
What we will store. If you allow notifications, your phone's operating system issues a push token, and we keep it, along with which install it belongs to and which account, if any, is signed in on that install.
A push token is a delivery address issued by Apple or Google, not an identifier we invent. It is stored in ordinary readable form rather than hashed, because unlike a password or a session token it is something we send to, not something we check you against. It changes on its own, and it stops working when you turn notifications off, delete the app, or move to a new handset.
Keeping a token is not gated on the analytics switch. Delivering a message someone asked for is not measuring them. What does gate it is your operating system's permission and the category switches in Settings; turn a category off and no message in it is sent to you.
What decides whether a notification is addressed to you. Which category it is in, and an audience which may be built from: the country, state and district your plan is made from (section 3.6), the country you are applying to, the route and how far through it you are, and your age band (section 3.1).
What is never used to address one: your checklist answers, your target date, your name, your email, or what you have been reading. The reading list never leaves your device (section 3.4).
Two rules that cannot be switched off by an operator:
- Nobody recorded as under 18 is ever in an audience. Same rule, same query, as the contact list in section 3.8.
- A device with no account is never sent anything promotional. Without an account we have no date of birth, so we cannot know whether we are writing to a child, and the response to not knowing is not to send.
What a member of staff can see while composing one. A count, and up to ten rows describing the shape of the audience (a state, an age band, a destination, a plan stage, a platform, a language). No email addresses, no account ids, no names, no tokens. Every send is written to the audit log with who sent it and to which audience.
How long we keep it. A push token until you turn notifications off, sign out, delete your account, or the platform tells us it is dead. A record of which notification went to which install, for 90 days. See section 7.
Legal basis: contract, for messages about a plan or an account you hold; legitimate interest for occasional product news; and where local law requires opt-in for a promotional message, your consent, given by the category switch.
Delivery is not guaranteed. Notifications travel through Apple's and Google's networks and through whatever your handset does with background apps. Some are late and some never arrive. Nothing that matters to your application will be told to you only by a notification.
3.10 Support look-ups
If you contact us with a problem, a member of staff may look up your account. That surface requires your exact email address or account id (there is no partial search, no wildcard, no browsing) and a written reason, and it writes an audit record naming the staff member and their reason on every look-up, including look-ups that find nothing. It shows account metadata, device and session information, plan counts and event counts. It does not show your documents, your checklist answers, or your coordinate.
3.11 Aggregate statistics
Our internal dashboards are otherwise aggregate-only, and any bucket with fewer than 5 people in it is suppressed rather than shown, so that a statistic can never resolve to a person. The map view buckets locations to half a degree (about 55 km) and applies the same threshold. A separate, clearly labelled synthetic demo dataset exists for screenshots and training; every synthetic row is flagged in the database and is excluded from the real dataset by default.
4. The website
The vdaDocs website is deliberately plain.
- No third-party analytics, no tag manager, no advertising or social pixels, no session replay, no A/B testing service, no CDN-hosted fonts. As of this version the site loads no third-party script of any kind and makes no third-party network request.
- Cookies: when you sign in on the web, we set a single strictly necessary
session cookie. It is
httpOnly(JavaScript on the page cannot read it),securein production, andsameSite=lax. It holds a session reference; your API credentials stay on our server and are never sent to your browser. It is deleted when you sign out or when the session expires. - Because the only cookie is strictly necessary and there are no trackers, the site does not show a cookie consent banner. If we ever add a non-essential cookie or any third-party analytics, we will add a proper consent banner first, and this section will say so.
- If we add a "notify me at launch" email form, we will state at the point of collection what the address will be used for, and it will be used for nothing else.
Reading news articles. The app and site open news stories in an in-app browser pointed at the publisher's own website. When you open a story, that publisher's servers see your request the same way they would in any browser: your IP address, your user agent, and whatever cookies they set. We do not control and are not responsible for what a publisher does; their privacy policy applies to that visit, not ours.
5. Who your data is shared with
We share personal data with four kinds of recipient and no others.
| Recipient | What they get | Why |
|---|---|---|
| Railway (hosting) | Everything, as our infrastructure provider: application servers, the Postgres database, and the request logs containing IP addresses | We have to run the service somewhere |
| Google (Firebase Crashlytics and Firebase Analytics) | Crash reports carrying your account identifier; analytics events; device and app metadata; a Firebase app-instance id; IP-derived coarse geography | Fixing crashes and understanding usage, only if you have not turned the consent switch off |
| Google (Firebase Cloud Messaging) | Your device's push token and the contents of the notification | Delivering a notification to your handset, once this is in operation (section 3.9). Not gated by the analytics consent switch, because delivering a message is not measuring you |
Our email provider (infrastructure operated in Phoenix, Arizona, United States, sending as noreply@vdadocs.com) |
Your email address, and the contents of the message, which may include your name | Sending you the three emails described below |
We send you exactly three kinds of email, and nothing else. There is no newsletter, no campaign, no drip sequence and no mailing list:
- A password reset link, when you ask for one.
- A short message confirming your account, once, when you create it. If you have set a name, that email uses it.
- An invitation to the admin panel, which only ever goes to a member of staff and never to a customer.
We do not need your permission to send the first two, because they are the service you asked for; section 3.8 covers anything beyond them.
We do not share personal data with advertisers, data brokers, lead-generation firms, immigration consultants, agencies, or anyone else. We may disclose data if we are legally compelled to, and we will tell you if we are permitted to.
News publishers are sources we read from, not recipients; we fetch their public feeds server-side with no user data attached whatsoever.
6. International transfers
Our servers and database are hosted with Railway, operating infrastructure in the United States. Our email is sent through infrastructure operated in Phoenix, Arizona, United States. Firebase is operated by Google and processes data on Google's infrastructure, which includes servers in the United States.
If you are in the EEA, the UK, India, or elsewhere outside the United States, this means your data is processed in the United States. Transfers to Google rely on Google's Standard Contractual Clauses and its supplementary measures, as set out in the Google Cloud/Firebase data processing terms. We maintain appropriate contractual and technical safeguards with our other infrastructure providers for the same purpose.
7. How long we keep things
| Data | Retention |
|---|---|
| Account (email, date of birth, password hash) | Until you delete your account |
| Plans and checklist ticks | Until you delete the plan or your account |
| Approximate location coordinate | 90 days, swept automatically |
| The state and district derived from it | Cleared with the coordinate: on revocation, and by the same 90-day sweep |
| Country derived from your IP, and the truncated address | 90 days, swept automatically |
| Push token | Until you turn notifications off, sign out, delete your account, or the platform reports it dead |
| Notification delivery records | 90 days, swept automatically |
| Other device telemetry (OS, model, app version, locale, time zone) | 180 days, swept automatically |
| News articles | 30 days |
| Session records | Until the session expires |
| Password reset tokens | Until they expire or are used |
| Analytics events | Retained without an automatic deletion schedule at this time |
| Internal audit records of staff access | Retained without an automatic deletion schedule at this time |
We are working toward a defined, automatically enforced retention period for the last two rows above. Until that is in place, those categories are kept rather than automatically purged; you may still ask us to delete data specific to your account by contacting us, and we will do so by hand.
Neither vdaDocs's user numbers nor its category put it within the Third Schedule of the DPDP Rules, 2025 (which imposes a hard three-year cap on e-commerce, social media and online gaming platforms above stated user thresholds). We state the schedule here for completeness, not because it currently binds us.
8. Your rights, and how to actually use them
Depending on where you live, you have rights to access, correct, delete, port and object to the processing of your personal data, to withdraw consent, and to complain to a regulator.
Here is what the product can do today:
Delete your account: self-service, immediate, and real. Settings → Delete account. This is a hard delete, not a flag: your account row, your name if you set one, your sessions, your password reset tokens, any push token registered to your account, and your synced plans and checklist ticks are removed from the database immediately. There is no grace period and no recovery.
Two things survive an account deletion, in a pseudonymised rather than erased form:
- Your device record: platform, OS version, device model, app version, language, time zone, and any coarse coordinate that has not yet aged out. It is disconnected from your account but not deleted immediately; it ages out on the 90/180 day schedules above.
- Your analytics events: the account id is set to null, but the events remain, still keyed to the per-install device token.
If you want either of these gone immediately rather than on the normal schedule, contact us and we will do it by hand.
Withdraw consent: in Settings, at any time, for usage and crash reporting, for local news, and (once they exist) for each category of notification. Withdrawal takes effect immediately and, for location, erases both our stored copy and the state and district we derived from it (section 3.6). To withdraw permission for the contact described in section 3.8, write to us and we will remove you from the list by hand.
Access, correction, portability, objection, and complete erasure: these requests are currently handled by hand rather than through a self-service export. Write to us at support@vdadocs.com and we will respond within 30 days.
Complaints. In India, to the Data Protection Board of India. In the EEA or UK, to your national supervisory authority. In California, to the California Privacy Protection Agency or the Attorney General. You can complain to a regulator without going to us first, though we would rather you told us.
9. Children and under-18s
We collect a date of birth from every person who signs up, and we use it to set an internal minor flag. Where that flag is set, the account is excluded from every contactable list, every export, and every notification audience. That exclusion is written into the queries themselves: it is not a filter a member of staff chooses and there is no screen on which it can be relaxed.
We do not independently verify the date of birth you give us, and vdaDocs does not currently obtain verifiable parental consent before a person under 18 creates an account, which India's Digital Personal Data Protection Act, 2023 requires for the processing of a child's personal data. The exclusion described above is real and enforced in the software, but it is narrower than what the Act asks for, and we are working to close that gap. If you are a parent or guardian and believe your child has created an account, contact us at support@vdadocs.com and we will remove it.
Under GDPR the age of digital consent is 13 to 16 depending on the member state, which is a lower bar than India's; the Indian standard is the binding one for our primary audience.
10. Security
- Passwords are stored as scrypt hashes and are never stored or logged in plain form.
- Session tokens are stored as SHA-256 hashes; the raw token exists only in your client.
- On the web, your API credentials never reach your browser; they stay on our
server behind an
httpOnlycookie. - Staff access to anything identifying a person is permission-gated by role, rate-limited, and audited.
- Our servers accept a closed allowlist of event names and parameters, which is why free text cannot end up in our analytics even by accident.
One limitation we will state rather than omit: on mobile, your session token is stored in the app's ordinary application storage, not in the iOS Keychain or the Android Keystore. It is protected by the operating system's per-app sandbox and by device encryption, but not by the platform's dedicated secret store. We intend to move this to the platform secret store.
No system is perfectly secure. If you believe your account has been accessed without your permission, sign out of all devices in Settings and contact us.
Breach notification. If a breach affects your personal data, we will notify you without undue delay, and will report to the Data Protection Board of India within 72 hours of becoming aware, as the DPDP Rules require, and to EEA/UK supervisory authorities where GDPR applies.
11. Advertising
There is a slot in the news feed reserved for sponsored content. It is currently unsold and renders an empty placeholder labelled "Sponsored." There is no advertising SDK in the app, no advertiser in our database, no ad request, no tracking pixel, and no impression or click event. No data is shared with any advertiser, because there is no advertiser.
If that ever changes, sponsored content will always be labelled as such, and this policy will be updated before any advertising runs, not after.
12. For California residents (CCPA/CPRA)
In the last 12 months we have collected the following categories: identifiers (email address, account id, device token, IP address in server logs, the country and truncated address derived from it), internet and application activity (the event list in section 3.5), geolocation data (coarse, as described in section 3.6, and not "precise geolocation" as the CPRA defines it), and one category that may count as sensitive personal information depending on how it is read: date of birth, used for age determination and, once notifications exist, age-band targeting.
We do not sell personal information and we do not share it for cross-context behavioural advertising, as those terms are defined by the CPRA, and we have not done so in the preceding 12 months. Because we do not sell or share, there is no "Do Not Sell or Share My Personal Information" link.
We currently use sensitive personal information only for purposes permitted without a right to limit (performing the service and ensuring security). As age-band targeting for notifications comes into operation, we will review whether that continues to hold and add a "Limit the Use of My Sensitive Personal Information" mechanism if it does not.
You retain the rights to know, delete, correct and to non-discrimination; see section 8.
13. Changes to this policy
This policy carries a version number (see the top of this document). When we change it:
- the version and date change;
- the change is described in the change log below;
- and we will not quietly re-interpret an old acceptance as covering a new practice.
The re-acceptance sheet the app shows on next launch is driven by the version of the Terms, the document acceptance is recorded against. A new version of this policy alone updates the "last updated" date and the text you are reading; where a change to this policy should be seen rather than merely published, we will update the Terms version as well so the sheet appears.
14. Contact
Change log
| Version | Date | Changes |
|---|---|---|
2026-09-16.1 |
2026-09-16 | First public version. Names the data controller (Xdecoders Programming Services, Fresno, California) and the contact address (support@vdadocs.com), both previously open. Names the country our infrastructure operates in for Railway and for our email provider (United States), closing the open items in section 6. Section 9 states our current practice on minors in plain terms: date of birth is self-reported and not independently verified, and the DPDP Act's verifiable-parental-consent requirement is not yet met, alongside the real protections that are in place today. |
2026-09-12.1 |
2026-09-12 | One correction and one new practice, both about your IP address. Section 3.7 previously said we had no geo-IP lookup. That is no longer true: the app now works out which of the six origin countries your connection appears to be in, so that somebody who has not yet made a plan is not assumed to be Indian. What is stored is a two-letter country code and a truncated address (an IPv4 /24 or an IPv6 /48), both deleted after 90 days. The lookup is a table of address ranges built into our own server; the address is not sent to a third party to perform it. Settings has an "Applying from" control that overrides it. |
2026-09-11.1 |
2026-09-11 | We send email now. Until 11 September 2026 no mail provider was configured and a password reset link went into our own server log instead of to the person who asked for it. The recipient table now names a provider and what it receives: three kinds of message, one of which (the confirmation sent when an account is created) goes to everybody who signs up. |
2026-09-10.1 |
2026-09-10 | Three changes of practice. Date of birth is no longer used for age determination alone; once notifications exist, an age band also helps decide who an announcement is addressed to (sections 3.1, 3.9). A new section 3.9 describes push notifications ahead of the feature being built. The contact permission described in section 3.8 moved from a Settings switch into this document. Also corrected: the derived state and district no longer outlive the coordinate they came from, and an optional name can now be set and edited on the account screen. |
2026-08-26.1 |
2026-08-26 | First draft, written from the source code and database schema. Establishes mandatory date-of-birth collection at signup; that crash reports carry a stable account identifier; that Firebase Analytics is enabled alongside Crashlytics; the coarse-location lifecycle; the marketing-contact list and its gates; the on-device-only reading profile; and the absence of any document, passport-number or file handling. |