> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Opt-In Tool Data & Retention

> What Trackly records when you use the opt-in tool, how long it is kept, and how the consent trail satisfies TCPA evidence needs

This page describes exactly what data Trackly captures when you deploy the
opt-in tool, how long each category is retained, and how the resulting
consent trail is designed to serve as TCPA and carrier-audit evidence.

<Warning>
  This page is informational and is not legal advice. You remain solely
  responsible for the legal adequacy of your consent language, the compliance
  of your messaging program, and the content of any end-user-facing disclosures
  on the properties where you deploy the opt-in tool. See the
  [Terms of Service](https://tracklysms.com/terms) and
  [Privacy Policy](https://tracklysms.com/privacy) for the binding terms.
</Warning>

## What counts as the opt-in tool

The opt-in tool includes every intake channel the platform offers for
capturing a new SMS subscriber:

| Channel                | Description                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------- |
| Popup widget           | Script-tag embedded popup with configurable triggers (delay, exit intent, form submit)      |
| Inline form            | Script-tag embedded standalone form that renders inline on the page                         |
| Form-field injection   | Phone field injected into an existing form on your site                                     |
| Hosted landing page    | Standalone responsive page at `/optin/page/<public_token>`                                  |
| Subscribe link         | Short URL (`/s/<slug>`) that redirects mobile to `sms:` URI and desktop to the hosted page  |
| Keyword (text-to-join) | Inbound keyword routed via your provider number; supports double opt-in                     |
| QR code                | PNG/SVG encoding of the `sms:` URI for a keyword campaign                                   |
| Opt-in webhook         | `POST /api/v2/optins/webhook` — API-key-authenticated intake for third-party form platforms |

Every channel writes to the same underlying consent-record schema, so the
retention and export rules below apply uniformly.

## Data captured at impression (pre-consent)

Each time a visitor *sees* the widget — whether or not they submit — Trackly
records an impression event used for creative A/B optimization, fraud
detection, and rate-limiting.

| Field                 | Description                                       |
| --------------------- | ------------------------------------------------- |
| `ip_address`          | Visitor's IP address                              |
| `user_agent`          | Browser user-agent string                         |
| `page_url`            | URL of the page where the widget was displayed    |
| `optin_configuration` | Reference to your opt-in campaign                 |
| `optin_creative`      | Reference to the creative variant shown (for A/B) |
| `created_at`          | Impression timestamp                              |

<Note>
  **Retention:** Impression events are automatically deleted **90 days** after
  creation via a time-to-live (TTL) index on the database collection. There is
  no option to extend this — the window is a platform-level default.
</Note>

## Data captured on successful opt-in (consent record)

When a visitor opts in through any channel above, Trackly creates a
**tamper-evident consent record** designed to serve as TCPA evidence. The
fields populated depend on the channel: a **web-widget** opt-in (popup, inline
form, field injection, hosted page, subscribe link) freezes the full set —
including the visitor's IP, user-agent, page, and the creative they saw.
**Keyword** and **webhook** opt-ins have no browser or rendered page, so they
record a smaller set (see the **Captured by** column).

### Fields on a consent record

| Field                   | Description                                                                                                                                                                                                                                   | Captured by           |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `phone_number`          | E.164 phone number submitted                                                                                                                                                                                                                  | All channels          |
| `compliance_text_shown` | **Frozen** verbatim copy of the consent disclosure text at the moment of submission. Web widget: the disclosure shown on-page. Keyword: the configured auto-reply text (**empty if none is set**). Webhook: the text supplied in the payload. | All channels          |
| `headline_shown`        | Frozen copy of the creative headline shown                                                                                                                                                                                                    | Web widget only       |
| `body_text_shown`       | Frozen copy of the creative body text shown                                                                                                                                                                                                   | Web widget only       |
| `ip_address`            | IP address of the submitting device                                                                                                                                                                                                           | Web widget only       |
| `user_agent`            | Browser user-agent string                                                                                                                                                                                                                     | Web widget only       |
| `page_url`              | URL of the page where consent was submitted                                                                                                                                                                                                   | Web widget only       |
| `consent_source`        | Channel identifier — `widget`, `keyword`, `webhook`, `subscribe_link`, and similar                                                                                                                                                            | All channels          |
| `created_at`            | Timestamp when the record was created on Trackly's servers                                                                                                                                                                                    | All channels          |
| `consent_timestamp`     | Timestamp when consent was actually given (may differ from `created_at` for webhook intake — see below)                                                                                                                                       | Webhook only          |
| `status`                | `confirmed`, `pending_confirmation`, or `expired` (double opt-in)                                                                                                                                                                             | All channels          |
| `expires_at`            | Cutoff 24 hours after a pending take, after which a late confirmation reply is rejected                                                                                                                                                       | Keyword double opt-in |
| `optin_consent`         | Reference to the consent-text template version in effect at submission                                                                                                                                                                        | Web widget only       |
| `optin_creative`        | Reference to the creative variant shown                                                                                                                                                                                                       | Web widget only       |
| `optin_configuration`   | Reference to your opt-in campaign                                                                                                                                                                                                             | All channels¹         |
| `custom_fields`         | Any additional fields you or the third-party platform submit                                                                                                                                                                                  | All channels          |

¹ For webhook intake, `optin_configuration` is set only if the caller passes an `optinConfigurationId`.

<Note>
  Fields marked **Web widget only** require a Trackly-rendered page and the
  visitor's browser. SMS-keyword and webhook opt-ins have no page or browser
  context, so those fields are left empty on those records.
</Note>

### Why fields are "frozen"

Trackly stores the consent disclosure text and creative as **independent
copies on each record** rather than as references. Even if you later edit
the campaign's consent language or delete a creative, every prior consent
record continues to reflect the exact text that each specific visitor saw
at their moment of submission. Superseded versions of the consent-text
template are archived rather than deleted.

<Note>
  **Retention:** Consent records are retained **indefinitely** for the lifetime
  of your account and, following account termination, for any additional period
  reasonable for defense against consent-related claims. This retention applies
  as a legal-compliance / evidentiary-preservation exception under applicable
  privacy laws and may, to the extent permitted by law, override individual
  end-user deletion or erasure requests.
</Note>

## Double opt-in evidence

When a campaign has double opt-in enabled (recommended for keyword
campaigns), the consent trail is split across two records:

<Steps>
  <Step title="Initial take is recorded with status `pending_confirmation`">
    On the first opt-in submission, Trackly writes a consent record with
    `status = pending_confirmation` and `expires_at` set to 24 hours in the
    future. No marketing messages are sent. The system sends a single
    confirmation prompt (e.g. "Reply Y to confirm").
  </Step>

  <Step title="Inbound confirmation is routed to the pending record">
    When the visitor replies `Y`, `YES`, or `CONFIRM` within 24 hours, the
    record is promoted to `status = confirmed`. The confirmation reply itself
    is stored as part of the message log, so the trail includes both the
    original submission and the affirmative confirmation.
  </Step>

  <Step title="Unconfirmed records are never enrolled">
    A pending record stays `pending_confirmation` until the visitor replies. If
    they reply *after* the 24-hour window, the confirmation is rejected and the
    record is marked `status = expired` at that point. If they never reply, the
    record remains `pending_confirmation` indefinitely — there is no background
    job that expires it on a timer. Either way the visitor is never enrolled in
    marketing journeys, and records are preserved, not deleted.
  </Step>
</Steps>

## Webhook intake from third-party platforms

The opt-in webhook (`POST /api/v2/optins/webhook`) lets third-party form
platforms (Zapier, Make.com, Unbounce, Carrd, Typeform, and similar) submit
opt-ins to Trackly directly. Webhook intake has two differences from
widget-originated opt-ins:

1. **Separate `consent_timestamp`** — the third-party platform transmits the
   timestamp at which consent was actually given on their side. This is
   stored separately from `created_at` (when Trackly received the webhook),
   so a backfilled or delayed transmission still reflects the true consent
   moment.
2. **Platform-transmitted `consent_text`** — because Trackly never rendered
   a widget in this case, the consent disclosure text comes from the webhook
   payload and is frozen into `compliance_text_shown` as-is. You are
   responsible for ensuring the third-party platform transmits the correct
   consent text your visitor actually agreed to.

<Warning>
  If a third-party platform transmits an inaccurate `consentText` or
  `consentTimestamp`, the resulting Trackly consent record will reflect that
  inaccuracy. The webhook is a pass-through; Trackly does not and cannot
  validate that the transmitted values match what the visitor actually saw
  on the third-party platform. You are solely responsible for the integrity
  of any webhook-sourced consent record.
</Warning>

## Your disclosure obligations

Because the opt-in widget is embedded on properties you control, applicable
law (including the CCPA, the GDPR, and state telemarketing and privacy
statutes) generally requires *you* — not Trackly — to disclose to your site
visitors the data-handling practices associated with the widget.

At minimum, the privacy policy of each property where you deploy the widget
should disclose:

<AccordionGroup>
  <Accordion title="That a third-party service provider is embedded">
    Identify Trackly SMS as a third-party service provider or data processor
    that collects data via an embedded widget on the property.
  </Accordion>

  <Accordion title="Categories of data collected">
    IP address, browser user-agent, page URL, the submitted phone number,
    and any custom fields your campaign configures.
  </Accordion>

  <Accordion title="Purposes of processing">
    Impression logging, creative optimization, fraud detection, double
    opt-in confirmation, and retention of consent records as evidence.
  </Accordion>

  <Accordion title="Retention practices">
    Impression data is retained for 90 days; consent records are retained
    indefinitely as consent evidence.
  </Accordion>

  <Accordion title="Cross-border transfers">
    Data is transferred to and processed in the United States, where
    Trackly's services are hosted.
  </Accordion>

  <Accordion title="Contact for rights requests">
    Provide a contact for end-user requests to access, correct, or delete
    their data, subject to legal-compliance exceptions.
  </Accordion>
</AccordionGroup>

## Exporting consent evidence for an audit

If a carrier, regulator, plaintiff, or arbitrator asks you to produce the
consent record for a specific phone number, the frozen fields above are
what you produce. In the current release, export paths are:

* **Dashboard lookup** — opt-in records for each contact are visible in the
  Contact Lookup view alongside signup metadata.
* **API** — opt-in records can be read through the admin API under
  `/api/optins/configurations` and related endpoints.
* **Support-assisted export** — for high-urgency audit or discovery
  requests, email [support@tracklysms.com](mailto:support@tracklysms.com)
  with the relevant phone numbers and we will produce a consent-record
  export.

<Warning>
  Trackly makes no representation that any consent record is sufficient to
  establish prior express written consent under the TCPA or any other law.
  Carriers, regulators, and courts apply their own standards. The consent
  record is designed to preserve the maximum amount of evidence, but its
  sufficiency in any specific dispute is a legal question that depends on
  the content of your consent language and the facts of the submission.
  See the [Terms of Service, Section 12](https://tracklysms.com/terms) for
  the full allocation of responsibility.
</Warning>

## Deletion and erasure requests

End-users occasionally submit deletion or erasure requests under the CCPA,
the GDPR, or state privacy laws. Because consent records serve as legal
evidence against future TCPA claims, Trackly treats them under a
**legal-compliance retention exception**:

* **Impression records** — deleted automatically after 90 days, and can be
  deleted earlier on request.
* **Consent records** — retained indefinitely. To the extent permitted by
  applicable law, a request to delete a consent record may be declined or
  partially honored while the underlying legal-evidence purpose persists.
  Where permitted, Trackly may instead restrict processing (e.g., flag the
  record as non-sendable while preserving the evidence).
* **Contact Data downstream of the opt-in** — the resulting `Contact` and
  `ListContact` entries created by the opt-in are governed by the normal
  contact data retention and deletion rules; they can be deleted or
  unsubscribed independently of the consent record.

Coordinate deletion requests with our support team so that the
legal-evidence exception is applied consistently and documented.

## Related pages

<CardGroup cols={2}>
  <Card title="Compliance & TCPA" icon="shield" href="/concepts/compliance">
    STOP handling, quiet hours, and consent fundamentals
  </Card>

  <Card title="Privacy Policy" icon="file-shield" href="https://tracklysms.com/privacy">
    Full customer-facing privacy policy
  </Card>

  <Card title="Terms of Service" icon="scale-balanced" href="https://tracklysms.com/terms">
    Full Terms of Service, including §12, §13, §26, and §27
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:support@tracklysms.com">
    Request a consent-record export for audit purposes
  </Card>
</CardGroup>
