Privacy Policy
Last updated: 2026-09-04
This policy explains what Competitive Campaigns collects, where it comes from, who else sees it, how long it is kept, and what you can do about it.
It is written to be read by a campaign manager, not by a lawyer. Where something is unfinished or imperfect, this policy says so rather than describing a system we do not have.
1. Who runs this service
Competitive Campaigns ("the Service") is operated by Competitive Campaigns LLC, a Maryland limited liability company ("we", "us", or "our"). The service providers that process data for us are listed in section 6.
Contact: support@competitivecampaigns.com. Postal address: We do not publish a postal address here. If you need a postal address to serve a legal notice or exercise a privacy right, email support@competitivecampaigns.com and we will provide one.
2. The groups of people in this system
Almost every privacy question about this Service turns on which of these groups you are in.
Campaign users. These are the people who create an account and sign in: candidates, campaign managers, and their staff. You gave us your information directly, you agreed to our Terms of Service, and you can ask us to change or delete what we hold.
People invited to a campaign. A campaign owner or manager can give us an email address so we can send that person an invitation. The person becomes a campaign user only if they create or sign in to an account with that email address and accept the invitation.
People waiting for another state. These are people who ask us to tell them when Competitive Campaigns becomes available in a state we do not support yet. Joining a state list does not create an account, begin a trial, or give access to campaign or voter data.
Campaign contacts. These are supporters, volunteers, donors, and endorsers a campaign records in its private workspace. The campaign may enter this information, or a volunteer may submit their own information through the campaign's public volunteer form. A campaign contact does not need an account and is not treated as a registered voter unless a later product step explicitly links the records after staff review.
North Carolina voters. These are the roughly 8.4 million people in the North Carolina voter registration file. They never signed up for anything here and never agreed to anything. We did not collect their information from them. We copied it from public files published by the North Carolina State Board of Elections ("NCSBE"), which North Carolina law makes a public record under N.C.G.S. section 163-82.10.
Code holders. These are volunteers a campaign brings into its field program: people who hold a turf code the campaign issued them instead of an account. A code holder never signed our Terms of Service; they are shown a short volunteer notice before any voter information appears, and their access exists at the campaign's discretion.
Sections 3 and 4 below cover campaign users, campaign contacts, and what we hold about code holders. Section 5 covers voters, and section 6 says exactly what a code holder is shown.
3. What we collect about campaign users
People waiting for another state
If you ask us to notify you when another state becomes available, we collect your email address, the state you selected, the version of the notice shown with the form, the first and most recent request times, whether we sent the availability notice, and whether you later asked us to stop. We use this information only to understand demand by state and tell you when the selected state becomes available. We do not create an account or send the selection to Google Analytics or Google Ads.
Account and identity
- Email address, which is your login.
- Display name.
- A bcrypt hash of your password. We never store the password itself and cannot recover it.
- The state your account works in, chosen at signup. Today that is North Carolina.
- Your role (user, admin, or owner) and account status (active or suspended).
- Your access level (locked, trial, or comped), when it was granted, when it expires, and the active-campaign allowance for a comped grant.
- The date your account was created.
- Whether you have opted out of notification email.
- If you have asked us to delete your account: the date you asked, the date it is erased, and whether we have sent you the warning email. All three are cleared if you reactivate.
Account setup and access progress
We record when an account request is completed, campaign setup starts, a race or strategy step is saved, setup is completed, access is approved, the account holder returns after approval, and a paid subscription starts. Each record contains the account link, a fixed step name and time. It does not contain the selected race, district, party, strategy, voter information or free-text answers. We also keep whether a browser event was claimed and whether a one-time reminder was queued so retries do not repeat those actions.
Staff use this progress to review waiting requests. We compare aggregate request-to-setup, setup-to-return and return-to-subscription rates to identify where applicants stop. These account-service records are created by our own application. They are separate from Google Analytics and Google Ads data. We do not copy Google event-level records or ad-click identifiers into them.
Sign-in and sessions
- A server-side session record holding an opaque session id, its expiry, and when it was created. Signing out deletes the record, which immediately invalidates the cookie.
- A session cookie (
cm.session) in your browser. It is HTTP-only, Secure, and SameSite=Lax, and it carries only a signed reference to the session record, never your identity or password. - If you sign in with Google or Apple: the provider's permanent account identifier, the email address the provider asserted, and the first and most recent sign-in times. We store the provider's identifier rather than the email, so changing your email at Google does not detach your account.
- Short-lived records for a sign-in attempt in progress, holding hashed values only (a hashed state parameter, a hashed browser-binding secret, and the PKCE verifier and nonce). These are single-use, expire in minutes, and are deleted about an hour after they expire.
- If you request a password reset: a SHA-256 hash of the reset token, its expiry, and whether it was used. The token itself only ever exists in the emailed link. A completed reset revokes every session on the account.
Security and abuse prevention
- Rate-limit counters keyed by IP address or account id, for example
login:ip:203.0.113.7. These hold a key, a count, and a window, and they are deleted after they expire (opportunistically, so a row can outlive its window by a while). - Administrative audit records. Every privileged action taken in the admin console writes one permanent record containing the administrator's id and email, the action, the target, a one-line summary, structured details about what changed, the administrator's IP address, and the time. These records are append-only. There is no way to edit or delete them, by design.
Billing
- Approval time and the exact end of the first approved one-campaign, seven-day trial.
- If you start a paid subscription: your Stripe customer id, Stripe subscription and item ids, Base plan, subscription status, current period end, whether a cancellation is scheduled, the current validated campaign-slot quantity, when Stripe created the subscription, when we last synchronized it, when the catalog and quantity were verified, and a fixed safe synchronization error category when a check fails.
- Campaign-slot change records: the requested increase, currency, current and new monthly totals, the immediate amount Stripe previewed, renewal and proration dates, fixed state, idempotency key, confirmation and effective times, bounded attempt, lease, and revision state, the provider subscription, item, price, and preview correlations needed to reconcile it, and the campaign that eventually used the slot. We do not store raw provider responses or card details in this record.
- Campaign archive, deletion, and restore billing records: the account and campaign ids, who requested the action, the requested action, current and proposed campaign-slot quantities, current and new monthly totals, Stripe's estimated account credit and next invoice, renewal and proration dates, fixed state and safe failure category, bounded attempt, lease, revision, idempotency key, and the provider correlations needed to reconcile the result. These protected records may remain after a campaign is permanently deleted so an uncertain provider result can be resolved. They are removed when the account is permanently erased after billing is confirmed.
- Minimal Stripe webhook receipts: provider event, object, and customer identifiers; event type and provider-created time; processing state, attempt count, retry and lease times; a local correlation id; the linked account when resolved; and a fixed safe failure category. We do not store the raw webhook body or provider response.
- Durable cancellation and refund operation records used for account deletion and authorized staff support: provider correlations, the requested action and amount where relevant, fixed state and outcome categories, bounded attempts, leases, retry times, confirmation expiry, and completion time. These records do not contain card details or raw provider errors.
- We do not receive or store card numbers, expiry dates, or CVCs. Those go directly to Stripe.
Notification records
- One record per notification email we send you: the kind, the subject line, the provider, the provider's message id, whether it succeeded, a fixed safe error category, bounded attempt and retry times, and the accepted-delivery time. Trial and billing notice keys use exact UTC deadlines or stable paid-period state, without customer, subscription, invoice, or payment identifiers. Most notification journals do not store email copy. Polling-place staffing delivery records keep a bounded assignment snapshot with the signup state, location, shift times, and public instructions so a delayed move, cancellation, or promotion notice cannot change meaning. They do not store a link secret, private URL, provider response, invoice id, or payment detail.
What you create in the product
- Campaigns: campaign name, candidate name, party, and the race you selected.
- Campaign access: which account owns a campaign, which accounts may view it, and when each person joined.
- Campaign invitations: the invited email address, the access offered, who sent it, a SHA-256 hash of the single-use invitation token, when it expires, and whether it was accepted or canceled. We do not store the token from the emailed link.
- Campaign access history: when an invitation is sent or canceled, a teammate's role changes, or a teammate is removed. Each entry stores the action, time, the actor's account id, name, and email address, the affected person's account id, name, and email address when available, and the previous and new access levels when applicable.
- Campaign people: names, contact details, postal address, whether the campaign identifies the person as a supporter, volunteer, donor, or endorser, when those relationships were added, staff notes, and contact-permission history for email, text messages, and phone calls. We keep who created the person, wrote a note, or recorded a permission change and when they did it. A manager may also link one campaign person to one public voter record after reviewing possible matches. We store the voter record's internal id, who confirmed the link, and when. The link is optional and removable. It does not copy voter fields into the campaign-person record or override a voter do-not-contact record. When a manager combines duplicate campaign-person records, we keep the retired record, which active record it was combined into, and who completed the merge and when. Notes, permission history, and campaign relationships move to the active record with their original names and dates.
- ActBlue contribution imports and automatic updates: the recipient line-item id, gross contribution and refund amounts, contribution time, recurring status and cancellation time, form name, refcode, and the campaign person connected to the contribution when one exact email match exists. We also keep an import record with the source, a SHA-256 fingerprint of the report or verified delivery, row counts, who completed a manual import, and when it ran. If finance staff enable CSV API updates, we keep the ActBlue client UUID and client secret in authenticated encrypted form, the selected start date, the last date checked, safe status and error codes, and retry timing. If finance staff enable live updates, we keep the campaign's ActBlue Entity ID, a random endpoint key and username, a one-way hash of the live-update password, safe delivery times and error categories, a consecutive-failure count, bounded processing time, and a compact receipt containing only the line-item id and event type. The live-update password is shown once and cannot be recovered from our database. We do not keep an uploaded or downloaded CSV, its raw rows, a raw live-update body, or provider error details after processing. We do not receive an ActBlue account password, payment-card number, or bank detail.
- Public volunteer forms and polling-place staffing: the campaign's public links, publication state, public locations and instructions, selected shifts, confirmation or waitlist status, and later moves or cancellations. When a person submits a form, we collect their name, email address, optional phone number, and separate choices about campaign email and text messages. Each valid interest or signup action is saved under an isolated campaign-person record unless that browser presents its own campaign-scoped continuity token. A typed email address never opens, links, or changes an existing record. We store one-way request and private-link hashes, an immutable event confirmation receipt, and a revocation time when applicable instead of raw secrets. We record signup, waitlist, move, cancellation, and promotion history. We do not use these forms to search the voter file or automatically link the person to a voter record.
- Saved lists: the list name and either the saved filter settings or a snapshot of which voters were on the list. For a strategy-based list the Service recommends, we also keep its purpose and description, the versioned audience recipe and the campaign party, race type, and election-history basis used to create it, when it was generated, and whether it was replaced or hidden. The recipe contains filters and categories, not a second copy of voter records.
- Saved win-number scenarios: the full projection result at the time you saved it.
- Tags you create and apply to voters.
- Outreach records: for each voter you target, the campaign, the voter's state id number, the channel, the outcome, the message text you entered, the time, and an identifier for the request that recorded it so a resubmitted request cannot record the same voter twice. See section 6 on what outreach does and does not do today.
Code holders (campaign volunteers)
A code holder has no account, no email address, and no password here. What we hold about a code holder is:
- The display name the campaign supplied for them.
- A hash of their access code. The code itself is never stored and cannot be recovered from the hash.
- Which version of the volunteer notice they accepted, and when.
- Activity timestamps: when their code was issued, expires, was revoked, and was last used, and when they were last active.
- IP addresses in the rate-limit counters described above, held only to bound abuse of the code entry endpoint.
People who submit a public volunteer form
The information entered on a campaign's volunteer form or polling-place staffing page goes into that campaign's private Campaign people and assignment records. Campaign staff with permission to manage people and staffing can see it. An ordinary interest or event submission creates an isolated record even when the typed email matches an existing campaign person. We place an HTTP-only, Secure, SameSite=Lax cookie named cm.volunteer-public on that campaign's public path. It contains a random continuity token, expires after 30 days, and can be revoked. The database keeps only its one-way hash. The cookie may let the same browser add another action to the isolated record in that campaign. It is not email verification and cannot open an existing record or work in another campaign. We use a one-way versioned HMAC of the normalized email address only as a staff review hint for polling-place staffing. Rate-limit records use the connection's IP address and one-way email and link identifiers. The IP address is not added to the person's profile, assignments, notes, or contact-permission history.
Each polling-place staffing request immediately saves its selected shifts under a new isolated provisional person and enrollment. We do this whether the entered email matches zero, one, or several existing campaign records. The typed email is not authority to open, link, or change an existing person's record. The provisional record is excluded from automatic voter linking, contribution matching, ordinary outreach, audiences, exports, and generic person merging. Campaign staff see that the contact needs review.
We send an optional email-proof link so the person can unlock private self-service for only that request's enrollment. The signup remains saved if the person never clicks or if delivery fails. Proof is one-use, valid for no more than seven days and no later than 24 hours after the last selected shift ends. Opening the email proves only access to that exact normalized email. It does not prove a submitted name or phone number and does not merge the provisional record with an existing person. Used and expired request, receipt, proof-delivery, and consent-provenance rows are retained with the campaign record for audit and recovery rather than deleted by the reminder job.
The email and text boxes start unchecked. A selected email choice remains pending until that request's exact email proof succeeds. Email proof can activate only that request's email choice. It never activates a text choice or a choice from another request. Supplying an email address or phone number without selecting the matching box leaves that channel's permission unknown. Competitive Campaigns does not verify the campaign's later communications or determine whether a recorded choice satisfies every law or provider rule.
A public link, email-proof link, or management-link secret is carried in the URL fragment, which browsers do not send in HTTP requests, and is removed from browser history before use. Sensitive polling-place staffing and volunteer management routes do not load Google Analytics. Link identifiers and secrets are excluded from page metadata, referrers, provider telemetry, and application logs.
Analytics across the Service
We may use Google Analytics across the Service, including ordinary public pages, the sign-up path, and the signed-in product. We do not load it on polling-place staffing public-link, email-proof, or management routes. It helps us understand how visitors find the Service, whether they complete signup, and which product features are useful.
When enabled, Google Analytics receives an analytics cookie identifier, a sanitized page or route category, referring site or search engine, time of visit, browser and device category, approximate location inferred from the connection, and the name of a product action. The browser also sends the technical network information needed to deliver the service, including its IP address.
We do not send Google Analytics your name, email address, form answers, account identifier, campaign or candidate name, voter data, voter lists, list filters, search queries, uploaded files, message content, or the content you create in the product. We do not include page query strings, object identifiers, public-link ids, confirmation-link ids, management-link ids, or link secrets in analytics events.
For the trial and billing funnel, the application sends only a fixed action name, a fixed route category, and a fixed outcome. The campaign billing categories cover opening a price preview, confirming or applying a slot increase or decrease, starting or completing campaign setup, a restore blocked by capacity, a change failure, and a change that needs reconciliation. It does not send a full URL, customer or subscription identifier, invoice or payment identifier, trial or billing timestamp, amount, campaign count, role, access code, provider error, support reference, user-entered text, or Terms and Privacy acceptance content.
For example, we may record that someone created a list, printed a walk sheet, viewed a campaign plan, previewed or applied a strategy change, dismissed or restored a strategy-based recommendation, repaired or superseded one, opened a recommended or current-work list, started a contact program from one, opened the volunteer-ask view, or submitted an AI question. Recommendation lifecycle events are fixed action names only. A current-work event may include only a fixed queue category and action category. We do not send the list's id, name, filters, recipe version, voter count, support value, consent value, lifecycle dates, the walk sheet's voters, the plan's contents, the AI question itself, or a campaign or account identifier.
We may connect Google Analytics to our Google Ads account so we can attribute a visit from one of our ads and count a completed account request. Google Ads auto-tagging may add a click identifier to the landing-page URL. The Google tag may use that identifier for attribution, but our application does not read, store, log, or copy it. We import only the fixed generate_lead event described above as an account-request conversion.
We do not use this connection for remarketing, audience building, Google Signals, personalized advertising, enhanced conversions, customer-list uploads, or cross-site ad targeting. Google Ads audience import remains off.
We enable Google Analytics' account-level data-sharing settings for Google products and services, modeling and business insights, technical support, and business recommendations. Those settings let Google use our analytics data and account configuration to improve its products, create aggregated or de-identified benchmarks and modeled insights, help us resolve technical problems, and make product recommendations. They do not change the data fields we send from the Service or enable advertising audiences.
What we do not collect
We do not use remarketing trackers, session recording, or heat maps. When Google Analytics is enabled, it places analytics cookies on the public and signed-in pages described above. Those cookies may also attribute a visit and completed account request to one of our Google Ads. The sign-in cookies described above remain separate from those analytics cookies. We do not sell information about you, track you across other websites for advertising, or use information collected through analytics to train a machine learning model.
4. Why we use campaign user information
- To let you sign in and stay signed in.
- To decide what your account may reach, which is what the locked, trial, and comped access levels do.
- To operate the product features you use: campaigns, lists, exports, projections, and AI queries.
- To bill you, if and when paid plans are switched on.
- To send service email: campaign invitations, a welcome message, password resets, notices that your data is stale or a sync failed, new candidate filings in your race, election countdowns, and the two account deletion notices described in section 8. Account holders can turn off optional emails. Account-access approval notices, password resets and deletion notices are separate. A campaign invitation goes to the address supplied by the campaign owner and includes a link to accept or ignore it.
- To stop abuse: rate limits on sign-in, signup, public volunteer forms, password changes, field-code redemption, AI queries, exports, outreach, and billing.
- To keep an accountable record of administrative actions.
- To measure use of public pages, the sign-up path, and product features, so we can improve the Service and understand which marketing work leads to completed account requests.
If you have not returned within 48 hours after approval, we may send one optional email inviting you to continue. We do not send another follow-up. Turning off optional emails, returning, deleting your account, or losing or changing the approval stops that follow-up. The account-access approval notice is separate from this optional email.
We do not sell information about you, share it to build advertising audiences, or use it to train a machine learning model.
5. What we hold about North Carolina voters
Where it comes from
Every voter record in the Service is derived from public files published by NCSBE and, for a subset of derived statistics, from public precinct-level election results, public campaign finance filings, and the public candidate filing list. We do not buy voter data from vendors, we do not merge in consumer data, and we do not add anything a campaign tells us about a voter except the tags and outreach records that campaign creates itself.
North Carolina law makes voter registration records public. The same law makes certain fields confidential and they are not in the published files: full or partial Social Security numbers, full dates of birth, driver's license numbers, and signature images. We do not have those fields and cannot obtain them here.
What we store per voter
- Names: first, middle, last, and suffix.
- Residential address, city, state, and ZIP code.
- Mailing address lines, city, state, and ZIP code.
- Telephone number, where the source file contains one.
- Registration status and the reason for that status.
- Registration date.
- Party affiliation.
- Race code, ethnicity code, and gender code.
- Birth year and age. We store no day or month of birth, and the AI feature is instructed never to expose birth dates.
- State of birth.
- County, precinct, municipality, ward, and every district assignment in the file: congressional, NC House, NC Senate, judicial, superior court, county commission, township, school, fire, water, sewer, sanitation, rescue, municipal, and voting tabulation district.
- The statewide voter identifier (NCID) and the county registration number.
- The confidentiality flag described in section 7.
- The date we loaded the record, and the date it disappeared from the source file if it has.
- A vote propensity score we compute (how many of the qualifying elections we have loaded the voter has a history record for) and the list of elections that score was computed from, which is also its denominator.
We also hold, linked to a voter by their NCID:
- Vote history. One record per ballot cast per election: the election date and description, the voting method, the party ballot taken in a primary, and the precinct and county. Whether a person voted is public record in North Carolina. How they voted is not, is not in the source file, and is not here.
- Absentee and early ballot requests. Request type, request date, send date, return date, and return status, from NCSBE's cumulative absentee export.
- A change journal. When a nightly sync sees a field change on a voter, we record which fields changed and their old and new values.
Why we hold it
To let a campaign see the electorate in its own district, build targeted lists, estimate turnout and a win number, and produce canvassing and mail lists. This is the entire purpose of the Service.
The legal basis, stated plainly
We process this data because it is a public record that North Carolina publishes for exactly this kind of use, and because campaigns have a legitimate interest in contacting the voters they seek to represent. Voters did not consent to this and we do not claim they did.
6. Who else receives data, and exactly what they receive
These are every third party that receives anything. Each one is listed with what actually crosses the boundary, because the difference matters.
Anthropic (the Claude API)
The limits below apply to every use of Claude in this Service, present and future. They are the promise; the feature list after them is how it is kept today.
We send Anthropic only:
- Text describing our database structure - table names and column names, with no data in them.
- Reference information published by the state, such as what each party or status code means.
- Public record about a race: contest names, election dates, certified vote totals, candidates as they appear on the ballot, and campaign finance disclosures.
- Figures this Service calculated and already showed you on your own screen.
- Words you typed yourself.
We never send: any voter's record or any part of one, any list of voters, any tag, note or contact history, the results of any query, your account details, or anything identifying an individual voter. No information about any individual voter leaves this Service to Claude, in any feature, for any reason.
If we add a feature that uses Claude and stays inside those limits, we will name it here and say what it sends, but you will not be asked to accept the policy again - nothing about what leaves the Service will have changed. If we ever needed to send something outside those limits, that is a material change: we would say so plainly and ask you to accept it before it took effect.
Four features use Claude today.
Natural-language voter queries. When you type a question on the AI page, we send Anthropic:
- A generated description of our database structure: table names and column names only, with no data in it.
- A glossary of North Carolina code values, for example what each party and status code means.
- The question you typed.
Anthropic returns a SQL query. We do not send any voter data to Anthropic. The returned query is executed on our own database, under a restricted read-only role, against a view already narrowed to your campaign's district and already excluding confidential voters. The results go straight from our database to your browser. They are never sent back to Anthropic.
If you type personal information into the question box, that text is sent to Anthropic as part of your question. Do not type a voter's name, address, or phone number into the AI query box.
Campaign finance narratives. For the race money page, we send Anthropic the contest name, the report date, and for each committee in the race the candidate name, committee name, and total raised, total spent, and cash on hand rounded to the nearest hundred dollars. All of that is public campaign finance disclosure data. No voter data is included.
Post-election wrap-up conclusions. The results page ends with a short paragraph written by Claude that draws the rest of the page together. To write it we send Anthropic, for your race only:
- The name of the contest as the state published it, and the date of the election.
- The number of ballots your saved projection expected, and the number of ballots actually cast.
- The votes-to-win figure this Service published to you for that seat.
- Every candidate's name and vote total from the certified results, with a marker on the one that is your own candidate.
All of that is public record: the contest, the certified totals, and the candidates' names are published by the State Board of Elections, and the two remaining figures are numbers this Service printed on your own screen. No voter data is included. Nothing about your account, your saved lists, your tags, your contact history, or any individual voter is sent, and no vote is ever attributable to a person - certified results are counts. The marker on your own candidate identifies a name already on the published ballot; it does not send anything additional about you.
Campaign plan letters. The generated campaign plan document closes with a short note written by Claude, written once and then kept with the document until you delete the campaign. To write it we send Anthropic, for your race only:
- The office, district, race type, and election date, as public record.
- Figures this Service calculated and already showed you on your own screens: the registered voter count and voting universe, the turnout basis (a percentage, whether it came from this district's own history or comparable districts, and how many elections it was measured in), the votes-to-win figures and projected ballot counts per scenario, and the weekly attempts figure computed from your own assumptions.
- The assumptions you typed on the plan page: your support rate, attempts per conversation, and field start date.
- How many candidates have filed in the race, as a count - no names.
No voter data is included. Nothing about your account, your saved lists, your tags, your contact history, or any individual voter is sent. Everything here stays inside the limits above: public record, figures already on your own screen, and numbers you typed yourself.
Anthropic is not permitted to use this data to train its models under its commercial API terms. If no Anthropic API key is configured, nothing at all is sent to Anthropic: the voter query page returns a "not configured" notice, the finance and wrap-up narratives are simply not shown, and the campaign plan document closes with a standard sentence written by this Service instead.
Resend (email delivery)
Resend delivers service email to campaign users, campaign invitees, and volunteers who submit an event or polling-place staffing request. It receives the recipient's email address, the subject line, and the message body. The message bodies are: a campaign invitation, a welcome message, a password reset link, a data-staleness or sync-failure notice, a list of newly filed candidates in your race (public candidate filing information), an election countdown, volunteer shift details and private management links, an optional polling-place signup email-proof link, and the two account deletion notices.
Resend also sends the account-access approval notice and the optional follow-up described in section 4.
Staff may receive one reminder when an access request remains unreviewed beyond two complete following weekdays in Eastern Time. It contains a generic review notice and a link to the restricted admin console, not the applicant's name, email address, race or strategy. These emails use our existing email provider. The provider receives the recipient address, subject and message. A successful provider response means the message was accepted for sending, not that delivery to an inbox was confirmed.
No voter records are sent to Resend. If no Resend key is configured, ordinary non-credential service messages may use the development log provider. Polling-place proof and private-management messages are never written to that log. Their delivery records remain failed and retryable or require staff attention until a real email provider is configured.
Stripe (payments)
When you start a checkout, we create a Stripe customer using your email address and display name, tagged with your internal account id, and a checkout session tagged with the same id. Stripe collects and holds your payment details directly; they never reach our servers. Stripe tells us the current subscription status, price and product, paid period, scheduled cancellation, invoices, charges, refunds, and the results of authorized billing operations. We keep the limited local billing mirror and receipts described in section 3 so access decisions, retries, reconciliation, and account deletion do not depend on one webhook arriving once and in order.
Render (hosting and database)
The application and the Postgres database both run on Render in the virginia region, which is in the United States. Everything in this policy is stored there. Render is our hosting provider and has the access to infrastructure that any hosting provider has.
ActBlue (campaign contribution reports)
Only when a campaign's finance staff turn on automatic ActBlue updates, we send ActBlue that campaign's client UUID and client secret through HTTPS Basic Authentication. Each report request also includes the requested report type and date range. ActBlue returns CSV reports containing the campaign's donor, contribution, and refund data. Competitive Campaigns uses those reports to update the campaign's private fundraising tools.
We do not send ActBlue voter data, a Competitive Campaigns account password, an ActBlue account password, payment-card or bank information, or a Google Analytics identifier. We do not send the client UUID, secret, report date range, or ActBlue response data to analytics.
ActBlue's CSV reports remain the source of truth for the campaign's reporting and compliance. Totals in Competitive Campaigns are operational campaign tools and are not a replacement for official compliance reporting. ActBlue processes these requests and reports under its own legal terms and privacy policy.
Google and Apple (optional sign-in)
Only if you choose to sign in with Google or Apple. They learn that you are signing in to this Service. We receive the account identifier, email address, and display name they assert.
Google Analytics and Google Ads
When Google Analytics is enabled, it receives the limited analytics data described in section 3: an analytics cookie identifier, sanitized page or route category, referring site or search engine, time of visit, browser and device category, approximate location, product-action name, and technical network information from the browser connection.
It does not receive account, campaign, candidate, list, voter, or other object identifiers; email addresses; form answers; voter information; list filters; search queries; uploaded files; message content; or page query strings.
We connect this Analytics property to Google Ads for first-party ad-click attribution and conversion measurement. Google Ads auto-tagging may add a click identifier to the URL when someone visits from our ad. The Google tag may process it, but our application does not read, store, log, or copy it. Google Ads receives the fixed generate_lead event only after a new account request has been saved. We do not send names, email addresses, form answers, account identifiers, or other user-provided data as an enhanced conversion.
Google processes this data under its own terms and privacy policy. Its processing may occur outside the United States. We use these services to understand the public website, sign-up path, product use, and which ads lead to completed account requests. We keep Google Ads audience import, personalized advertising, remarketing, Google Signals, enhanced conversions, and customer-list uploads off.
We also enable Google's optional account-level data-sharing settings for product improvement, aggregated or de-identified business insights, technical support, and business recommendations. Google may use the analytics data and account configuration covered by those settings for those purposes.
NCSBE and other public sources
We fetch public files from NCSBE. We send them nothing about you or about any voter.
United States Census Bureau (address geocoding)
To place voters on a map for field work - which precincts and streets a canvass can actually reach - we convert residential addresses to coordinates using the Census Bureau's public geocoding service.
For each address we submit exactly four fields, in batches of up to 10,000: the street address, city, state, and ZIP code. Each row is labeled with a sequence number (1, 2, 3, ...) that is meaningless outside that single batch; we match results back to voters on our own server. No name, no party, no voter identifier, and no other field ever crosses. The Census Bureau receives a list of addresses and cannot tell from anything we send whose addresses they are, or that they are voters' at all.
We only submit addresses in the counties that campaigns actually using this Service need, never the whole state. Voters flagged confidential (section 7) are never submitted - their address does not leave this system for geocoding or for anything else. The Census Bureau's geocoder is a public service of the United States government; the addresses we send it are already public record in the NCSBE file it helped us position.
Code holders (campaign volunteers)
A volunteer holding a live turf code is shown the contact fields of one claimed voter record at a time: name, residential address, precinct, party, the telephone number where the source file has one, and the names and party of other targeted voters in the same household. A code holder is never shown demographic fields (race, ethnicity, gender, birth year, age), vote history, absentee records, identifiers (NCID or county registration number), propensity scores, or any list or export. Their access ends when the campaign revokes the code, when the code expires, or when the campaign ends.
Everyone else
No one. We do not send personal information to data brokers or advertising audiences. Google Analytics and Google Ads receive only the limited measurement data described above.
A note on outreach
Campaign contact results may be used inside the campaign to build current retry and supporter-reminder lists. The latest valid contact attempt and the latest valid voter conversation with a support value are kept as separate derived facts. Current ballot data is used to remove a supporter from a turnout list only when it is for that campaign's election and the update is complete.
The Campaign people volunteer-ask view uses an explicit relationship recorded by campaign staff and the latest recorded permission for each email, phone, or text channel. It does not infer a relationship, support, or permission from voter data or other traits. Contact details are shown only for channels whose current recorded permission is opted in. The view itself sends nothing.
The Service has an outreach feature that can target a saved list by SMS, email, or mail. Today it sends nothing. Every one of those channels is wired to a logging provider that writes a record of the attempt and performs no external communication at all. No voter has ever been contacted through this Service. If that changes, this policy will be updated with the provider's name and what it receives, and the version marker at the top of this document will change.
7. Voters with confidential addresses are excluded
North Carolina protects the address of certain voters. Under N.C.G.S. section 163-82.10(e), a registered voter's address is kept confidential if they give their county board of elections a domestic violence protective order, a restraining order, or a valid authorization card from the state Address Confidentiality Program, together with a statement that publishing their address would endanger them or their family.
The Address Confidentiality Program is established by Chapter 15C of the North Carolina General Statutes and administered by the North Carolina Attorney General. It exists so that victims of domestic violence, sexual offenses, stalking, and human trafficking can be reachable by government without their real address becoming a public record. Participants are given a substitute address, and disclosing or obtaining a participant's real address without authorization is a criminal offense under Chapter 15C.
NCSBE marks these voters in the published file with a confidentiality indicator. Wherever that indicator is set, the Service excludes the voter from every place a campaign could see or use them: the voter browser, every CSV export, the printable walk list, the AI query results, and outreach targeting. The exclusion is enforced twice, once in the ordinary database layer and once in the SQL view the AI feature queries, so a query cannot reach around it.
To be exact about what this does and does not mean:
- These voters are still stored in our database, because they are in the file we load. They are filtered out of every read path, not omitted from the copy.
- The exclusion depends on the flag being set correctly in the NCSBE file. If a voter has protection that is not reflected in the published file, we cannot know about it.
- Excluding a voter here does not affect their status anywhere else. Only the county board of elections can set or change the flag.
If you believe you should be excluded and are not, contact your county board of elections, and contact us at support@competitivecampaigns.com so we can check what our copy of the file says.
8. How long we keep things
We would rather tell you the truth than quote a retention period we do not enforce.
| What | How long |
|---|---|
| Voter registration records | Indefinitely. Records are never hard deleted. When a voter leaves the source file we mark the date they disappeared and keep the record, because saved lists and history may reference it. |
| Vote history records | Indefinitely. These are append-only. NCSBE's file covers a rolling ten-year window; records we loaded are kept after they age out of that window. |
| Absentee ballot records | Replaced in full each time the source file is reloaded for an election. |
| The voter field-change journal | 90 days. This is the record of what changed about a voter between two syncs. A daily job deletes entries older than that. |
| Your account and everything attached to it | Until you delete it. Deleting soft deletes immediately and hard deletes three months later. See below. |
| Account setup and access progress, browser-event claims and reminder queue markers | Until the account is permanently deleted. A temporarily deleted account is excluded from reports and reminders. |
| A request to hear when another state becomes available | Until we send the requested availability notice, you ask us to remove it, or the list is no longer useful for that state. Repeating the request updates the same email-and-state row instead of creating another one. Email support@competitivecampaigns.com to see, correct, or delete it. |
| Saved lists, including strategy-based and current-work recommendation definitions, and derived latest campaign-contact state | Until the campaign is deleted. Hiding or replacing a recommendation records that status but does not delete its definition. Derived latest-contact state is rebuilt from campaign outreach history and is removed with the campaign. |
| Campaign invitations and their delivery records | Invitation links are valid for seven days unless accepted or canceled sooner. The campaign keeps the invitation and email-delivery records until the campaign is deleted. If the invited email belongs to an account that is later deleted, we also delete invitations and delivery records addressed to it. |
| Campaign access history | Until the campaign is deleted. The history remains with a campaign when a teammate deletes their account. It keeps the names and email addresses recorded when access changed so the campaign can tell who granted or removed access. |
| Public volunteer settings, campaign people, event and polling-place signups, public request and browser-session hashes, immutable confirmation receipts, staffing link hashes, management link hashes, delivery journals and items, exact-value email or phone confidence evidence, staff signup confirmation history, pending consent, assignment history, duplicate-merge records, voter-record links, notes, and contact-permission history | Until the campaign is deleted. Contact confidence records the exact normalized email address or phone number that was proved, how and when it was proved, and any revocation time. Editing a contact detail leaves the earlier evidence in history but it no longer verifies the new value. Campaign confirmation and unconfirmation keep the staff actor name and time and do not change whether a volunteer's saved spot counts. A browser-continuity session expires after 30 days and may be revoked sooner; its hash and revocation evidence remain with the campaign. Public request rows remain as replay and revocation tombstones so the same form token cannot create a second action. An unused polling-place email-proof link is valid for no more than seven days and no later than 24 hours after the last selected shift ends. Private polling-place management links expire seven days after the latest assignment they cover. Generic event management links expire no later than 24 hours after the shift and within 90 days. Campaign staff may revoke or replace a link sooner without invalidating an independent link unless they explicitly revoke that link too. We retain link hashes, source, exact-value assurance where applicable, issue, exchange, expiry, revocation, and last-use evidence with the campaign. Raw link secrets are not stored. Used and expired request, receipt, proof-delivery, confidence, and consent-provenance rows remain with the campaign for audit and recovery. If the campaign owner's access ends, new volunteer-interest and polling-place signups pause while existing records remain stored. Existing management links may still cancel an active future assignment, but cannot move it or promote another person without an active plan and account. A campaign may revoke a public staffing link sooner without invalidating private management links. Permission changes and staffing history remain so the campaign can understand what happened over time. |
| Field participants and turf codes | Deleted with the campaign that issued them. A revoked code's record is kept until then, because which codes existed and when they were cut off is the campaign's record of who could reach the field surface. |
| Sessions | Until they expire, you sign out, you change your password, or a password reset completes. Any of those removes them immediately. |
| Password reset tokens | 60 minutes, single use, and all outstanding tokens are deleted when a reset completes. |
| Sign-in attempt records for Google and Apple | Minutes, then deleted about an hour after expiry. |
| Rate-limit counters | Until the window expires, then removed opportunistically. |
| Notification delivery records | Account-linked notification records are deleted with their account. A generic operations reminder sent to a configured staff mailbox without an account may remain in the operations delivery journal. That record contains the staff recipient address, generic subject, send status and an opaque reminder key, not the applicant's identity or campaign choices. If the applicant is erased, the remaining key cannot reopen their account record and any unsent reminder is canceled when the worker next checks it. |
| ActBlue connection, contribution, import, sync, and webhook delivery records | Until the campaign that owns them is deleted. If the campaign owner's access ends, scheduled pulls pause without deleting the encrypted credential, cursor, history, imported contribution data, or catch-up position. Restoring access resumes from that stored position. Finance staff may disconnect CSV API updates sooner, which deletes the encrypted API credential and stops new pulls without deleting contribution history. They may also turn off webhook updates sooner. Uploaded and downloaded CSVs, raw rows, and raw webhook bodies are not retained after processing. |
| Google Analytics event data and imported Google Ads conversions | We set event-data retention in Google Analytics to two months. Google Ads keeps imported conversion and campaign reporting data under its account settings and terms. We do not copy event-level or ad-click data into our database. |
| Administrative audit records | Indefinitely, including after the account they refer to is deleted. This is deliberate: an accountability log that can be erased is not an accountability log. These records contain the affected user's email, display name, and role. |
| Local subscription mirror, minimal Stripe webhook receipts, notification journals, and billing-operation records | Until the account is deleted, except administrative audit records, which remain indefinitely as described above. Permanent account deletion waits for confirmed provider cancellation, then removes these account-linked local records. |
| Stripe's records | Governed independently by Stripe's retention and by the record-keeping obligations that apply to payment records. Canceling a subscription or deleting an account here does not erase Stripe's records. |
What "delete my account" does.
There is a delete button in your account settings, and it works in two stages.
Immediately, when you press it:
- You are signed out on every device.
- Your account can no longer reach any part of the product.
- Any paid subscription is cancelled outright in Stripe, so you are not charged again during the three months that follow. We do not leave billing running through a grace period.
- We email you to confirm, and the email names the exact date your data is erased.
- Nothing is erased yet. Every record listed below is still here, untouched.
Three months later, by a scheduled job:
Everything is permanently erased. We email you a warning a week beforehand, so a deletion you regret and forgot about is not silently final. That email goes out whether or not you have turned off notification email, because it is a notice about permanent data loss rather than a digest.
During those three months, you can change your mind.
Sign in with the same email address and password, or the same Google or Apple account, and we offer to bring the account back. Everything returns exactly as you left it. There is no link to click and nothing to ask us for. An administrator can also restore it for you if you would rather ask.
Your email address stays reserved for the whole three months, so signing up again with it will not work until either you reactivate or the account is erased. This is deliberate: releasing the address would make the account you can still recover unreachable, and would hand your identity to whoever claimed it first.
Exactly what is erased at the end of the three months:
your account record, your sessions, your linked Google and Apple accounts, your password reset tokens, your notification delivery records, your subscription record, your access code redemptions, your legal acceptance records, your campaign memberships, invitations addressed to your email, campaigns you own, the races you created for them, campaign people, their voter-record links, notes, and contact-permission history in those campaigns, ActBlue connection credentials, contribution, import, sync, and webhook delivery records, your saved lists and their members, your saved win scenarios, your tags and every voter you applied them to, and your outreach records.
Exactly what is not erased, and why:
- The North Carolina voter file, vote history, and the voter change journal. These are the public records described in section 5. They are not yours and they are not about you: one copy is shared by every campaign using this Service, and deleting it would break every other campaign's product while doing nothing about the file NCSBE publishes. If you are a voter who wants to be excluded, section 9 explains the mechanism that actually works, and deleting a campaign account here is not it.
- Campaign access history for a campaign you do not own. Removing your account ends your membership, but the campaign keeps the access changes that happened while you were on its team. These records may contain the name and email address stored when the change happened. The campaign owner can delete them by deleting the campaign.
- Attribution on campaign people, duplicate merges, notes, and permission history in a campaign you do not own. Removing your account ends your access, but the campaign keeps the display name recorded when you created or merged a person, wrote a note, or recorded a permission change. Your account id is removed from those records. The campaign owner can delete the records by deleting the campaign.
- Administrative audit records, as described above. They record that an account was deleted, and by whom, and they survive the deletion. An accountability log that can be erased is not an accountability log. These records contain the affected user's email address, display name, and role.
- Anything already delivered. Emails Resend has sent, and any CSV your campaign already downloaded, are outside our control.
- Records Stripe keeps. Cancelling a subscription does not erase Stripe's own record of the payments, which they retain under their own terms and under the record-keeping rules that apply to payment records.
Deleting one campaign deletes what belongs to it. From the campaigns page the campaign owner can delete a single campaign. That removes its team access, access history, pending invitations, campaign people, duplicate-merge records, voter-record links, notes, contact-permission history, ActBlue connection credentials, contributions, import, sync, and webhook delivery records, saved lists, tags, outreach history, win scenarios, turfs and turf assignments, contact programs and packets, field participants and their turf codes, and do-not-contact ledger. None of it is recoverable. Archiving is the alternative: it keeps the campaign saved and read-only and stops it from using a paid campaign slot.
9. Your rights, and how to use them
If you are waiting for another state
Email support@competitivecampaigns.com to ask what state lists include your address, correct the address, stop future notices, or delete the request. We will verify control of the email address before disclosing or changing the record.
If you are a campaign user
You can:
- See and correct your account details. Your name, email, and password are editable in settings.
- Get a copy of your data. Email us and we will export your account record, campaigns, campaign people and their voter-record links, notes, contact-permission history, ActBlue contribution, import, sync, and webhook delivery records, lists, scenarios, and outreach records. We do not include a decrypted ActBlue client secret, webhook password hash, or endpoint key in an export.
- Delete your account. There is a button in your account settings. It closes the account at once and erases everything three months later, and you can undo it at any point in between by signing in. Section 8 sets out exactly what is erased and what is not.
- Pause optional campaign reminders. There is a single switch in the product. Password reset, account access, trial deadline, billing status, security, and data deletion notices are not covered because they communicate a requested account service, access change, payment state, security step, or pending data loss.
- Complain. Email us first. If you are unsatisfied you may contact the North Carolina Attorney General's Consumer Protection Division.
We will respond to any of these within 30 days. We will verify that a request comes from the account holder before acting on it.
If you are a North Carolina voter
You can ask us:
- What we hold about you. Email support@competitivecampaigns.com with your name and county and we will tell you what our copy of the public file contains for you.
- To confirm your exclusion status. If you have a protective order or are enrolled in the Address Confidentiality Program, we will confirm whether our copy shows the confidentiality flag.
We cannot do the following, and we want to be straightforward about why:
- We cannot correct your registration record. Our copy is a mirror of the NCSBE file. If a field is wrong, it is wrong at the source, and correcting it here would be overwritten by the next sync. Contact your county board of elections.
- We cannot make you private by deleting our copy. A deletion here does nothing about the public file, other copies of it held by every other campaign and vendor in the state, or the next sync, which would reload you. The mechanism that actually works is the one North Carolina built for this: a protective order or the Address Confidentiality Program, filed with your county board of elections. Once the flag is set in the published file, this Service excludes you automatically.
- We cannot tell you who contacted you. Campaigns using this Service contact voters using data they export. We do not see or control what they do afterwards.
If a campaign contacted you and you want it to stop, tell that campaign. If you tell us which campaign, we will pass the request on, and repeated failure to honor opt-outs is grounds for us to terminate their account under our Terms of Service.
State privacy laws
North Carolina has not enacted a comprehensive consumer data privacy law. Bills have been introduced and none had passed as of this policy's date. We nonetheless offer the access, correction, and deletion rights described above to anyone who asks.
10. Security, described as it actually is
What is in place:
- All traffic is served over HTTPS, with HTTP Strict Transport Security, clickjacking protection, MIME-sniffing protection, and a restrictive referrer policy.
- Passwords are hashed with bcrypt at cost factor 12 and must be at least 10 characters. Sign-in failures run a dummy hash comparison so a response time cannot reveal whether an account exists.
- Sessions are server-side and revocable. The cookie is HTTP-only, Secure, and SameSite=Lax, and it carries only a signed reference to a session record.
- Every state-changing request must prove it came from our own site. Provider webhook endpoints are exempt and use their configured provider credentials instead.
- Rate limits on sign-in (three separate layers), signup, public volunteer and polling-place forms, public-link checks, password changes, field-code redemption, AI queries, both CSV export paths, outreach, and billing.
- The AI feature runs as a separate Postgres role that can only read a short list of tables and cannot write anything. Each AI query runs inside a transaction that is always rolled back, against a view scoped to that one campaign, with a five-second statement timeout.
- Every voter read is scoped to the campaign's own district, and voters with confidential addresses are excluded at both the application and SQL layers.
- Database network access is restricted to an IP allowlist.
- Administrative actions are recorded in an append-only audit log.
- Anthropic, Resend, Stripe, and automatic ActBlue updates are each optional. With no key or campaign credential configured, the corresponding data never leaves at all.
What is not in place, so you are not misled:
- No SOC 2, ISO 27001, or any other security certification or audit.
- No third-party penetration test and no bug bounty.
- No security monitoring, intrusion detection, or alerting.
- No multi-factor authentication for user accounts.
- Ordinary volunteer forms do not verify email addresses. Polling-place staffing offers optional, request-scoped email proof for self-service management, but the staffing signup is valid and fills a seat without it. Campaign staff may separately record that they confirmed or did not confirm a signup.
- ActBlue client credentials are encrypted at the application layer. Other individual fields rely on the protection provided by the Render managed platform.
- No formal incident response plan or tested backup restoration procedure.
This is a one-person operation and its security posture is the security posture of a one-person operation. Do not put anything into this Service that you would not put into a system with those properties.
If there is a breach. If we discover unauthorized access to personal information about North Carolina residents, we will notify affected people and the North Carolina Attorney General's Consumer Protection Division as required by N.C.G.S. section 75-65, without unreasonable delay.
11. Children
The Service is for adults running political campaigns. We do not knowingly create accounts for anyone under 18. North Carolina lets 16 and 17 year olds preregister to vote under N.C.G.S. section 163-82.1, so the published file may contain a small number of records describing minors. Those records come from the public file and are handled exactly like every other record in it. We do not seek them out and we have no relationship with the people they describe.
12. Where data lives
Our application and product data are stored in the United States, in Render's virginia region. Google Analytics and Google Ads, when enabled, may process the limited measurement data described in sections 3 and 6 outside the United States under Google's own terms and privacy policy. We do not send campaign, candidate, account, or voter data to either service. Our other subprocessors may operate globally; their own policies govern their internal infrastructure.
13. Changes to this policy
The version marker at the top of this document changes whenever the policy does. If we add a materially different analytics provider or expand what analytics receives, we will update this policy before that change takes effect. If the change is material, you will be asked to review and accept it the next time you sign in. Continuing to use the Service after a change means you accept the current version.
14. Contact
Competitive Campaigns LLC support@competitivecampaigns.com
We do not publish a postal address here. If you need a postal address to serve a legal notice or exercise a privacy right, email support@competitivecampaigns.com and we will provide one.
For anything about a voter record, include your name and county so we can find the right record.