1. Parties and scope
1.1. This Data Processing Agreement (“DPA”) is between the customer that accepted the Pixelary Terms of Service (the “Customer”) and Oleksii Ukrainskyi, a sole proprietorship (jednoosobowa działalność gospodarcza) entered in the Polish business register CEIDG, ul. Ceramiczna 5c/58, 03-126 Warszawa, Poland, NIP 5242785728, REGON 521840030 (“Pixelary”). Contact for this DPA: hello@pixelary.app.
1.2. This DPA forms part of the Terms and applies whenever Pixelary processes personal data on the Customer’s behalf while providing the Service. The Customer accepts it together with the Terms. A signed copy is available on request to hello@pixelary.app.
1.3. This DPA does not cover data for which Pixelary is the controller: the Customer’s account, billing, team and support data, and Microsoft Clarity analytics in the dashboard. The Privacy Policy covers those.
1.4. Terms such as “controller”, “processor”, “personal data”, “processing”, “data subject”, “personal data breach” and “supervisory authority” have the meanings given in the GDPR.
2. Roles
2.1. The Customer is the controller of the personal data of visitors to its sites that the Service processes. Pixelary is the processor.
2.2. If the Customer runs Pixelary on sites it manages for its own clients, the Customer acts as a processor for those clients. Then Pixelary is the Customer’s sub-processor, the Customer passes on its clients’ instructions, and the Customer remains Pixelary’s only point of contact. The Customer must make sure that each client authorizes Pixelary and Pixelary’s sub-processors, by a general written authorization as in section 8.
2.3. Destinations are not sub-processors. Meta, TikTok and OpenAI (ChatGPT Ads) receive personal data because the Customer connects them to a site and gives Pixelary its access tokens. Pixelary sends them data on the Customer’s instruction, as the Customer’s chosen recipients. The Customer’s own agreements with these platforms govern their processing.
3. Description of the processing
The subject matter, duration, nature and purpose of the processing, the types of personal data and the categories of data subjects are set out in Annex 1.
4. Instructions
4.1. Pixelary processes the personal data only on the Customer’s documented instructions, including with regard to transfers to third countries, unless EU or Polish law requires otherwise; in that case Pixelary will tell the Customer before processing, unless that law forbids it (Art. 28(3)(a) GDPR).
4.2. The Customer’s documented instructions are: the Terms and this DPA; the settings the Customer and its team make in the dashboard, the Framer plugin and the Google Tag Manager template (sites, domains, destinations, triggers, consent defaults, site settings); and the calls the Customer’s sites make to the Pixelary script.
4.3. Pixelary will tell the Customer immediately if, in its opinion, an instruction infringes the GDPR or other EU or Member State data protection law.
5. The Customer’s obligations
5.1. The Customer is responsible for the lawfulness of the processing, in particular for:
- a legal basis for collecting the data and sending it to the destinations, including consent where Article 5(3) of Directive 2002/58/EC as implemented in national law, or the GDPR, requires it;
- a cookie banner or consent tool whose answer reaches the Pixelary script, and consent defaults on the Consent screen that suit the law that applies to its visitors (Annex 1, section 6);
- informing visitors under Articles 13 and 14 GDPR, including about Pixelary and the destinations;
- not sending special categories of personal data, data about criminal convictions, payment card numbers, government ID numbers or credentials, and not putting contact details in event names, event IDs, custom parameters or page addresses;
- its agreements with the destinations, and the access tokens it provides.
5.2. The Customer should move sites from the older Framer plugin tag (framer.js) to the current script. The older tag does not apply the consent handling described in Annex 1 (Annex 1, section 9).
6. Confidentiality
Pixelary ensures that every person it authorizes to process the personal data is bound by confidentiality, by contract or by law (Art. 28(3)(b) GDPR). Today only Oleksii Ukrainskyi has access to production systems and data. Any future staff or contractors with access will be bound by written confidentiality and data protection obligations.
7. Security
7.1. Pixelary implements the technical and organizational measures in Annex 2 (Art. 28(3)(c) and Art. 32 GDPR).
7.2. Pixelary may update these measures as technology and risks change, provided the overall level of protection does not decrease.
8. Sub-processors
8.1. The Customer gives Pixelary general written authorization to engage the sub-processors for website visitor data listed in the sub-processor list (Annex 3) (Art. 28(2) GDPR). Today these are Cloudflare and Supabase. The other providers on that page work only with data for which Pixelary is the controller (section 1.3).
8.2. Pixelary will tell the Customer about any intended addition or replacement of a sub-processor at least 30 days in advance, by email to the account owner and an update of https://pixelary.app/subprocessors. The Customer may object on reasonable data protection grounds within that period. If the parties cannot resolve the objection, the Customer may terminate the affected part of the Service before the change takes effect. Pixelary then refunds the prepaid fees for the terminated part, pro rata.
8.3. Pixelary imposes on each sub-processor, by contract, data protection obligations that offer at least the same level of protection as this DPA, in particular sufficient guarantees for appropriate technical and organizational measures (Art. 28(4) GDPR). Where a sub-processor offers only its standard terms, Pixelary relies on those terms. Each sub-processor processes personal data under its data processing terms (Cloudflare’s Customer Data Processing Addendum and the Supabase DPA), which impose obligations equivalent to those in Art. 28(3) and (4) GDPR. Annex 3 lists them.
8.4. Pixelary remains responsible to the Customer for the performance of its sub-processors’ obligations.
9. International transfers
9.1. Pixelary stores the database in the EU (Supabase, AWS region eu-west-1, Ireland) and the per-site event log in Cloudflare Durable Objects created with EU jurisdiction.
9.2. Some processing takes place outside the EEA: Cloudflare handles each request at the data center nearest to the visitor, which can be outside the EEA; cached site configuration in Cloudflare Workers KV and counters in Workers Analytics Engine are not limited to the EU; and some sub-processors are US companies. Annex 3 lists the locations.
9.3. For each transfer outside the EEA, Pixelary relies on an adequacy decision (including the EU-U.S. Data Privacy Framework for certified recipients) or on the Standard Contractual Clauses adopted by Commission Implementing Decision (EU) 2021/914. For transfers of the Customer’s visitor data to sub-processors outside the EEA where the Data Privacy Framework does not apply, Module 3 (processor to processor) of those clauses applies.
10. Assistance
10.1. Data subject requests. Taking into account the nature of the processing, Pixelary assists the Customer by appropriate technical and organizational measures in responding to requests from data subjects (Art. 28(3)(e) GDPR). Pixelary stores contact details only as hashes and does not store IP addresses, so it can usually find a person’s data only by event ID or by the hash of a known value. If a data subject contacts Pixelary directly about a Customer’s site, Pixelary will pass the request on to the Customer without undue delay and will not answer it on its own unless the Customer instructs it to.
10.2. Other obligations. Pixelary assists the Customer with its obligations under Articles 32 to 36 GDPR (security, breach notification, data protection impact assessments and prior consultation), taking into account the nature of the processing and the information available to Pixelary (Art. 28(3)(f) GDPR).
10.3. Reasonable assistance is free. Requests that need substantial work beyond what the dashboard offers may be charged at cost, after Pixelary tells the Customer the estimate.
11. Personal data breaches
11.1. Pixelary notifies the Customer without undue delay, and in any case within 48 hours, after becoming aware of a personal data breach affecting the Customer’s personal data.
11.2. The notification describes, as far as known: the nature of the breach, the categories and approximate number of data subjects and records concerned, the likely consequences, the measures taken or proposed, and a contact point. Pixelary provides missing information as soon as it has it.
11.3. Notification is sent to the account owner’s email address. The Customer may name a separate security contact by writing to hello@pixelary.app.
12. Deletion and return
12.1. At the end of the Service, Pixelary deletes the personal data processed for the Customer, unless EU or Polish law requires storage (Art. 28(3)(g) GDPR). The Customer can export the event log as CSV from the dashboard before the end; Pixelary does not keep another copy to return.
12.2. How deletion works today:
- the Customer can delete a site or the whole account in the dashboard at any time. Deletion is immediate: it removes the site’s configuration, destinations, access tokens, triggers and domains in Supabase, the cached configuration, and the site’s event log, counts and install data in its Durable Object. An account can be deleted once no subscription of it renews. On request by email to hello@pixelary.app, Pixelary does the same within 30 days of the request or of the end of the contract;
- event log entries are deleted automatically by a daily job once they are older than their retention period (Annex 1, section 7), so all entries are gone no later than that period after the last event;
- hourly counts and “where the script runs” records are deleted after 90 days;
- delivery errors for Meta and TikTok in Supabase are deleted by a daily job after 30 days, and with the site;
- Where the Supabase plan in use includes backups, they expire within 7 days, and deleted data disappears from them then.
12.3. Counts that identify no person (for example the number of events per month) may be kept. These counts contain no identifiers and are not personal data.
13. Information and audits
13.1. Pixelary makes available to the Customer the information necessary to demonstrate compliance with Article 28 GDPR, and allows for and contributes to audits, including inspections, by the Customer or an auditor it mandates (Art. 28(3)(h) GDPR).
13.2. The Customer first sends its questions in a written questionnaire, which Pixelary answers. An audit takes place at most once in 12 months, unless it follows a personal data breach or a supervisory authority orders it. The Customer gives at least 30 days’ notice. The audit is carried out by an independent auditor bound by confidentiality, at the Customer’s cost. Pixelary may rely on its sub-processors’ certifications and reports (for example Cloudflare’s ISO 27001 certification and SOC 2 report, and Supabase’s SOC 2 report).
14. Requests from authorities
If an authority asks Pixelary for the Customer’s personal data, Pixelary will refer it to the Customer where possible, tell the Customer unless the law forbids it, and disclose only what it is legally required to.
15. Liability and precedence
15.1. The liability cap in the Terms (section 16) applies to this DPA, without prejudice to Art. 82 GDPR towards data subjects.
15.2. If this DPA conflicts with the Terms, this DPA prevails on data protection matters. If the Standard Contractual Clauses apply, they prevail over this DPA.
15.3. This DPA applies as long as Pixelary processes personal data for the Customer. It is governed by the same law as the Terms (Polish law).
Annex 1. Description of the processing
1. Categories of data subjects
- Visitors to the Customer’s sites where the Pixelary script runs.
- People whose details reach the script on those sites: people who submit forms, book through embedded tools (for example Calendly, Cal.com, HubSpot, Tally, Typeform), arrive on thank-you pages with their details in the address, or whom the Customer’s code or Google Tag Manager identifies (for example logged-in customers).
- The Customer’s own users, when the Customer sends a test event from the dashboard (their IP address and user agent go to the chosen destination).
2. Types of personal data
Depending on the Customer’s configuration and its visitors’ consent:
| Type | Details | Leaves the browser |
|---|---|---|
| Contact and identity details, hashed | Email, phone, first name, last name, city, postal code, country, external ID (including the Pixelary visitor ID or the Customer’s own visitor cookie), each normalized and hashed with SHA-256 in the browser, separately for each destination | Only with ad_user_data granted. Server copies: Meta receives email, phone, first and last name and external ID; TikTok email, phone and external ID; OpenAI email, phone, first and last name and external ID. City, postal code and country hashes reach Pixelary’s servers but are not forwarded today. In the browser, only the ChatGPT Ads pixel receives hashes |
| Online identifiers | _fbp, _fbc, _ttp, ttclid, __oppref, __obref; the fbclid and ttclid click IDs | Only with ad_storage granted; removed by Pixelary’s servers otherwise |
| Network data | IP address and user agent of the visitor’s request; the country and network (ASN) that Cloudflare derives from the IP address | IP address and user agent are forwarded to the destinations with each server event, not stored. Country and ASN are used for the consent and bot rules; the country is also stored in free-plan session counters |
| Event data | Event name and ID, time, page address and referrer (with personal query parameters removed), trigger type, value, currency, product IDs, order ID and custom parameters set by the Customer | Yes |
| Consent and technical signals | The four Consent Mode states, which consent tool was found, whether each browser pixel loaded, automation signals, the script version and install method, other pixel IDs and Pixelary tags on the page, script load time | Yes |
Special categories of personal data: none. The Customer must not send them (section 5.1).
3. Nature of the processing
- In the browser (the Pixelary script, delivered from Pixelary’s servers with the Customer’s public settings): reading the page, forms, embedded tools, address parameters, cookies and consent signals as configured; holding events in memory until consent allows them; normalizing and hashing contact details; removing personal parameters from addresses; loading the destinations’ browser pixels and sending events to them; setting the cookies and storage listed in section 8.
- On Pixelary’s servers: receiving server copies (paid plans) and session summaries (free plan); checking the site key, the request’s domain, the visitor’s country and consent, automation signals and the fair-use limit; forwarding events to the destinations with the Customer’s tokens; writing the event log, counts and install information; deleting data on schedule.
4. Purpose
To deliver the Customer’s conversion events to the destinations it chooses, with one event ID for the browser and server copies, and to show the Customer delivery status, an event log, counts and installation checks. Also to apply the visitors’ consent, filter automated traffic and enforce the fair-use limit.
5. Duration and frequency
Continuous, for as long as the Customer uses the Service, plus the retention periods in section 7.
6. Consent handling (summary)
ad_storagecontrols whether the browser pixels load and whether advertising cookies are read or written;ad_user_datacontrols whether contact details or hashes are sent and whether a server copy is sent;ad_personalizationis passed to Pixelary’s servers and sets OpenAI’sopt_outwhen denied (no equivalent signal is sent to Meta or TikTok);analytics_storagecontrols the free-plan session summary.- Before a visitor answers: when the visitor’s IP country (reported by Cloudflare when the script is delivered) or the browser’s time zone is in the EEA, the UK or Switzerland, the script waits; elsewhere consent counts as granted unless the site’s banner, its Consent Mode defaults, the Customer’s defaults on the Consent screen or the visitor’s Global Privacy Control say otherwise. Waiting events are kept only in the page’s memory and are dropped if the visitor declines or leaves.
- On sites that use IAB TCF, the script reads the purpose consents (purposes 1, 3, 4 and 7) only. Pixelary is not a registered TCF vendor and checks no vendor consent.
- Pixelary’s servers drop a server event from the EEA, the UK or Switzerland (by the country Cloudflare derives from the IP address) unless
ad_user_datawas granted, and drop advertising cookie IDs unlessad_storagewas granted.
7. Retention
| Data | Location | Retention |
|---|---|---|
| Event log (paid plans): event name and ID, times, status and reason, trigger type, page path and query without host, consent state, pixel results, automation signals, names of the matching fields sent (not their values), destination responses, custom data with email addresses and international phone numbers masked | Cloudflare Durable Object per site, EU jurisdiction | 30 days on the 1-site and 5-site plans, 90 days on the 10-site plan; deleted daily |
| Hourly counts by event name, status, pixel result, destination result and trigger type | Same | 90 days |
| Where the script runs: hostname, staging flag, first and last seen, script version, install method, consent tool, load time, extra copies | Same | 90 days after last seen |
| Install check: other pixel IDs on the page, old tags, extra copies, embedded tools | Same | Latest report; embedded tools 30 days after last seen |
| Monthly server event count per site | Same | About 12 months |
| Per-visitor rate counter (8-byte hash of IP address and user agent) | Memory of the Durable Object | At most one minute; never written to storage |
| Delivery errors for Meta and TikTok: site, platform, event name, the destination’s error text (which includes the event ID and pixel ID), time | Supabase, eu-west-1 | 30 days, deleted daily; also deleted with the site |
Aggregate counters and free-plan session summaries (site key, event name, status, destination result, pixel result, script version, install method, consent tool, ad_storage answer, conversion names, country) | Cloudflare Workers Analytics Engine | 3 months |
| Site configuration with access tokens (cache) | Cloudflare Workers KV | 5 minutes |
| IP address and user agent | Not stored by Pixelary | — |
8. Cookies and storage the script sets on the Customer’s sites
| Name | Type | Content | Lifetime | Condition |
|---|---|---|---|---|
_pxl_vid | Cookie | Random visitor ID, sent hashed as external ID | 390 days | ad_storage and ad_user_data granted, visitor ID setting on (default), when matching data is prepared for a server copy or the ChatGPT Ads pixel |
_fbc | Cookie | Meta click ID from fbclid | 90 days | ad_storage granted, fbclid in the address, no _fbc yet |
ttclid | Cookie | TikTok click ID | 90 days | ad_storage granted, ttclid in the address |
pixelary_user | Local storage | Hashed contact details per destination, from earlier pages | Until cleared | Sites with server-side delivery, ad_storage and ad_user_data granted |
pixelary_t_<trigger ID> | Local or session storage | 1: a once-per-visitor or once-per-session trigger fired. No identifier | Until cleared / session | When such a trigger fires, before the visitor’s consent answer, so that the same trigger is not counted twice |
pixelary_beacon | Session storage | 1: session summary sent | Session | Free plan, analytics_storage granted |
The destinations’ browser pixels set their own cookies once loaded.
9. The older Framer plugin tag (framer.js)
Sites still running the older tag are processed differently: the tag loads the Meta and TikTok pixel scripts on page load without waiting for consent; it treats tracking as allowed unless the site calls ft.setConsent(false); it sets ft_external_id (random ID, 2 years) and _fbc (2 years) and keeps ft_pv in session storage; it hashes email, phone, first and last name in the browser but passes ft_external_id and the full page address to the destinations as they are; and Pixelary’s servers forward its events to Meta and TikTok without the country check in section 6. Its delivery errors are stored in Supabase as in section 7. It has no event log.
Annex 2. Technical and organizational measures
A. Data minimization and pseudonymization
- Contact details are normalized and hashed with SHA-256 in the visitor’s browser, separately for each destination, before they leave the page.
- Pixelary’s servers accept contact fields only as 64-character hexadecimal hashes and discard any other value.
- The script and the servers remove query parameters that carry personal data from page and referrer addresses: known names (email, phone, name and their variants in several languages) and any value that looks like an email address. On thank-you pages, the parameters the Customer maps to contact fields are also removed from the address bar before any browser pixel loads.
- Form fields other than the recognized contact fields are read only in the browser, to check trigger conditions, and are not transmitted. Password and file fields are skipped.
- The event log stores no contact details and no IP addresses: only the names of the matching fields sent, the page path without the host, and custom data with email addresses and international phone numbers masked.
- IP addresses and user agents are passed through to the destinations and not stored. The rate limit uses an 8-byte hash of IP address and user agent, kept in memory for one minute.
- Without
ad_user_data, no contact data and no server copy leave the browser; withoutad_storage, no advertising cookie is read or written and the browser pixels do not load. The servers enforce the EEA, UK and Swiss rule again by country and strip cookie IDs sent withoutad_storage.
B. Storage location
- Database: Supabase, AWS region eu-west-1 (Ireland). Event log, counts and install information: Cloudflare Durable Objects with EU jurisdiction.
C. Access control
- Customers reach their data only through the dashboard, the Framer plugin and Pixelary’s API, after signing in with Supabase Auth (Google or an email code). Pixelary’s servers validate each session token (by its signature, or with Supabase Auth) and check, on every request, that the site belongs to the signed-in account.
- Row-level security is enabled on the database tables, so customers’ browsers can read and change only their own rows. The dashboard writes settings only through Pixelary’s servers; the older Framer plugin writes its own configuration columns directly, under the same row-level rules.
- Access tokens and API keys are stored in separate tables with row-level security and no access policies; the roles used by browsers have no rights on them, so only Pixelary’s server, with the service key, can read them. The API never returns a token, only whether one is present.
- Billing fields cannot be changed from customers’ browsers (database grants and a protecting trigger); only Pixelary’s servers and the billing webhook change them.
- Moving a site to another account is refused while the site has tokens, an active subscription or delivery errors recorded in the last 30 days.
- Only Oleksii Ukrainskyi holds administrator access to Cloudflare, Supabase, Lemon Squeezy, Mailgun, Google and the code repository. Two-factor authentication is used on these accounts. Pixelary’s own keys and tokens are kept as encrypted secrets in Cloudflare, never in the code repository, and are rotated when a compromise is suspected or a person with access leaves.
D. Encryption
- Connections from the script, the dashboard and the plugin to Pixelary’s servers, and from Pixelary’s servers to Supabase and the destinations, use HTTPS.
- Supabase and Cloudflare encrypt stored data at rest (AES-256, according to their documentation), including Durable Objects and Workers KV. Access tokens and API keys are additionally encrypted by Pixelary (AES-256-GCM) with a key kept only in the server’s secrets, so a copy of the database or a backup holds no usable token. To deliver events, the servers cache the decrypted configuration for up to 5 minutes in Workers KV.
- Tokens are sent to the destinations only over HTTPS: to Meta as the
access_tokenparameter of the Graph API request, to TikTok in theAccess-Tokenheader, to OpenAI in theAuthorizationheader. Pixelary’s code does not write tokens to logs or error messages.
E. Input control and integrity
- Events are accepted only from the domains registered for the site (
OriginorRefererheader). Events from staging domains are sent to the destinations only in test mode. - Requests are validated and limited in size (100 KB and 50 events per batch; 8 KB per session summary); unknown fields are dropped.
- Billing webhooks from Lemon Squeezy are verified with an HMAC signature.
- Automated traffic is filtered: crawler and HTTP-library user agents, browsers reporting automation, filled anti-spam form fields, PageView and ViewContent events from cloud and hosting networks, and more than 60 events per minute from one visitor.
F. Retention and deletion
- A daily job in each site’s Durable Object deletes event log entries older than the retention period, counts and “where the script runs” records older than 90 days, and monthly counts older than about 12 months. A daily job in Supabase deletes delivery errors older than 30 days. Cached configuration in Workers KV expires after 5 minutes; plugin sign-in handoff tokens after 10 minutes.
G. Availability and resilience
- The servers run on Cloudflare’s network; the database runs on Supabase. Where the Supabase plan in use includes backups, they expire within 7 days, and deleted data disappears from them then.
- The Service has no SLA (Terms, section 11).
H. Organization
- Incidents are detected from Cloudflare and Supabase monitoring, from delivery-error rates in the Service and from customers’ reports. Each incident is recorded in an incident register (Art. 33(5) GDPR) with the facts, its effects and the measures taken. Oleksii Ukrainskyi decides on notifications to customers and to the supervisory authority.
- Every change passes automated tests (consent rules, event intake, database migrations), type checks and lint before release. Database migrations are tested in a rolled-back transaction on production data before they are applied. Each release keeps the previous version for rollback. Dependencies are reviewed and updated at least monthly.
- Confidentiality of personnel: section 6.
Annex 3. Sub-processors
The current list, with each sub-processor’s purpose, data and location, is published at https://pixelary.app/subprocessors.