Resources · Reference & troubleshooting
GDPR & attendee data
Where attendee data lives in Site Calendar, and the practical admin steps to respond to data subject requests — exports, deletions, anonymisation. The legal framing sits in our privacy policy; this article is the technical playbook for site admins.
- You'll need: Site Calendar Pro 1.1.0 or later active, admin access to WordPress, optional phpMyAdmin or WP-CLI access for bulk operations
- Estimated time: 10 minutes to read; reference whenever a data request lands in your inbox
- Difficulty: Intermediate — practical SQL and admin operations, no legal analysis required
Your role and ours, briefly
Site Calendar Pro is a self-hosted WordPress plugin. Every attendee record it creates is stored in your own database — Nettonic Ltd has no access to it and no way to retrieve it. That makes you the data controller for attendee data and Nettonic Ltd a software vendor, not a data processor.
The full breakdown of what data flows where is in Privacy Policy section 2. For practical purposes, the takeaway is: attendee data is yours to manage, on your infrastructure, and your obligation when an attendee exercises their UK GDPR rights.
What attendee data Site Calendar collects
Every event registration creates a pcal_attendee custom post type record on your site. The fields stored against that record:
Always collected
- Name —
_pcal_attendee_name - Email address —
_pcal_attendee_email - Event ID —
_pcal_event_id - Ticket type ID —
_pcal_ticket_id - Unique attendee code (the 8-character QR identifier) —
_pcal_attendee_unique_code - Registration timestamp —
_pcal_attendee_registered_at - Payment status (
free,paid,refunded) —_pcal_payment_status
Collected for paid tickets only
- Order number —
_pcal_order_number - Amount and currency —
_pcal_amount,_pcal_currency - Payment gateway and reference —
_pcal_payment_gateway,_pcal_payment_reference
Collected if the attendee provides it
- Phone number (if your form includes the phone field) —
_pcal_attendee_phone - Custom fields (dietary requirements, t-shirt size, etc.)
Audit trail (Pro 1.1.4+)
- Check-in —
_pcal_checked_in_at,_pcal_checked_in_by - Email resends —
_pcal_last_resent_at,_pcal_last_resent_by,_pcal_resend_count - Check-in undos —
_pcal_last_checkin_undone_at,_pcal_last_checkin_undone_by,_pcal_checkin_undo_count
Site Calendar does not collect or store IP addresses, browser fingerprints, marketing cookies, geolocation, device IDs, or anything beyond what's entered on the registration form or generated by the check-in process.
What third parties receive attendee data
Beyond your own installation, attendee data flows to these external services as part of normal plugin operation. Each is an independent data processor with their own privacy and DPA arrangements that you need on your own behalf:
- Stripe — receives name, email, billing address, and card details when an attendee pays for a ticket via Stripe. Stripe's privacy policy.
- WooCommerce + your WooCommerce payment gateway — same as Stripe but routed through WooCommerce first. WooCommerce's own DPA covers their handling; the underlying payment gateway has its own.
- Your transactional email provider (Postmark, Brevo, SendGrid, etc.) — receives the body of confirmation emails, including attendee name and ticket details. Each provider has its own privacy and DPA documentation.
- Your hosting provider — physically stores the database. Their DPA applies.
List these in your own attendee-facing privacy notice. A template paragraph is provided in the "Privacy notice text you can adapt" section below.
Responding to a Subject Access Request (SAR)
An attendee asks what data you hold about them. Process:
- Verify identity. Confirm the requester's email matches a registered attendee record. For higher-risk situations, ask for additional verification (e.g. the date of an event they attended).
- Search your database for all records associated with that email. Use the SQL recipe below, or use a WordPress GDPR plugin that automates the search.
- Compile a response — typically a CSV with events registered, ticket types, registration dates, payment amounts, custom-field answers. Add any communications from your WP Mail SMTP log.
- Send securely — encrypted email or a password-protected file with the password delivered separately.
- Log the request — date received, identity verified, what data provided. UK GDPR Article 5(2) requires you to be able to demonstrate compliance.
The 30-day response deadline starts the day you receive the request, not the day you verify identity.
Responding to a Right to Erasure request
An attendee asks for their data to be deleted. Process:
- Verify identity as for a SAR.
- Check for overriding interests. Is the attendee in a refund window? Is there a pending dispute? Are you legally required to keep records (e.g. UK HMRC's 6-year tax retention for paid transactions)? If yes, you can decline or partially fulfil, but you must explain why and document your reasoning.
- If proceeding, choose delete or anonymise. Delete removes the record entirely. Anonymise replaces identifying fields with
[Erased]markers, keeping the event-attendance shell for aggregate statistics. Both satisfy UK GDPR Article 17. - Also handle data outside Site Calendar: WooCommerce orders, Stripe customer records (managed via Stripe dashboard), WP Mail SMTP logs, your hosting provider's access logs.
- Confirm and log.
Quick SQL recipes
For phpMyAdmin or any MySQL client. Replace mhx_ with your WordPress table prefix, and the email address with the requester's.
Find all attendee records for a given email
SELECT p.ID, p.post_title, p.post_date,
pm_event.meta_value AS event_id,
pm_status.meta_value AS payment_status,
pm_amount.meta_value AS amount,
pm_code.meta_value AS unique_code
FROM mhx_posts p
JOIN mhx_postmeta pm_email
ON pm_email.post_id = p.ID
AND pm_email.meta_key = '_pcal_attendee_email'
LEFT JOIN mhx_postmeta pm_event
ON pm_event.post_id = p.ID
AND pm_event.meta_key = '_pcal_event_id'
LEFT JOIN mhx_postmeta pm_status
ON pm_status.post_id = p.ID
AND pm_status.meta_key = '_pcal_payment_status'
LEFT JOIN mhx_postmeta pm_amount
ON pm_amount.post_id = p.ID
AND pm_amount.meta_key = '_pcal_amount'
LEFT JOIN mhx_postmeta pm_code
ON pm_code.post_id = p.ID
AND pm_code.meta_key = '_pcal_attendee_unique_code'
WHERE p.post_type = 'pcal_attendee'
AND pm_email.meta_value = 'requester@example.com';
Anonymise rather than delete
UPDATE mhx_postmeta
SET meta_value = '[Erased]'
WHERE post_id IN (
SELECT post_id FROM (
SELECT post_id FROM mhx_postmeta
WHERE meta_key = '_pcal_attendee_email'
AND meta_value = 'requester@example.com'
) AS subq
)
AND meta_key IN (
'_pcal_attendee_name',
'_pcal_attendee_email',
'_pcal_attendee_phone'
);
Hard delete
DELETE p, pm
FROM mhx_posts p
JOIN mhx_postmeta pm ON pm.post_id = p.ID
WHERE p.post_type = 'pcal_attendee'
AND p.ID IN (
SELECT post_id FROM (
SELECT post_id FROM mhx_postmeta
WHERE meta_key = '_pcal_attendee_email'
AND meta_value = 'requester@example.com'
) AS subq
);
Automating data retention with WP-CLI
For sites with high event volumes, automate periodic cleanup:
# List all attendee records older than 6 years
wp post list --post_type=pcal_attendee --before='6 years ago' --format=ids
# Move them to trash
wp post delete $(wp post list --post_type=pcal_attendee --before='6 years ago' --format=ids)
# Empty trash to permanently delete
wp post delete $(wp post list --post_type=pcal_attendee --post_status=trash --format=ids) --force
Schedule monthly via cron:
# 02:00 on the 1st of every month
0 2 1 * * cd /path/to/wordpress && wp post delete $(wp post list --post_type=pcal_attendee --before='6 years ago' --post_status=publish --format=ids) --force --quiet
Setting your retention policy
Site Calendar doesn't auto-delete attendee records — you decide retention based on your legal obligations and operational needs. Common patterns:
- Sports clubs and community groups — duration of the season, then anonymise. Check your insurer's record-keeping requirements before deleting.
- Ticketed events with paid sales — at least 6 years (UK HMRC business-record requirement; similar elsewhere). After 6 years, anonymise or delete.
- One-off festivals or conferences — 12 months post-event for refund / dispute handling, then delete.
- Membership organisations — until the member leaves, plus a 3-year grace period.
Document whichever policy you adopt in your own attendee-facing privacy notice so it's transparent.
Privacy notice text you can adapt
The single most effective compliance measure is a clear, plain-English privacy notice on your own site. Paragraph you can adapt:
Event registration
When you register for an event on this site, we collect your name,
email address, and (optionally) your phone number. If payment is
involved, we also collect billing and card details, processed by
[Stripe / WooCommerce + gateway name] as an independent data processor.
We use this data to: send you a ticket confirmation with QR code;
admit you at the event door; provide a refund if applicable.
We retain attendee records for [X years/months] after the event date,
in line with [your retention rationale — HMRC, club insurer, etc.].
After that period, records are deleted or anonymised.
You have the right to access, correct, or request deletion of your
data at any time. Contact [your data protection email] to make a
request — we'll respond within 30 days.
Beyond [payment gateway] and our email provider [Postmark / Brevo /
SendGrid / etc.], we do not sell, share, or transfer attendee data to
third parties.
Replace bracketed placeholders. Add to whatever privacy notice you already have on the site where your attendees register.
Troubleshooting
"An attendee requested deletion but they bought a ticket two months ago — can I refuse?"
Probably not, unless you have a specific overriding reason. Event has occurred, payment settled, no dispute open. Erase or anonymise. Exception: HMRC retention obligations on the financial transaction record — in which case retain the order data but erase the personal name / email / phone (anonymise approach).
"An attendee requested deletion but their event is tomorrow"
Treat as both a cancellation and a deletion request. Refund them (if paid), then erase or anonymise. Confirm by email before deleting in case they meant to cancel but not delete.
"Can I use the CSV export as my SAR response?"
The CSV export from the Attendees screen contains most of what you'd need to provide. Filter to just the requester's rows before sending. You'll still want to add any custom-field data and check-in audit details not in the default export, but the CSV is a good starting point.
"How do I delete Stripe-side data?"
Stripe Dashboard → Customers → find customer → Delete. Stripe retains anonymised transaction logs as required by financial regulation (typically 7 years for tax). That's lawful under UK GDPR Article 17(3)(b) — financial records may be retained when required by other legal obligations.
"What if the requester's email doesn't match any record?"
Respond confirming you hold no data. Failing to respond at all is itself a UK GDPR violation. A short "We have searched our records and confirm we hold no personal data associated with the email address you provided" is sufficient. Log the request and the response.
"Do I need a DPA with Nettonic Ltd?"
For attendee data, no — Nettonic Ltd doesn't receive or process attendee data. For your own customer account data with us, yes — see Privacy Policy section 10 for how to request one.
"Attendee data appearing in Google search results"
Attendee records are private custom posts and shouldn't be indexed by default. If they are, your theme or a plugin is exposing the pcal_attendee archive publicly. Find and disable that exposure, then submit a removal request via Google Search Console.
"Events involving children"
Additional UK GDPR provisions apply — under-13s (UK) and under-16s (some EEA states) need parental consent. Consider whether the child's name is genuinely needed; for many events the parent's name is sufficient. Where the child's name is needed, capture parental consent and retain proof alongside the attendee record.
"How do I prove I responded to a SAR in time?"
Keep an internal SAR log: date received, requester email, date of response, what data was provided (or reason for refusal), staff member who handled it. A Google Sheet or Notion page is sufficient. UK GDPR Article 5(2) requires demonstrable accountability.
What's next
- Our Privacy Policy — legal framing of Nettonic Ltd's role and your rights as our customer
- Managing attendees — day-to-day admin including Remove and anonymise workflows
- Branded confirmation emails — your transactional email provider as an independent data processor
- Setting up Stripe payments — Stripe as an independent data processor
