Legal

Data processing agreement

The article 28 agreement: what we handle on your instruction, who else touches it, and what happens when you leave.

Version
2026-10-12-5
Last updated
12 October 2026

When you accept this document we store the version above, a fingerprint of this text, and the time you accepted it, so either of us can show later what was agreed.

What this agreement is

This is the data processing agreement required by article 28 of the GDPR. It applies to the personal data we handle on your instruction when you use Happyads, and it is part of the terms of service. Where this agreement and the terms say different things about personal data, this agreement wins.

It takes effect when you accept it, and it lasts for as long as we handle data for you. We store which version you accepted and when, so either of us can show later what was agreed.

It is written to say plainly what we do, so that your own adviser can check each statement against what you need.

Who it is between

Happyads is a service operated by Oaksmond ApS, CVR 43117785, Hovborgvej 1, 6623 Vorbasse, Denmark.

In this agreement you are the data controller and we are your data processor. It is between your company and ours; the person who clicks accept does so on behalf of the company, and we record which user it was.

We have not appointed a data protection officer, because we are not required to. Write to privacy@happyads.so and it reaches the people who can answer.

Which data is yours and which is ours

This is the distinction the whole agreement rests on, so it comes before the detail.

We are the controller, and this agreement does not cover it
Your own account and sign-in, the workspace, your billing and invoicing details, and anything you write to us. We decide why and how we hold those, and the privacy policy explains it. That half is our relationship with you, not yours with your customers.
You are the controller, and this agreement covers it
The personal data inside your advertising: the images you upload, the text you write in the campaign builder, the identifiers of your ad accounts and campaigns, and the figures we read back about them. You decide why it exists; we only handle it to run the product for you.

What we process, and on whose instruction

Your documented instruction is this agreement, the terms of service, and the choices you make inside the product. We process your data to do those things and nothing else.

We do not process it for any purpose of our own. We do not sell it, we do not share it for anyone else's marketing, we do not use it to train models, and we do not use it to build anything for another customer. If we ever believed an instruction from you broke data protection law, we would tell you and not act on it until it was sorted out.

The data, and the people it is about

Written narrowly on purpose. The product reads less than people expect, and an agreement that claimed otherwise would promise protection for data we do not hold.

Categories of data subjects
The people in your workspace who use Happyads. Any person who appears in an ad image you upload. Any person you happen to name in the ad text or headline you write. That is the list.
Categories of personal data
Images you upload, and the text and links you write. The identifiers, names and statuses of your ad accounts, campaigns, ad sets and ads. The daily spend and result figures attached to them. The revenue figures you enter yourself.
What is deliberately not in scope
We do not pull audience lists, custom audiences or customer lists out of your Meta account. We do not pull lead data, form submissions or messages. We hold nothing about the individual people who see or click your ads: Meta aggregates those into counts and sums before they reach us.
Special categories
We do not ask for and have no use for data about health, religion, politics, trade union membership, sex life, biometrics or criminal records. Do not put it in an ad image or an ad text, and this agreement does not cover processing it.
Nature and purpose
Storing, displaying and calculating on the above so that the product can set up campaigns in your own ad account, show you what they cost and earned, and judge them against the framework. Transmitting your ad content into your own Meta ad account when you create a campaign.
Duration
For as long as your subscription runs, and then as set out under leaving, below.

Confidentiality

Everyone at Oaksmond who can reach your data is bound to keep it confidential, and that duty outlasts their work for us. Access is given to the people who need it to run or support the service, and to no one else.

Security

The measures below exist in the product today. They are listed because each one can be checked, not because a template suggested them.

  • Each workspace's rows are separated inside the database itself, by row level security, so the separation is enforced by Postgres rather than by our application code remembering to filter.
  • Writes that have to bypass row level security use a server-only key that never reaches a browser. When you are signed in and set something off, the server first reads a row through row level security with your own session, and that row is what proves the workspace is yours: an ad account, a campaign, a campaign draft, or your membership of the workspace. Only then does the server key write anything into the workspace, and that workspace is the only one it writes to.
  • What it writes is not always the row it read. A sync reads the ad account and then writes that account's campaigns, ad sets, ads and daily figures, and it may renew the Meta access token on the connection that account belongs to. Connecting Meta reads your membership and then creates the connection and its ad accounts, which did not exist a moment before. And the first time you sign in there is no workspace to read, so one is created for you and you are made its owner.
  • Two things the server key writes belong to no workspace and hold none of your advertising data: a counter that limits how often an action can be repeated, and a log of our own calls to Meta that records what kind of call it was and whether it worked. In most places the counter is written as soon as we know who is signed in, before the workspace check.
  • Two kinds of write to a workspace have nobody signed in behind them, so there is no session to check, and each proves itself another way. The scheduled sync that refreshes your figures carries a secret only our scheduler holds. It writes each ad account's figures under the workspace that account already belongs to, and when the Meta access token behind that account is within 30 days of expiring, it asks Meta for a new one, checks that the new token can read that account, and only then stores it, encrypted, on the same connection. And when you remove Happyads inside Meta, Meta tells us in a message signed with our app secret; we verify the signature, and the only thing that message can do is switch your connection off and erase its token.
  • Your Meta access token is encrypted with AES-256-GCM before it is written down, with a key that lives only in the server environment and never in the database. Each token gets its own random initialisation vector and is authenticated, so a tampered value fails to decrypt rather than decrypting to something wrong.
  • Tokens are never shown in the interface, never sent to a browser, and never written to a log, a URL or an API response. A guard in the logging code drops any line that would carry one.
  • The images you upload sit in a private bucket on a path that begins with your workspace, and no other customer can read them. Two things hold that. A signed-in session can only reach paths under its own workspace. And the server, whose own key is not bound by that rule, only reads an image or issues a link to one after it has checked the path against the workspace your session proved. The images are never served from a public URL: the link is short-lived, and it is issued when the builder shows them.
  • Data is stored in the EU, in Frankfurt.
  • We run no analytics, advertising or third-party tracking scripts on the site, so there is no fourth party collecting anything in the background.
  • Only Oaksmond's own people can reach the production database, and today that is one named person.

We have no security certification, no SOC 2 report and no ISO 27001. We would rather say that than imply one. If you need an audited supplier, we are not one yet.

Sub-processors

You give us a general written authorisation to use the sub-processors below, and to add or replace one on the notice set out in the next section.

Supabase (Supabase Inc.)
Database, authentication and file storage. Your data, the images included, is stored in the EU (eu-central-1, Frankfurt).
Vercel (Vercel Inc.)
Hosting for the website and the API. Requests may be routed through infrastructure outside the EU, which is covered under transfers below.

Two, and no others. Each is bound by terms that give them the same obligations we have towards you, and we remain answerable to you for what they do.

Meta is deliberately not on this list. You have your own agreement with Meta for your ad account, and Meta is an independent controller for what it does with the data inside it. When you create a campaign we send your text, your link and your images into your own ad account on your instruction, and Meta's own terms apply from that point. Our payment provider is not on the list either: it handles our billing of you, where we are the controller, and it never touches the data this agreement covers.

Telling you before the list changes

A sub-processor list without a notice obligation is a list that can change behind your back, so here is the obligation.

  • Before we add or replace a sub-processor we write to the email address on your workspace at least 30 days in advance. The notice says who they are, what they will do, and where the data will sit.
  • You can object on reasonable data protection grounds within those 30 days. We will either keep things as they are, or tell you honestly that we cannot and why.
  • If we go ahead over your objection, you can cancel the subscription with effect from the day the change takes effect, and we return the unused part of the period you have paid for.
  • If a sub-processor has to be replaced urgently, for instance because it stops operating or loses a certification, we can act on shorter notice. We will tell you as soon as we can, and say why the notice was short.

Transfers outside the EU

Your data is stored in the EU. One transfer can still happen: our host may route a request through infrastructure outside the EU on its way to the server. That transfer rests on the European Commission's standard contractual clauses, which form part of our agreement with the host.

We will not move the storage of your data outside the EU without telling you first under the notice obligation above, and we will not transfer it anywhere else on an instruction other than yours unless the law obliges us to. If a public authority ever demanded your data, we would tell you unless we were legally barred from doing so.

Helping you answer your own customers

If someone exercises a right against you and the answer sits in our product, write to us and we will help you find, correct, export or delete it. We aim to come back within 10 working days, and faster when a deadline of yours is closer than that.

We will not answer your customers directly. You are their controller, and a reply from us would come from the wrong party. If one of them writes to us by mistake we will tell them to write to you, and tell you that they did.

The same goes for a data protection authority: if one asks us about your processing, we will help you respond rather than respond for you.

If there is a breach

If we discover a personal data breach affecting your data we will tell you without undue delay, and at the latest 48 hours after we become aware of it. We will not wait until we understand it fully: the first message says what we know, and the rest follows as we learn it.

The message will say what happened, which categories of data and roughly how many records are involved, what we are doing about it, and what we think you should do. Reporting it to a data protection authority is your call, because you are the controller, and we will give you what you need to make it.

Audits, and what we will show you

We will answer your questions about this agreement in writing, including a security questionnaire, and that is usually enough.

If you need more, you can audit us once in any twelve-month period, on 30 days' written notice, at your own cost, at a time that does not disrupt the service, and under a confidentiality agreement. For the sub-processors we pass on whatever documentation they publish; we cannot let you audit them ourselves.

When you leave

When your subscription ends you keep read access for 90 days, as the terms of service describe. After those 90 days we delete your data. We write to the email address on your workspace once, at least 14 days before, and say which day it will happen.

You do not have to wait. Ask us to delete your data sooner, or to return it to you first, and we will do whichever you ask.

  • Deleting the workspace removes everything attached to it in the database in one operation: connections, ad accounts, campaigns, daily figures and campaign drafts.
  • The uploaded images sit in storage rather than in the database, so that one operation does not reach them. We delete them by hand as part of the same request, and nothing expires them on a timer in the meantime.
  • What Happyads created inside your own Meta ad account stays there. It is yours, we have no right to remove it, and we do not touch it when you leave.
  • Where the law requires us to keep something, for instance an invoice under the Danish bookkeeping act, we keep exactly that and nothing else, and it stays under our own controller obligations rather than this agreement.
  • The record of which version of this agreement and of the terms your company accepted is kept for five years after the agreement ends. It is detached from the workspace when the workspace is deleted, so we can read it and no other customer can. It is our own record of the agreement, held under our controller obligations.

We will confirm in writing when the deletion is done.

Liability

The liability section of the terms of service applies to this agreement too, with one carve-out that matters: it does not limit what either of us owes the other, or a data subject, under the data protection rules themselves. A cap cannot be written over article 82 of the GDPR, and we are not going to pretend otherwise.

Changes to this agreement

Any change gives this page a new version number, the one at the top. A change that affects your rights or our obligations is written to you at least 30 days before it applies, and we will tell you what changed rather than asking you to compare two documents.

Your earlier acceptance is not overwritten. Each version you accept is stored as its own record, with the time and a fingerprint of the text, so the history can be read backwards and a version number cannot come to mean two different documents.

Law and venue

Danish law applies to this agreement, and disputes belong before the Danish courts, the same as the terms of service.

Contact

Oaksmond ApS, CVR 43117785, Hovborgvej 1, 6623 Vorbasse, Denmark. privacy@happyads.so.