Record of processing activities (UK GDPR Article 30)
Derived from src/lib/data-class-register.ts and src/lib/subprocessors.ts, which are the files the serving gate and the verification rotation read at runtime. A hand-written record describes what someone believed the system did on the day they wrote it; this one cannot describe processing the code does not do, and CI fails when the two diverge.
Controller
SiteLens, a UK planning intelligence service. Contact: privacy@sitelens.co.uk.
We are a controller for everything below, and not a processor for our customers: we decide what to collect and why, so there is no Article 28 processor relationship with a subscriber and no data processing agreement is owed to one.
The Article 30(5) derogation does not apply
Article 30(5) exempts an organisation with fewer than 250 staff unless the processing is not occasional. A nightly scrape of several hundred planning portals is not occasional, so this record is required.
Purposes of processing
To publish and index UK planning applications, building control records and public procurement notices, and to identify which firms are named on them, so that construction suppliers and subcontractors can find live projects and the firms running them.
We index property and schemes, never people. There is no reverse lookup by person name, and there is no send path, dialler, template store, reply capture or audience builder for any electronic channel: our customers do their own outreach by email and telephone, and on those channels we are never the sender, the instigator or the caller.
Post is the one exception, and it is narrow and not yet offered. A path to send a printed letter to the applicant at the application site, fulfilled through Stannp, our Article 28 processor for print and post, is built but runs in Stannp's test mode and dispatches nothing. No customer can send a letter today. When it goes live we are the CONTROLLER of the corpus and the targeting tooling; the customer decides who to write to and what the letter says, and remains the marketer for CAP Code purposes. Sequential controllers, so no data processing agreement is owed to a subscriber. The path carries no email address and no telephone number by construction, so it is outside PECR reg 22 entirely, and every letter will carry an Article 14 notice clause and an objection route that suppresses the recipient across every customer.
Categories of personal data (37 classes)
| Class | Description | Tier | Channel | Lawful basis | Retention | Art 14 notice |
|---|---|---|---|---|---|---|
| H30 | An applicant's own published email and phone, split by subscriber type | T2 | electronic | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H33.ip | Requesting IP address and user agent recorded against an email open | T0 | none | None: acquisition prohibited | Not retained: prohibited | Not owed |
| H17.notes | Free-text notes against one of our own outbound prospects | T0 | none | None: acquisition prohibited | Not retained: prohibited | Not owed |
| H10 | A planning agent's or firm's published business contact channel | T2 | electronic | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H10.addr | A party's postal address as published on the register | T2 | postal | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H1 | A named party on a planning application or appeal: applicant, appellant, agent, or the firm they act for | T3 | none | Legitimate interests, Art 6(1)(f) | Retained while the record naming the person is retained. On an application, the name is part of the public planning record and removing it would misstate who applied. On an appeal, retention follows the Inspectorate's own publication window rather than ours: the loader full-replaces pins_appeals from each quarterly release, so a case that falls out of that rolling five-year window of decided cases leaves our table with it. | Owed |
| H2 | The council case officer named on an application | T3 | none | Legitimate interests, Art 6(1)(f) | Retained while the application record is retained. | Not owed |
| H7.contact | The case officer's published email and telephone, for case correspondence only | T2 | electronic | Legitimate interests, Art 6(1)(f) | Retained while the application record is retained. The value is only meaningful in the context of the case it belongs to, so it has no life of its own to time out. | Not owed |
| H15 | Email deliverability verdict from a verification provider | T4 | none | Legitimate interests, Art 6(1)(f) | 1 year | Not owed |
| H16 | Our own subscriber-type classification of a party | T4 | none | Legitimate interests, Art 6(1)(f) | Recomputed on read; not a stored fact with its own clock. | Not owed |
| PV1 | Field-level provenance: which source a stored value came from | T4 | none | Legitimate interests, Art 6(1)(f) | Retained for as long as the value it describes. Deleting the provenance while keeping the value would leave a value we cannot account for, which is the opposite of the intended effect. | Not owed |
| H17 | One of our own outbound prospects | T5 | electronic | Legitimate interests, Art 6(1)(f) | 1 year | Owed |
| H29 | A suppression, objection or complaint record | T5 | none | Legal obligation, Art 6(1)(c) | Permanent by design. A suppression record is the only thing that makes a suppression survive re-acquisition, so deleting it on erasure would silently re-admit the person. A complaint record is permanent for the mirror-image reason: it is the proof that we acknowledged and answered, and DPA 2018 s.164B makes that provable rather than asserted. | Not owed |
| H33 | Proof that a notice or email was sent: recipient hash, date, notice version | T5 | electronic | Legal obligation, Art 6(1)(c) | Retained as the proof-of-notice record. Article 14 compliance is unprovable without it, so it is retained through a suppression event rather than deleted with the contact. | Not owed |
| H33.post | Proof that a letter was dispatched: which application, which sender, cost, notice version | T5 | postal | Legal obligation, Art 6(1)(c) | Retained as the proof-of-dispatch record for as long as the application it refers to is retained, and deleted with it. Article 21 compliance is unprovable without it: it is the only evidence of which letters were sent, when, and under which version of the notice clause, which is what answers an objection or a complaint about one. | Not owed |
| H12 | A business premises' published contact details from a places dataset | T2 | electronic | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H14 | A named individual at a firm, with their role and work contact details | T2 | electronic | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H20 | A registered proprietor of a commercial title, and a business rates ratepayer | T3 | postal | Legitimate interests, Art 6(1)(f) | 1 year | Owed |
| H21 | A supplier contact point on an awarded public contract | T2 | electronic | Legitimate interests, Art 6(1)(f) | 2 years | Owed |
| H38 | A supplier named on a public procurement notice: the awarded supplier, and each unsuccessful supplier a contract award notice names | T4 | none | Legitimate interests, Art 6(1)(f) | Retained while the tender record it was published on is retained. The name is part of the published contract award notice, and removing it would misstate who won or who bid; an unsuccessful supplier row is deleted with its tender row (ON DELETE CASCADE). No contact channel of any kind is stored against an unsuccessful supplier, and only a name carrying a Companies House number on the notice or passing the business-identity gate is held, so a stale row is a stale bid attribution rather than a stale route to a person. | Owed |
| H8 | A design-team firm named in an application's documents: architect, main contractor, structural engineer, quantity surveyor, M&E consultant | T3 | none | Legitimate interests, Art 6(1)(f) | Retained while the application record naming the firm is retained. The name is part of what the published documents say about who designed or is building the scheme. | Owed |
| H9 | A company officer as Companies House lists them: name, role, appointment date, occupation and nationality | T3 | none | Legitimate interests, Art 6(1)(f) | Held with the company profile, which has no deletion job. The list is replaced when the profile is refreshed from Companies House, by the enricher and by scripts/refresh-company-profiles.ts for profiles older than 365 days, so an officer who has resigned drops out at the next refresh. | Owed |
| H39 | A person with significant control as Companies House lists them: name, kind, nature of control, notification date, nationality and country of residence | T3 | none | Legitimate interests, Art 6(1)(f) | Held with the company profile, which has no deletion job. The list is replaced when the profile is refreshed from Companies House, by the enricher and by scripts/refresh-company-profiles.ts for profiles older than 365 days, so a person who has ceased to have control drops out at the next refresh. | Owed |
| H32 | A customer's own searches and saved-alert locations: typed search text, applied filters, the last place searched and the filters of each export | T5 | none | Legitimate interests, Art 6(1)(f) | Held for the life of the customer's account and deleted with it; no shorter clock runs on any of it. The digest ranking reads only the last 60 days of searches. | Not owed |
| H42 | Answers a customer or visitor gives to one of our surveys, and our own notes classifying a signup | T5 | none | Legitimate interests, Art 6(1)(f) | A survey answer is kept when the account is deleted, with its link to the account removed (survey_responses.user_id is set to NULL), and a customer's dormant-account answer replaces their previous one. A signup classification is deleted with the account. | Not owed |
| H37 | A rate-limit key: a visitor's IP address, or our own id for a customer or an API key | T5 | none | Legitimate interests, Art 6(1)(f) | A key is pruned once it is older than ten minutes, but only when an allowed request happens to trigger the prune (about one in a thousand), so on a quiet route a key can outlive ten minutes; there is no scheduled sweep. | Not owed |
| H34 | Our own customers: account, plan, billing state | T5 | electronic | Contract, Art 6(1)(b) | Retained for the life of the account, then per the retention schedule. | Not owed |
| H35 | Abandoned registrations: unconfirmed Cognito signups | T5 | electronic | Contract, Art 6(1)(b) | 90 days | Not owed |
| BC0 | A building control enforcement case: an alleged offence and the person alleged to have committed it | T0 | none | None: acquisition prohibited | Not retained: prohibited | Not owed |
| BC1 | A building control agent's or builder's name as published on the register | T3 | none | Legitimate interests, Art 6(1)(f) | Retained while the building control record is retained. The name is only meaningful as the party on that case, so it has no life of its own to time out. | Owed |
| BC2 | An approved inspector's name and published practice contact point | T3 | telephone | Legitimate interests, Art 6(1)(f) | Retained while the building control record is retained. The practitioner is only recorded as the approver on that case. | Owed |
| P21 | The operator or applicant named on a DESNZ energy project register (REPD renewables, HNPD heat networks) | T4 | none | Legitimate interests, Art 6(1)(f) | Held for as long as the project is on the register and NOT deleted when the publisher removes it: the loader upserts on (source, ref_id) and never deletes, so a withdrawn project keeps its last-known row. There is deliberately no reconciliation sweep yet, because the value names an operating organisation and no contact channel for it is stored, so a stale row is a stale project attribution rather than a stale route to a person. Adding a contact channel to this table would make a reconciliation mandatory and require this criterion to be rewritten first. | Not owed |
| P20 | The connection customer named on a DNO Embedded Capacity Register | T4 | none | Legitimate interests, Art 6(1)(f) | Held for as long as the connection is on the register and NOT deleted when the publisher removes it: the loader upserts on (dno, dataset_id, register_id) and never deletes, so a withdrawn connection keeps its last-known row. No reconciliation sweep is run, because the stored value names a business and no contact channel for it is stored, so a stale row is a stale connection attribution rather than a stale route to a person. A publisher redaction is preserved forever and is never repaired from any other source. | Not owed |
| P51 | The lead and developing organisations named on a Homes England Affordable Homes Programme grant confirmation | T4 | none | Legitimate interests, Art 6(1)(f) | Held as an annual SNAPSHOT keyed on the publication's as-at date, so nothing is ever silently overwritten and no row can be read without its age being visible. Not deleted when a later publication drops a scheme, because the earlier snapshot remains a true statement about what was confirmed at that date. No contact channel is stored, so a stale row is a stale grant attribution rather than a stale route to a person. | Not owed |
| P52 | The operator named on an Environment Agency U1 waste exemption registration | T4 | none | Legitimate interests, Art 6(1)(f) | Held while the registration is on the public register and for as long after as the site fact remains a true statement about that site. Not deleted when a registration expires, because an expired exemption is still evidence that waste was deposited there. Only names that passed the business-identity gate are held at all, and no contact channel of any kind is stored, so a stale row is a stale site fact rather than a stale route to a person. | Not owed |
| P53 | The connection customer named on the NESO Transmission Entry Capacity (TEC) register | T4 | none | Legitimate interests, Art 6(1)(f) | Held for as long as the project is on the register and NOT deleted when the publisher removes it: the loader upserts on the composite row_key and never deletes, so a withdrawn connection keeps its last-known row. There is deliberately no reconciliation sweep, because only names that passed the business-identity gate are held at all and no contact channel of any kind is stored, so a stale row is a stale project attribution rather than a stale route to a person. Adding a contact channel to this table would make a reconciliation mandatory and require this criterion to be rewritten first. | Not owed |
| P54 | A domestic EPC's dwelling address line, held to join a sale price to a floor area | T3 | postal | Legitimate interests, Art 6(1)(f) | Held for as long as the certificate is the current EPC row for the dwelling. epc_records is truncated and fully reloaded from the register bulk download by scripts/load-epc.ts and there is no incremental path, so a certificate the register withdraws leaves our copy at the next reload rather than being deleted on a clock. No contact channel of any kind is stored alongside it and the table has no person column. | Not owed |
Stores outside the database
The column-derived CI gate cannot see these. They are declared on the class instead, and their retention is enforced by a named control rather than by a schema sweep.
| Class | Store | Retention |
|---|---|---|
| H35 | cognito:eu-west-2_5gVyJujg3 (status UNCONFIRMED) | 90 days |
Sources and licences
Not published on this page, because it names every supplier in our data stack. Ask privacy@sitelens.co.uk if your review needs it.
Prohibited classes (3)
These are recorded because a record that lists only what we hold cannot show that a decision was made about what we refuse to hold. Each is dropped at the parser before persistence, not filtered on the way out.
| Class | Description | Dropped at |
|---|---|---|
| H33.ip | Requesting IP address and user agent recorded against an email open | src/api/market-pulse-tracking.ts (write site) plus migration 0195 (row sweep) |
| H17.notes | Free-text notes against one of our own outbound prospects | src/lib/lead-engine/suppression.ts plus migration 0195 (row sweep; both columns measured at 0 rows) |
| BC0 | A building control enforcement case: an alleged offence and the person alleged to have committed it | Two halves. Structural: the descriptors in src/scrapers/idox-search-request.ts never request an enforcement search type, so the portal is not asked. Defensive: dropProhibitedRecords() in src/lib/building-control.ts drops any enforcement row that arrives inside a building control result set anyway, before persistence, and is mutation-checked in src/__tests__/lib/building-control.test.ts. |
Categories of recipient (Art 30(1)(d))
Categories: infrastructure, email_delivery, payments, analytics, postal_fulfilment, ai_processing, email_verification, web_search, contact_data, register_lookup.
There are 3 email-verification providers, which is the number the Article 14 notice states. It was sixteen; a list of sixteen verification vendors is not a disclosure a recipient can read or a buyer can accept, and the rotation now rejects an unapproved provider in code rather than by convention.
| Recipient | Category | Purpose | Classes | Location | Third-party data |
|---|---|---|---|---|---|
| Amazon Web Services | infrastructure | Cloud hosting, database, object storage and email sending (SES) | H1, H10, H10.addr, H12, H14, H15, H17, H20, H21, H29, H33, H34, H38, PV1, P1, P2 | United Kingdom (eu-west-2) | Yes |
| Amazon SES (contact-ops stream) | email_delivery | Delivery of the Article 14 transparency notice, on an isolated identity and configuration set so a notice pause can never take down customer digests | H14, H33 | United Kingdom (eu-west-2) | Yes |
| Stripe | payments | Subscription billing and payment processing | H34 | United States, under the UK Addendum to the EU SCCs | No |
| PostHog | analytics | Product analytics for our own customers | H34 | European Union | No |
| Stannp | postal_fulfilment | Print and postal fulfilment for a planned feature that is not yet offered: a letter from a customer to an applicant at an application site. The integration is built but runs in Stannp's test mode, which prints and posts nothing, and no page in the product sends a letter. A test request carries the same fields as a live one, and test requests made with real rows have already reached Stannp. Stannp receives the applicant name, the site address and the letter body, which is the customer's own text. The postal path never selects the applicant's email address or telephone number | H1, P1 | United Kingdom for print and fulfilment; EEA/EU for storage (Stannp DPA s.7). Onward: Royal Mail, Royal Mail PAF, Whistl, Sagacity | Yes |
| Anthropic | ai_processing | AI classification, and extraction of business information from published sources. Also processes search queries typed by customers and inbound email | P1, H1, H10, H10.addr, H14, H34, H32, H42 | United States, under the UK Addendum to the EU SCCs | Yes |
| Zoho Mail | infrastructure | Hosts the business mailbox: customer correspondence and anything the public sends in, including opt-out requests and complaints | H34, H29 | European Union (Zoho Mail EU datacentre) | Yes |
| MyEmailVerifier | email_verification | Confirms whether a published business email address still accepts mail | H15 | United States, under the UK Addendum to the EU SCCs | Yes |
| NeverBounce | email_verification | Confirms whether a published business email address still accepts mail | H15 | United States, under the UK Addendum to the EU SCCs | Yes |
| Reoon | email_verification | Confirms whether a published business email address still accepts mail | H15 | United States, under the UK Addendum to the EU SCCs | Yes |
| Tavily | web_search | Web search: a firm or supplier name is sent as a query to find the firm's own website | H1, H8, H38 | United States (AlphaAI Technologies Inc. d/b/a Tavily, New York); its privacy policy relies on the EU SCCs and UK Addendum for transfers | Yes |
| SerpApi | web_search | Web search: a firm or supplier name is sent as a query to find the firm's own website | H1, H8, H38 | United States (SerpApi, LLC, Austin, Texas) | Yes |
| Serper | web_search | Web search: a firm or supplier name is sent as a query to find the firm's own website | H1, H8, H38 | Not published: the provider names no entity or country, says it "operates globally" and relies on the EU SCCs for transfers out of the EEA | Yes |
| Brave Search | web_search | Web search: a firm or supplier name is sent as a query to find the firm's own website | H1, H8, H38 | United States (Brave Software Inc., San Francisco); the Search API's processing location is not published | Yes |
| Wikidata (Wikimedia Foundation) | web_search | Entity search: a firm or supplier name is looked up to find the firm's official website | H1, H8, H38 | United States (Wikimedia Foundation, San Francisco; US data centres) | Yes |
| A web-fetching service (named on request) | infrastructure | Web fetching: retrieves public council planning pages, planning documents and firm websites for us where a site refuses direct requests, and sees their content in full | P1, H1, H2, H8, H10, H10.addr, H14, H30 | Ireland (the processor); its hosting providers and their countries are not published, and it relies on the EU SCCs for transfers out of the EEA | Yes |
| OpenStreetMap Foundation (Nominatim) | infrastructure | Geocoding: a place a customer types into search, or an application site address the other geocoders cannot place, is sent to be turned into map coordinates | P1, H32 | United Kingdom and the Netherlands, with backups in the EU (OpenStreetMap Foundation privacy policy) | No |
| Hunter | contact_data | Contact-data lookup, only when a subscriber asks for a firm's contacts: a company director's name and the firm's web domain are sent to find a published business email address | H9 | United States (Hunter Web Services, Inc., Delaware); its servers are in Belgium, and it relies on the EU SCCs and the UK International Data Transfer Agreement for transfers | Yes |
| Apollo | contact_data | Contact-data lookup, only when a subscriber asks for a firm's contacts: a company director's name, the company name and, where known, the firm's web domain are sent to find a business email address | H9 | United States (ZenLeads, Inc. d/b/a Apollo.io, California); relies on the EU SCCs and the UK Extension to the EU-US Data Privacy Framework | Yes |
| Companies House | register_lookup | Register lookup: an applicant, agent, design-team firm or tender supplier name is searched on the company register to match a company, and company numbers are sent to fetch its officers and persons with significant control | H1, H8, H38, P2 | United Kingdom (Companies House, an executive agency of the Department for Business and Trade) | Yes |
| A professional body's member directory (named on request) | register_lookup | Directory lookup: a quantity surveying firm's name, as an application's documents give it, is sent to the member directory to find the firm's published office contact details | H8 | United Kingdom (London); the body says it may share data with its offices worldwide | Yes |
| A professional body's practice directory (named on request) | register_lookup | Directory lookup: an architect firm's name, as an application's documents give it, is sent to the practice directory to find the practice's canonical name and address | H8 | United Kingdom (London); the body says it may store data outside the UK or EEA where protection is adequate | Yes |
| A charity register search service (named on request) | register_lookup | Charity lookup: an applicant's name that reads as a charity is sent to a charity register search to find the charity's number and website | H1 | United Kingdom (the operator); the hosting region is not published | Yes |
4 of these recipients are described rather than named: they supply our data-gathering stack, which this published record does not name. Articles 14(1)(e) and 30(1)(d) ask for categories of recipient, and the names are held in the register and given on request to privacy@sitelens.co.uk.
Transparency
An Article 14 notice is owed for 15 of the 37 personal classes. It is given at ingest, per person, and carries the source and whether it was public, the retention period, the recipient categories, the Art 14(2)(da) complaint right and, presented separately per Art 21(4), the objection right. The objection link never expires.
Classes owing a notice: H30, H10, H10.addr, H1, H17, H12, H14, H20, H21, H38, H8, H9, H39, BC1, BC2.
Non-personal data recorded as such
124 columns whose names read like personal data carry a recorded decision that they are not. CI rejects a column that is in neither this list nor a class above, so "nobody has looked at this yet" and "someone decided this is fine" are distinguishable.
Security
Data at rest in RDS and S3 is encrypted; transport is TLS throughout. Access to the production account is limited to the controller. Personal data leaves the serving boundary only through permissions(class, channel, recipient) in src/lib/serving-gate.ts, which is the single serving decision in the codebase and carries a per-class kill switch.