Privacy
Last updated 18 September 2026
Sourcedock connects to marketing accounts you already have, runs a query you built, and writes the answer into your own spreadsheet on a schedule. This page says what that means for the data involved: what we read, what we keep, what we never keep, who else touches it, and what you can ask us to do.
It describes the product as it is actually built. Where something a privacy policy normally promises is not built yet, this page says so rather than implying it.
The short version
- We do not keep your results. A query result travels from the source, through our server’s memory, to your browser, your download, or your spreadsheet. No row of result data is written to our database.
- We do keep the working parts: your account, your team, your connections, your saved queries, and a history of every run.
- Access tokens are encrypted with AES-256-GCM before they reach the database. The key lives only in the server’s environment, never in the database.
- Disconnecting hands the grant back. Where the provider supports it, removing a connection also revokes our access at the source, not just our copy of the token.
- There is no tracking. No analytics script, no tag manager, no advertising code, no error-reporting service.
- Almost nothing is deleted on a timer. There is no cleanup job in the product. The retention section says exactly what deletion is today.
Who we are
Sourcedock is operated from the Netherlands by Milan van Bruggen. It is a one-person operation, and the product is pre-launch: a private pilot, with no paying customers yet.
For anything on this page — a question, a copy of your data, a correction, a deletion — write to privacy@sourcedock.eu. A person reads it. For anything else, hello@sourcedock.eu.
We have not appointed a data protection officer. One is not required for a service of this size and kind, and we would rather say that than leave the question hanging.
Which role we are in
Two different things happen here, and the law treats them differently.
We are a processor for everything you bring into Sourcedock or pull through it: your connections and their tokens, your saved queries, and the data fetched from Google Analytics, Search Console, Google Ads, Facebook Ads, Reddit Ads or your WooCommerce store. We have no independent purpose for any of it. Your own legal basis governs that data; we do not invent one.
We are a controller for your account and how you sign in, for teams and invitations, for requests to join the pilot, and for operational logs.
Run history sits on both sides. It is your record of which queries ran, and it is our record of whether the service is working. We treat it as both.
We are not a controller for the platforms you connect. Google, Meta and Reddit are independent controllers for their own processing, and your WooCommerce store is yours. If you are an agency and your client’s data passes through Sourcedock, you are likely a processor for that client and we are your sub-processor.
Why we are allowed to hold it
This applies only where we are the controller. Where we are the processor we act on your instruction and rely on your basis, not one of our own.
- Your account, your team, and running the service — Article 6(1)(b). There is no sign-in, no team and no scheduled refresh without them.
- A request for a place in the pilot — Article 6(1)(b), as a step taken at your own request before any contract.
- Keeping the service working and secure — Article 6(1)(f). Our interest is in knowing that a refresh broke and why, in spotting abuse of a public form, and in being able to tell you what happened. Ask and we will explain how we weighed that against you, and you can object to it.
We do not rely on consent for anything, so there is no consent here to withdraw. The consent that matters is the one you give Google, Meta or Reddit, and you withdraw it by disconnecting.
Google user data
Each Google connection asks for one permission and nothing else. Connecting for Search Console does not hand over your Analytics or your spreadsheets. If you untick something on Google’s consent screen, Sourcedock refuses to store the connection rather than recording a permission you did not give.
What each permission allows, and why we ask
- Google Analytics 4 —
analytics.readonly. Read-only access to the GA4 properties the connecting account can already see. Used to list your properties and run the reports you defined. It cannot write anything back. - Search Console —
webmasters.readonly. Read-only access to that account’s sites. Used to list them and run search performance queries. Search Console itself keeps only a limited window of history, which is one reason people schedule these queries. - Google Ads —
adwords. Google publishes no read-only variant of this permission, so the scope is broader than what we do with it. Sourcedock makes only read calls: listing the accounts a connection can reach, and reading campaign, ad group and keyword performance. It does not create, change or pause anything. - Google Sheets —
spreadsheets. Used to write a query result into the spreadsheet, tab and cell you nominate, and to add that tab if it does not exist. It is a separate connection from every reading connection, so a team that only reads never grants it. openidandemail, on every Google connection. Used for one thing: reading the account’s address so the connection has a name you recognise, and so a team with two Google accounts can tell them apart.
Google’s narrower drive.file permission reaches only files an app created itself or that you picked through Google’s own file picker. A Sourcedock destination points at a spreadsheet that already exists — usually one your client already reads, identified by its link — which drive.file does not authorise. That is why the broader permission is the one this feature needs.
Sourcedock reads Google Analytics data on your behalf. It does not run Google Analytics on this website, and there is no Analytics tag anywhere in the product.
What Google data we store
- The access and refresh tokens, encrypted before they are written. The Sheets connection’s token is the only one that can write anything.
- The account’s email address, the permissions Google reported as granted, and which kind of connection it is.
- A cached list of what that connection can reach: GA4 property names and ids, Search Console site addresses, Google Ads customer ids and account names. For an agency these are often your clients’ names. The list is refetched after an hour, but the stored copy is not wiped on a timer — it is replaced when you reconnect, and deleted when the connection is deleted.
- Query definitions and run history: which accounts, which date range, which fields and filters, whether the run worked, the row count, the duration, and any error. Filter values are free text, so a filter can contain a search term a real person typed or a page address.
What Google data we do not store
Result rows. Not once, not in a cache, not in a log. The query engine hands the result back in memory and records only the status, the row count, the duration and any error. From memory the rows go to exactly one of three places: the table in your browser, a CSV or JSON file your own browser assembles, or your spreadsheet.
That is the most important sentence on this page. Marketing data passes through Sourcedock. It does not live in Sourcedock.
Limited use of Google user data
Sourcedock’s use and transfer of information received from Google APIs to any other app will adhere to the Google API Services User Data Policy, including the Limited Use requirements.
The use of information received from Google Workspace APIs will adhere to the Google Workspace API Services User Data Policy, including the Limited Use requirements.
In plain terms: we use this data to run the query you saved and put the answer where you told us to. We do not transfer it to anyone else, we do not use it for advertising, we do not sell it to data brokers, we do not use it to train models, and no person here reads it.
The other sources
- Facebook Ads asks for
ads_readonly, and reads spend, reach and results from ad accounts you manage. Meta issues no refresh token, so a connection lasts roughly sixty days and then has to be made again. We store the account holder’s name, not an email address. - Reddit Ads asks for
identityandadsread, and reads campaign performance. We store the Reddit username asu/name, nothing else about the person. - WooCommerce uses a consumer key and secret you generate in your own store. There are no scopes to ask for: whatever you ticked when you created the key is what the key can do, and only your store knows. The pair is encrypted the same way a token is. Sourcedock refuses a store address that is not HTTPS, because the key and secret travel as HTTP Basic authentication.
One thing about WooCommerce worth saying plainly. A store’s orders carry its buyers: the billing block alone is a name, a street, a postcode, an email address and a phone number. Sourcedock does not ask for it. The request names the eleven fields a result row is built from — the order’s status, date, currency, totals, payment method, item counts, coupon codes, whether the buyer was a registered customer or a guest, and the billing country and nothing else from that block. What we do not ask for never reaches us. Those are still your store’s own customers and you are the controller for them, so make sure your own privacy notice covers what you report on.
What is in our database
Your account and profile. Your teams, who is in them and each person’s role. Invitations, with the address an admin typed in and the token that matches it. Connections, with the encrypted tokens and the cached list of what each can reach. Saved queries. Destinations, with the spreadsheet id, tab and start cell. Schedules. And one row per run, with the status, the row count, the duration, what started it, and the error if it failed.
Three honest details about that.
Error text is third-party text. When a run fails we store up to 2,000 characters of whatever the source said. Nothing redacts it, and it can quote part of the request back. It is stored so that whoever opens the page hours later can see why their spreadsheet is empty.
Inside a team, all of it is readable by every member, not only by admins — including invitation links and the error text on a failed run. The encrypted token columns are readable too, but the key that decrypts them is not in the database. Invitation tokens are stored as plain text, so treat an invitation link like a password.
Server logs. Our host keeps request and function logs, which include IP addresses, the pages requested and timestamps. We do not put tokens or result rows in them, we cannot search them by person, and they are deleted on our host’s schedule rather than ours. We read them to investigate a fault or abuse, and for nothing else.
How teams are kept apart
Twice over. The application checks which team you are acting for on every request, and the database enforces the same rule independently through row-level security. A forgotten filter in our code cannot expose another team’s rows, because the database refuses them on its own account.
Cookies, and the absence of tracking
Three kinds of cookie, all of them necessary to run the service:
- Authentication cookies managed by our auth provider, which keep you signed in.
- sd_active_team — which team you are currently looking at. Not readable by scripts, kept for a year.
- sd_oauth_state — a short-lived value that ties a connect flow to your browser so it cannot be hijacked. Not readable by scripts, expires after ten minutes.
Your browser also remembers your light or dark theme choice locally, and that never leaves your device.
There is no analytics, no tag manager, no advertising pixel, no session recorder and no third-party error reporting anywhere in the product. Both typefaces are compiled into our own deployment at build time, so loading a page tells Google nothing. That is why there is no cookie banner: none of these are used for tracking, and there is nothing to consent to.
Who else processes your data
Three companies, each doing one job:
- Vercel — hosting, the functions that run your queries, the hourly schedule, and request and function logs.
- Supabase — the database and sign-in, including password hashes and sessions.
- Resend — transactional email. Optional: if no mail provider is configured, Sourcedock sends no email at all.
All three process data outside the European Economic Area in some circumstances. We rely on the safeguards in each provider’s own data processing agreement, including the European Commission’s standard contractual clauses. Write to privacy@sourcedock.eu and we will tell you which agreement is in force and where each provider publishes its current terms and its own sub-processors — we would rather point you at the live document than quote a certification here that may have changed.
We will tell customers at least 30 days before adding or replacing a sub-processor, and you can object. If we cannot resolve the objection you can stop using Sourcedock and we will delete your team’s data.
Email is used for exactly two things: telling the owner of a saved query that its schedule broke, and again when it recovers; and delivering a request for a place in the pilot to us. That first message carries the query name, the team name, the destination as a sheet and cell reference, the error the source returned, and a link. Invitations are not emailed — an admin copies the link and sends it themselves.
The platforms you connect are not our sub-processors. You hold the relationship with each of them, you grant the access, and data moves because you told Sourcedock to fetch it.
Where the result goes
The full result is sent to the Google Sheets API, into the spreadsheet you nominated. It is written as raw values, so a cell is never re-interpreted as a formula. The new block goes in first and only then are the cells the old block no longer covers cleared — never the other way round, so a failed write cannot leave your report blank.
CSV and JSON exports are built by your own browser from the result already on screen and downloaded straight to your device. Nothing is uploaded, and there is no server-side export.
How long we keep things
Honestly: until you remove it. There is no automatic expiry and no cleanup job. Connections, saved queries, destinations, schedules and run history stay until the connection, the query or the team is deleted. Invitations stay after they are accepted, revoked or expired. The cached list of accounts a connection can reach is replaced rather than cleared.
We would rather publish a retention period than a paragraph admitting there is not one, and that is on the list of things to build. Stating a period the code does not enforce would be worse than saying this.
Disconnecting, and revoking access at the source
Removing a connection deletes its row and the encrypted tokens with it, and hands the grant back to the provider, so Sourcedock stops appearing among the apps with access to your account.
Google and Reddit accept that handback directly: we send the refresh token to their revocation endpoints, which ends the whole grant rather than just the hour the access token had left.
Meta and WooCommerce do not work that way. Meta revokes on a user id rather than a token, so remove Sourcedock under business integrations in your Facebook settings. A WooCommerce key is withdrawn by deleting the key pair in your own store, under WooCommerce, Settings, Advanced, REST API.
The handback is best effort and never blocks the removal: if the provider is unreachable at that moment we still delete the connection, because you asked for it to be gone. You can always revoke us yourself in the provider’s own settings.
Your rights
If you use Sourcedock, you can ask for a copy of the personal data we hold about you, ask us to correct it, delete it, restrict or object to our use of it, or send it to you in a portable form. Write to privacy@sourcedock.eu. We will answer within one month, and if we need longer we will tell you why inside that month.
Be aware how that works in practice: there is no export button and no delete-my-account button in the product. We do all of it by hand. That is slower than a self-service switch, and it is the honest state of a product this young.
If your data reached Sourcedock because an agency reports on a site you visited, the agency is your contact, not us. We hold their data on their instruction and will help them answer you. In almost every case the honest answer is that we hold no result data about you at all — only the definition of a query and a record that it ran.
If we get this wrong, you can complain to the Autoriteit Persoonsgegevens, the Dutch supervisory authority, or to the authority in the EU country where you live.
If you were invited to a team
Your address reached us because an administrator of a Sourcedock team typed it in, not because you gave it to us. We hold that address, the role you were offered, an invitation token and an expiry date, so the invitation can be matched to you when you accept it.
We do not email invitations — the administrator sends you the link themselves — so this page is where you are being told, and it is the only place you will be. If you would rather not have been invited, write to privacy@sourcedock.eu and we will delete the invitation and the address with it, whether or not you ever accept.
A data processing agreement
If you are a customer you are entitled to a processor agreement under Article 28, and there is not one published yet. Writing it — including the case where you are yourself a processor for your client and we are your sub-processor — is in progress. Ask us and we will tell you where it stands and send you the draft.
If something goes wrong
If we discover a personal data breach affecting data we process for you, we will tell you within 48 hours of becoming aware, with whatever we know at that point, so you still have most of your own 72 hours to work with.
For data where we are the controller — accounts, teams, pilot requests — we will report to the Autoriteit Persoonsgegevens within 72 hours where the law requires it, and tell affected people directly where the risk to them is high.
No profiling, no automated decisions
Sourcedock does not profile anyone and makes no automated decisions with legal or similarly significant effects. There is no scoring, no segmentation and no model of any person in the product. It runs the query you wrote and writes down the answer.
Changes
When we change what the product does with your data, we change this page and move the date at the top. If the change affects how we handle data from a connected account, we will write to you rather than leave you to notice. The terms change the same way.