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.

Where the legal framing lives. For the legal context — Nettonic Ltd's role as software vendor (not data processor), sub-processors we use, your rights as a customer of ours, retention periods on our side — see the Privacy Policy. This article is operational: what data Site Calendar stores on your WordPress installation, and how you respond to data requests from your attendees as the data controller.

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:

  1. 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).
  2. 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.
  3. 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.
  4. Send securely — encrypted email or a password-protected file with the password delivered separately.
  5. 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:

  1. Verify identity as for a SAR.
  2. 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.
  3. 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.
  4. 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.
  5. Confirm and log.
Why anonymise instead of delete? If you need to retain "X people attended this event" for reporting (annual reports, insurer requirements, grant applications), anonymisation lets you keep the attendance shell while erasing the personal data. The attendee's right is satisfied either way. Outright deletion is cleaner when you have no operational need for the shell.

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
  );
Back up first. SQL DELETE operations can't be undone. Always run a database backup immediately before executing deletion queries — most hosts offer one-click backups, or use a plugin like UpdraftPlus.

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

Stuck? Email support@getsitecalendar.com and we'll help directly. Pro licence holders get priority response.