Legal
Jule Privacy Policy
Effective date: September 18, 2026
This policy explains what information Jule collects on its own websites and Dashboard, what the Jule widget does in a visitor’s browser on our customers’ websites, who we share information with, how long we keep it, and the choices you have.
See also our Terms of Service.
1. Who we are and what this policy covers
Jule LLC (“Jule”, “we”, “us”, or “our”) is a Delaware limited liability company. We build a platform that lets businesses create on-site pop-ups, forms, quizzes, surveys, coupon experiences, A/B tests and hosted preference centers, and connect what those experiences collect to marketing and commerce tools such as Iterable, Shopify and Stripe. We call all of this, together with our websites, documentation, dashboard, APIs and embeddable widget script, the “Services”.
This policy describes how we collect, use, share and protect personal information in connection with the Services. It applies to our marketing website at jule.ai and www.jule.ai, our documentation at docs.jule.ai, our application dashboard at app.jule.ai and jule.ai/app (the “Dashboard”), our API at api.jule.ai, our asset host at assets.jule.ai, our internal administration console at admin.jule.ai, the preview versions of these sites, the Jule widget script (widget.js) that our customers embed on their own websites, and the preference centers we host for our customers, whether they are served from a Jule address or from a customer’s own custom domain pointed at cname.jule.ai.
If you have a signed agreement with us that includes a Data Protection Addendum, that agreement governs our processing of your data as a service provider and prevails over this policy to the extent of any conflict.
2. Summary
Jule is a business-to-business service. The people whose information we handle fall into two groups, and our role is different for each.
When you visit our websites, read our documentation, subscribe to our newsletter, book a demo, contact us, or create and use a Jule account, we decide how and why your information is used. In privacy law terms we are the “controller” or “business” for that information.
When you interact with a pop-up, form, quiz, survey, coupon or preference center that one of our customers has built with Jule and placed on their own website or preference center address, that customer decides what is collected and why. We collect that information, transmit it to the destinations the customer chooses (their Iterable account, their Shopify or Stripe account, or their own webhook endpoints), and in some cases store it for the customer, for example coupon records, SMS consent records and usage analytics, all on the customer’s behalf and on the customer’s instructions. In privacy law terms the customer is the controller or business and Jule is a “processor” or “service provider”. The customer’s own privacy policy governs that information, and requests about it should go to the customer. Section 6 describes exactly what our widget does in your browser and what reaches our servers.
We do not sell personal information. We do not share personal information for cross-context behavioral advertising. We do not use personal information for targeted advertising. We do not use the information our customers collect through Jule to train artificial intelligence or machine learning models, and we do not run such models on that information; the only automated analysis we perform on it is statistical, such as computing A/B test results from aggregate counts, and we will update this policy before introducing any feature that applies such models to that information. We do not send marketing to our customers’ end users from our own systems. Where a customer has configured it, our servers instruct the customer’s Iterable account to send an SMS opt-in confirmation or to record an event that may start a campaign the customer has set up there.
3. Information we collect from visitors to our websites
3.1 Analytics
Every page of our web application, which includes jule.ai (including the sign-in, registration and legal pages), docs.jule.ai, the Dashboard, our preview sites, and the preference centers we render through our web application on customers’ custom domains, loads Google Analytics 4 under measurement ID G-3BZB5LQBLG when the page opens. Google Analytics uses cookies (for example the _ga and _ga_<container-id> cookies) and collects information such as the pages you view, the site that referred you, the time and duration of your visit, your browser and device type, your screen size, and an approximate location derived from your IP address. Google processes this information for us under Google’s terms and its own privacy policy. We use it to understand how our sites are used and to improve them. Our only advertising tag is the measurement pixel described in section 3.7, which runs only if you allow it. Google Analytics records the address of each page it loads on, so where a page address contains a token or identifier from a link you clicked, such as a password reset link, that address may be recorded.
On our public websites Google Analytics does not run until you allow it. The first time you visit we show a cookie bar, and we load Google Analytics only if you choose Analytics Only or Allow All; if you choose Decline, nothing is loaded and no analytics event is sent. Your choice is kept in a jule_cookie_consent cookie for one year, and you can change it at any time through the Cookie Settings link in our website footer. Withdrawing it also clears the Google Analytics cookies from your browser.
You can also prevent Google Analytics from running by installing the Google Analytics Opt-out Browser Add-on, by blocking the googletagmanager.com and google-analytics.com domains in your browser or with a content blocker, or by clearing and refusing cookies in your browser settings. Our sites work normally without it.
3.2 Error monitoring
Our websites and Dashboard use Sentry to capture errors, performance traces of page loads and route changes, and diagnostic logs so we can find and fix problems. Before an event leaves your browser or our servers we run it through a scrubber that replaces email addresses, identifiers, phone numbers and long digit sequences with placeholders, and in our web application the scrubber also removes the query string and fragment from request URLs, page addresses and network request descriptions, so that password reset tokens and email addresses that may appear in a page address are not transmitted. We have turned off Sentry’s option to send default personal information. Sentry traffic from our pages is sent through our own domain rather than directly to Sentry, so blocking Sentry’s domains in your browser does not stop it. Inside the Dashboard only, after you sign in, we also enable Sentry Session Replay for a sample of sessions (one in ten, and every session in which an error occurs) with all text, all form inputs and all media masked, so that a replay shows the layout of the page, the page addresses visited and the sequence of interactions but not the content you typed or viewed. Session Replay is not started on public pages; it begins only when the signed-in Dashboard loads, although a recording that has already started continues if you move from the Dashboard to another page of our site without reloading. The Dashboard also counts how many reports it sends to Sentry and reports the totals to us with your organization’s identifier so that we can allocate the cost; the counts contain no personal information. Error reports from our servers are labelled with the identifier of the organization whose request produced them so that we can trace a problem to the right account.
3.3 Newsletter
If you enter your email address in the newsletter form on jule.ai, we store that address and the time you subscribed in our database and use it to send you product news. You can unsubscribe at any time by emailing hey@jule.ai.
3.4 Booking a demo
The “Book a Demo” links on our website open a Google Calendar appointment scheduling page, and the /activate page embeds that scheduling page in a frame. Anything you enter there, such as your name, email address and the time you choose, is collected by Google Calendar under Google’s privacy policy and delivered to us as the owner of the calendar. We use it to hold the meeting and follow up with you.
3.5 Contacting us
If you email hey@jule.ai or otherwise write to us, we keep the correspondence and use it to respond to you.
3.6 Server logs, security and content delivery
Like nearly every online service, our hosting and network providers record technical information about requests to our sites and API, including the IP address, browser user agent string, requested address, timestamp and response status, and we use it for security, rate limiting, abuse prevention and troubleshooting. Our own application logs are configured to redact credentials, email addresses and phone numbers and to record a hashed identifier in place of an email address. For signed-in requests our application log records your user identifier and the organization, workspace and project the request concerned, together with the route, status and duration. Rate limits on our API are applied per IP address.
Our API also keeps an audit log of read requests to certain resources (see section 4.2). Because some public endpoints sit on the same audited resources, a request from the sign-in and registration pages of jule.ai, and a request the widget makes to load its configuration on a customer’s website, are currently recorded in that log with the requesting IP address and browser user agent, with no account identifier attached. Those entries are kept for the audit log retention period described in section 8.
Some content on our sites is delivered from third-party networks. The animations on our sites load a runtime file from the unpkg content delivery network, falling back to the jsDelivr network if unpkg is unavailable. Images and fonts that our customers upload, the widget script that customers place on their own websites, and the phone number input library that every page of our web application loads are served from assets.jule.ai on Cloudflare’s network, while our sites themselves are hosted by Vercel. Those providers see the technical request information described above when your browser fetches those files, and our web application writes its own operational logs at our hosting provider, for example when it resolves a customer’s custom domain. Fonts used on our own pages are bundled at build time and served from our own domain.
3.7 Advertising measurement
Our public websites can load OpenAI’s advertising measurement pixel (pixel ID 623UHxs86aAV97mkqrrEN1, served from bzrcdn.openai.com). It tells us whether people who saw or clicked our ads in OpenAI’s products later visit our sites or request a demo. It never loads in the Dashboard or on preference centers hosted on customers’ custom domains.
The pixel loads only if you choose Allow All in the cookie bar. Analytics Only and Decline keep it off. When it runs, it reports to OpenAI each page you view, when you open a product demo, and when you submit the Book a Demo form. OpenAI also receives the technical information your browser sends with each request, such as your IP address and browser type. If you arrived from one of our ads, the pixel keeps the ad click identifier in an __oppref cookie on our domain. OpenAI processes this information under its own terms and privacy policy, and it may use its own cookies on openai.com to connect the visit to an OpenAI account.
You can change your choice at any time through the Cookie Settings link in our website footer. Switching to Analytics Only or Decline turns the pixel off and clears the __oppref cookie from our domain. Cookies that OpenAI sets on its own domains are controlled by OpenAI and by your browser settings.
4. Information we collect when you create and use a Jule account
4.1 Registration and profile
To create an account you give us your first and last name, your work email address (which we verify with a six-digit code sent to that address and valid for fifteen minutes), a password, your role or profession (or a custom description), your company name, your company size, the Jule features you plan to use, and optionally a description of your use case. We derive your organization’s domain from your work email address. You may later add a profile picture, which is stored with our other uploaded assets and is reachable by anyone who has its address, and a phone number. Nothing is stored about you until you complete registration; the verification step is carried in signed tokens rather than in our database.
New accounts are placed in a queue for review by Jule, and sign-in is refused while an account is marked as awaiting approval. When a new account is created we send an internal notification to our team containing the registration details so that we can review it. If we decline an account, the registration details are not deleted automatically; we keep them until you ask us to delete them or we remove them ourselves. People who join an existing organization through an invitation are activated by the invitation itself.
We store your password only as a bcrypt hash. We never store or see the password itself.
4.2 Security information
If you enable two-factor authentication we store the secret for your authenticator app in encrypted form and store your backup codes as one-way hashes, so that a code can be checked but not read. For every sign-in session we record a hashed session token, the IP address and browser user agent of the device, and the time the session was created and last used, so that we can detect misuse and end sessions; changing your password signs out every other device. Ten failed sign-in attempts for an email address lock sign-in for that address for fifteen minutes.
We also keep an audit log of security-relevant and administrative activity in your account, such as sign-ins and failed sign-ins, password and two-factor changes, the creation, modification and deletion of roles, the creation of integrations and changes to webhook destinations, deletions of projects, workspaces, organizations and users, coupon redemptions, and reads of account, organization, workspace, project, trigger and analytics resources. Each entry records the action, the acting user, the affected resource and the time, and, where the request provides them, the IP address, browser user agent, and request path and query parameters. Entries carry a keyed cryptographic hash of their core fields that is chained to the previous entry, and our database rejects ordinary updates and deletions of audit rows, so that tampering with those fields can be detected.
4.3 Organization, workspace and team information
We store the names, domains and favicons of the organizations and workspaces you create, the branding you configure (logos, colors, fonts, header and footer content, the addresses of your own terms and privacy policy, and any SMS disclaimer text), the roles and permissions you assign, and the email addresses and roles of the people you invite. Invitees receive an email from us on your behalf with a link that expires after seven days. The invitation link is also shown to the administrator who sent it, and anyone who opens the link is added to the organization, so it should be shared only with the intended person.
4.4 Content and assets
We store the pop-ups, forms, preference centers, templates, custom HTML and scripts, copy, translations, triggers, experiments and coupon configurations you create, together with the thirty most recent saved versions of each project, each recording who made the change and when. Images and font files you upload are re-encoded where applicable and stored in Cloudflare R2 object storage under random identifiers, and are served publicly from assets.jule.ai because they need to be displayed to visitors of your website.
4.5 Integration credentials
When you connect a third-party service we store the credentials needed to act on your behalf: your Iterable API key and optional Iterable signing secret; the access token and refresh token Shopify issues when you install our app on your store (or an access token and webhook secret you paste from a custom Shopify app), together with the secret used to verify Shopify’s webhooks; the restricted API key you create for your Stripe account and the signing secret of the webhook endpoint we register in your Stripe account; and, for outbound webhook destinations, the signing secret we generate for each destination (and, for a short window after you rotate it, the previous one) plus the custom headers and named secrets you configure. All of these are encrypted at rest with AES-256-GCM using a key that is held separately from the database. Webhook signing secrets are shown to you once at creation and cannot be retrieved afterwards, Stripe keys are displayed only in masked form, and Shopify tokens are never displayed. The token for the coupon data feed and the coupon API key are stored only as one-way hashes. The public workspace key that identifies your workspace to the widget is not a secret and is stored in plain form.
4.6 Plan, usage and commercial information
We record which plan tier your organization is on (we currently offer an Essential tier and a Full tier) and, when applying plan limits, count the projects, workspaces and seats your organization holds. We also meter the infrastructure your organization consumes (for example requests served, database and storage footprint, analytics events ingested and queries run, Iterable calls made, preference center views and error reports generated) so that we can understand and allocate our own costs. This metering counts events per organization where the organization can be determined, is stored as aggregated totals, and does not contain personal information about your visitors; transactional emails are counted in total rather than attributed to an organization. Our administrators may also record commercial information about your organization, such as an estimate of the monthly revenue your account represents, for account management and cost reporting.
4.7 Administration and support
Our administrators can view and manage account records, including your profile, organization memberships, sign-in history and audit trail, in order to review new accounts, provide support, investigate security issues and keep the Services running. They can approve or decline accounts, force a password reset or email verification, disable two-factor authentication, suspend or delete accounts, cancel a deletion request, change an organization’s plan tier, regenerate workspace keys, and edit or delete organizations, workspaces and integrations. Administrative access to account records is written to the audit log, as are the most sensitive administrative changes, such as deleting a user, forcing a password or two-factor reset, changing administrator status, suspending an account, changing a plan tier and recording revenue estimates.
4.8 Cookies and browser storage used by the Dashboard
The Dashboard sets three cookies, which may carry an environment prefix in their names. The accessToken cookie is an HttpOnly cookie containing a signed token that identifies your account and session (it includes your user ID and email address); it expires after fifteen minutes and is silently renewed while you are active, and when you sign out the token is placed on a block list for its remaining lifetime. The refreshToken cookie is an HttpOnly cookie used to obtain new access tokens; it expires after seven days and is rotated when used (a just-replaced token presented within one minute, as can happen with several open tabs, is honored once), and signing out or changing your password from the Dashboard invalidates it on our servers, although resetting a forgotten password through the emailed link does not end sessions that were already signed in. The session-version cookie is a readable counter that lets multiple open tabs coordinate token renewal and expires after seven days. In production all three are marked Secure, use SameSite=Lax, and are set for the jule.ai domain and its subdomains.
The Dashboard also uses your browser’s localStorage to remember the organization and workspace you last selected and interface preferences such as analytics chart layouts, selected date ranges and dismissed tips. Google Analytics cookies are described in section 3.1.
Some Dashboard pages load third-party content. The branding font picker previews fonts from Google Fonts, the editor’s preview of an experience that uses a Google Font loads that font from Google Fonts, the animated mascot loads a runtime file from the unpkg network (with a jsDelivr fallback), and the embed instructions in the Integrations tab include a video hosted by YouTube, which may set its own cookies when it loads.
4.9 Transactional email
We send email to account holders to deliver sign-up verification codes and verification links (valid for twenty-four hours), confirm account approval, reset passwords (links expire after one hour), deliver invitations, notify you when an administrator adds you to an organization, confirm, cancel and complete account deletion requests, announce plan changes, report A/B test results and warn when coupon inventory is running low. These messages are sent from our Google account through Gmail’s SMTP service and, while queued for sending, are held encrypted in our job queue for at most one hour after delivery or twenty-four hours after a failure.
5. Information we receive from connected services you authorize
5.1 Iterable
When you connect Iterable, we use your API key to read your lists, channels, message types, custom fields and campaign metadata so that you can map form fields and build preference centers, and to read an individual subscriber’s profile and subscription state when an experience needs them. When you test a connection before saving it, we send the key you pasted to Iterable once to confirm it works, and it is not stored until you save. We send to Iterable, in the region (United States or Europe) you selected, the data your visitors submit through the experiences you configure and the coupon activity Jule records for them: profile updates, list subscriptions and unsubscriptions, channel and message type preferences, tracked events, SMS double opt-in requests, and, when coupon synchronization is enabled, coupon codes, their status and expiry, QR image addresses and phone numbers. Profile updates, list unsubscriptions and tracked events identify a person by either their email address or their Iterable user ID, using the email address when both are known; subscription updates made by a form’s subscribe action and SMS double opt-in requests include both identifiers when both are known. Jule also writes some of its own fields to the profiles it updates in your account: on a form submission, a signup source of “jule_widget”, the signup date and the project name when a profile is created, and the name of the last project and the date of the last submission when a profile is updated; and, when coupon synchronization is enabled, the coupon fields listed above under a field prefix you choose, using the phone number as the Iterable user ID when no email address is known. The tracked event configured for a form is tagged with the project name; other events are not. Iterable is a service you select and contract with directly, and its processing of that data is governed by your agreement with Iterable.
5.2 Shopify
When you install the Jule app on a Shopify store we request the write_discounts scope, which lets us create and deactivate discount codes in your store so that codes handed out by Jule work at checkout, and the read_orders scope, which lets us receive the orders/paid and refunds/create webhooks so we can detect when a Jule-issued code is redeemed or refunded. The order notification Shopify sends us contains the full order, but we read only the order identifier and name, the order total, the discount codes applied, and the order’s email address, and we do not store or log the rest. We do not request access to your customer records and we do not build customer profiles from order data. We use the email address to match the redemption to the code we issued; where the code is a shared code you configured (a static or fallback code) and we hold no earlier record for that shopper, we create a redemption record holding the email address, order identifier and order value. A refund does not undo a redemption; we flag the redemption record as refunded. We store your store domain, the access token Shopify issues and the refresh token used to renew it, encrypted as described in section 4.5, and we renew the access token automatically. If you install from the Shopify App Store before signing in to Jule, we hold the access token, encrypted as described in section 4.5, in our cache for up to seven days so that you can claim the store from your Dashboard. If more than one Jule organization has connected the same store, each order notification is applied to every one of them, and redaction requests are applied across all of them.
We honor Shopify’s mandatory compliance webhooks. On a customers/data_request we record the request together with a count of the coupon records that hold that customer’s email address or phone number, and our team compiles those records and provides them to you within Shopify’s response window. On a customers/redact we replace that customer’s email address on our coupon records with a fixed placeholder and remove the phone number, while keeping the non-identifying redemption statistics. When you disconnect the store from your Dashboard we delete the store’s integration record, including its tokens and configuration, and when Shopify sends a shop/redact after an uninstall we delete any remaining integration record for the store and any parked install token.
5.3 Stripe
When you connect Stripe we use the restricted API key you provide to create coupons and promotion codes in your Stripe account, to deactivate promotion codes when they expire or a coupon is archived, to read your account’s default currency and whether the key is in live or test mode, to register a webhook endpoint in your account that sends us checkout, invoice and refund events, and, once a day, to compare Stripe’s redemption counts with ours. Each promotion code we create carries your Jule coupon and organization identifiers in its metadata. From the events we receive we read the promotion codes applied, the order or session identifier, the amount, and the customer email address on the purchase. We use the email address to match the redemption to the code we issued; where the code is a shared code you configured and we hold no earlier record for that customer, we create a redemption record holding the email address, purchase identifier and amount. A refund does not undo a redemption; we flag the redemption record as refunded. We store the key and the signing secret of the webhook endpoint encrypted as described in section 4.5. Your use of Stripe is governed by your agreement with Stripe.
5.4 Webhook destinations
You may configure your own HTTPS endpoints to receive form submissions, subscription changes, preference changes and notices that an SMS double opt-in confirmation was requested for a phone number. We deliver the fields you select in the body template you define, which can include every answer a visitor submitted and the visitor’s resolved identity, signed with an HMAC-SHA256 signature so that your server can verify it came from us. Destinations must be public HTTPS addresses; we refuse private network and loopback addresses and do not follow redirects. Outbound webhooks are sent only after you switch them on for your workspace, and each request can include the custom headers and named secrets you configured for the destination. If your endpoint rejects a delivery we keep the first four kilobytes of its response, encrypted, with the delivery record for troubleshooting, and we retry only when your endpoint returns a rate limit or server error. Section 8 describes how long delivery records are kept.
5.5 AI assistants and developer tools
You may connect AI assistants and developer tools (for example Claude, ChatGPT, Cursor or a script you run yourself) to your Jule account through Jule’s MCP server at api.jule.ai/mcp. A connection is created only when you sign in to Jule from the assistant and approve the permissions it asks for, or when you create a personal access token under Settings → Connected Apps and give it to the tool yourself. When you approve a connection you may limit it to read-only access, and a token carries only the permissions you select. From then on the assistant can read and change the same Jule data you can, within the organization you chose and the permissions you granted: your account and workspaces, projects and their content, templates, triggers, A/B tests, coupons and coupon codes, branding settings and files, webhook settings, analytics, and the lists, channels and profile fields of a connected Iterable account. The assistant sends us the details of each action it asks us to carry out, such as the content of a pop-up you asked it to build. We do not receive your conversation with the assistant beyond those requests. The assistant is operated by its provider, not by Jule, under that provider’s terms and privacy policy.
For each connection we store the assistant’s identity, the permissions you granted, the organization, when the connection was created and last used, and how many calls it has made. For a connection made by signing in we also store the IP address and user agent the assistant connected from, and for a token the name you gave it and its expiry date. Each call that changes something is written to the audit log described in section 4.2 with the action, the user, the assistant, the outcome and the time; calls that only read data are counted but not written to the audit log. We also record capabilities requested through an AI connection that Jule could not provide, to improve the product: the area of the product, a description of the capability written by the assistant, why it could not be done, any workaround the assistant used, how often it was asked for, and which organization, workspace, user and assistant reported it. We ask the assistant to describe only the capability, without names, email addresses, phone numbers, customer web addresses or text copied from your conversation. We do not use the content of your requests to train models.
We do not share your data with the assistant’s provider except in response to requests the assistant makes on your behalf. The service providers listed in section 9.1 process this data as they process the rest of your Jule data. A connection made by signing in expires after ninety days without use, and a personal access token expires after the period you choose when you create it, at most one year. You can revoke a connection or a token at any time under Settings → Connected Apps, and revocation takes effect immediately. Audit log entries follow the retention period in section 8, and projects or other content created through an assistant are your account data and follow the retention rules there as well. Only users whose role includes the Connect AI Tools permission can connect an assistant or create a token, and only users whose role includes Manage AI Connections can see and revoke every connection in the organization; by default administrators have both and members have Connect AI Tools. Questions about AI connections: support@jule.ai.
6. Information we process on behalf of our customers through the widget and hosted preference centers
This section describes what happens when you, as a visitor to one of our customers’ websites, interact with an experience built with Jule. Jule handles this information as a processor and service provider for that customer. The customer’s privacy policy tells you how they use it, and requests to access, correct or delete it should go to the customer. We give our customers reasonable assistance in responding to such requests.
6.1 What you submit
Our customer decides which fields their experience contains. Depending on the experience, you may be asked for an email address, a phone number, a name, answers to quiz or survey questions, your communication preferences (which lists, channels and message types you want to receive), and your consent choices. Phone numbers are validated in your browser and transmitted only in international E.164 format; a number that cannot be validated is not sent. When you provide a phone number in a form that displays an SMS disclaimer and the customer has mapped that field to the phone number on their Iterable profiles, we store, on the customer’s behalf, a consent record holding an encrypted copy of the number, a one-way hash of the number used as a lookup key, the SMS disclaimer text in effect for the customer’s account when the submission is processed, the identifiers of the submission, project and workspace, and the time. The lookup hash is a plain hash of the number and is not itself a privacy protection; the number is protected by its encryption. For twenty-four hours after an opt-in text is requested we also hold the number itself in our cache so that a duplicate request is not sent.
Apart from the transient delivery copies described below, the coupon records described in section 6.3 and the SMS consent records described above, your form answers are not stored as records in our database. When you submit, the answers are placed in an encrypted job queue and delivered to the destinations the customer configured, such as the customer’s Iterable account or webhook endpoint. A successfully delivered submission is kept in the queue for at most one hour and a failed one for at most twenty-four hours. Our delivery logs keep an encrypted copy of the delivery payload for about twenty-four hours so that a failed delivery can be retried; an hourly job then removes it and only non-identifying delivery metadata remains. If a form has no email field but you previously submitted an email address on the same website, the widget attaches that remembered address to the submission so that it can be matched to your profile, and if no identity is known our servers treat an answer that looks like an email address as your email address when delivering to webhook destinations.
In a multi-page experience some information may reach our servers before you press the final button. When you move to the next page, an email address you entered is sent to our API for the deliverability check described in section 6.7, and if the customer has configured page-level profile updates or event tracking, the answers collected so far are sent to our API when a new page appears and your email address is already known, and are used to update your profile or record the configured event in the customer’s Iterable account.
6.2 How you may be identified
A customer’s website may tell the widget who you are by setting a JULE_USER_DATA object with your email address or user ID, or by including email, userId or hash parameters (or their aliases such as user_id and user_email) in the page address. A customer can also configure a form field to be pre-filled from a named parameter in the page address, in which case that value is submitted with the form. Links to hosted preference centers sent from Iterable emails carry your email address, the campaign and template identifiers, and, where the customer has configured a signing secret, a signed hash that we verify before showing or changing your preferences. Where the customer has not configured a signing secret, the preference center identifies you by your email address or user ID alone, and profile lookups are disabled. If you previously submitted an email address through a Jule experience on the same website, the widget recognizes you on later page loads from the token described in section 6.6.
Where an experience uses text personalized with fields from your Iterable profile, the widget requests those fields from our API, which reads them from the customer’s Iterable account and returns to your browser only the specific fields the experience’s text references together with your subscription state, and never Iterable’s internal, device or phone detail fields. This lookup is available only when the customer has configured a signing secret.
6.3 Coupons
When an experience issues you a coupon code we record, on the customer’s behalf, the code, your email address and phone number if provided, a random coupon session identifier generated in your browser, the full address of the page where the code was issued (including any query string), the time it was issued, whether it came from an experience on the customer’s website or from an email the customer sent through Iterable, the code’s status and expiry, and any QR content attached to the code. Codes can also be assigned without any interaction on your part when the customer’s Iterable account requests one for your email address at the moment an email is sent to you. When the code is reported as used, whether by the customer’s Shopify or Stripe account, by the customer’s own systems calling our API, or by the customer marking it redeemed in their Dashboard, we record the order identifier, the order value, the time of redemption and how the redemption was reported, and where a shared code is redeemed by someone we hold no earlier record for, we record the email address on the order as described in section 5. If the customer has enabled coupon synchronization with Iterable, we also write the code, its status and expiry, the QR image address and your phone number to your profile in the customer’s Iterable account. The customer can view and search these coupon records in their Dashboard. Each redemption is also recorded in the customer’s audit log with the code, the redemption method, the order identifier and the order value, but not your email address, and is kept for the audit log period described in section 8. When we synchronize a coupon to Iterable we keep an encrypted copy of what we sent for about twenty-four hours so that a failed sync can be retried. When a coupon includes a QR code, the image is served publicly from a URL containing a random identifier and encodes only the content the customer configured for it.
6.4 Analytics events
The widget sends usage events to our API so that our customer can see how their experience performs. Each event contains the event type (impression, open, close, page view, form submit, completion, call-to-action click, redirect click, preference change, experiment exposure, or email rejected), a random session identifier generated in your browser for that page load, a timestamp, the origin of the page you are on (its scheme and host, not the path or query string), your country as a two-letter code, a small amount of event detail, and, for A/B tests, the experiment and variant identifiers. Before an event is stored our servers also reduce any page address they receive to its origin, so that even an older version of the widget cannot cause a full address to be stored, and keep only a fixed set of detail fields: the close reason, the page index within the experience, the redirect destination, the preference field name and action, the list and message type identifiers changed, and, for a rejected email, only the domain part of the address. Events wait briefly, unencrypted, in our job queue before they are written to our analytics store; they contain none of the personal information described in section 6.1. Our request log for these calls records the country code and the types of events in the batch, but no IP address or user agent. A session summary records the start and end time, pages viewed, duration and whether the experience was completed.
For A/B tests the widget keeps a visitor identifier in your browser so that you see the same variant on repeat visits, and our servers assign variants by hashing that identifier without storing it.
Your country is normally determined at our network edge from your IP address: Cloudflare, or our hosting provider, adds a two-letter country code to the request, and our API returns that code to the widget, which fetches it when it loads, caches it in your browser and includes it in events. If that lookup is unavailable the widget instead infers a country from your browser’s language setting. Your IP address is not included in analytics events and is not stored in our analytics database. Analytics events are stored in Tinybird. Separately from analytics, the request the widget makes to load its configuration when a page opens is recorded in our API’s audit log with your IP address and browser user agent, as described in section 3.6.
6.5 Targeting evaluated in your browser
Our customers can choose to show an experience only to some visitors, or to show it at a particular moment. To evaluate those rules the widget reads, inside your browser, your device type (derived from your viewport width, whether your device supports touch, and the browser user agent string), the referring page, the current page address and its query parameters, the values of any cookies or localStorage keys the customer has named in their rules, your browser language, a count of your visits to the site, how far you have scrolled and how long the page has been open, whether your mouse leaves the page, and your country (which the widget fetches from our API and caches; if that request fails it falls back to the region in your browser language setting). These signals are evaluated inside your browser and are not transmitted to Jule, apart from the country code included in analytics events and the page origin described above. One exception is when a customer targets an experience by whether you are on one of their Iterable lists or are already known to their Iterable account: in that case the widget sends your email address or user ID, if the customer’s site or an earlier submission has supplied one, to our API, which looks you up in the customer’s Iterable account and returns only whether you are eligible.
6.6 Browser storage placed on the customer’s website
The widget writes no cookies. It uses first-party localStorage and sessionStorage on the customer’s domain to function. In some jurisdictions this storage requires the same consent as cookies, and our customers are responsible for obtaining it. The widget sets no expiry on these entries: the localStorage entries persist until you clear site data or the widget removes them, and the sessionStorage entry is cleared by your browser when you close the tab.
| Key | Purpose |
|---|---|
__jai_e | A token representing the email address you submitted, so that a returning visitor can be recognized, their preferences or coupon shown without re-entering the address, and Iterable-based targeting applied. Where possible this is an encrypted token issued by our server, valid for seven days, which the widget exchanges with our API for the address on later page loads, and which is removed when our server reports that it has expired or is invalid. When our server does not issue a token (for example on a workspace with a signing secret configured, when you did not arrive on a signed link) the widget instead stores the address in your browser encoded with a key derived from the customer’s workspace identifier. That identifier is delivered to every visitor with the widget’s configuration, so this fallback obscures the address rather than protecting it, and the entry remains until you clear site data. |
__jule_coupon_sid | A random identifier that lets a coupon issued in one visit be shown again to the same browser. |
jule_country | Your cached two-letter country code. |
project_widget_visitor_id | An identifier made of the time it was first created and a random suffix, used to keep you in the same A/B test variant across visits. |
_jule_visit_count | A count of page loads on the site, used for first-visit and repeat-visit targeting. |
project_widget_completed_<id>, project_widget_dismissed_<id>, project_widget_display_count_<id>, project_widget_last_display_ts_<id> | Whether a given experience has been completed or dismissed, how many times it has been shown, and when, so that the customer’s display frequency rules are respected. |
project_widget_session_<id> (sessionStorage) | That an experience was shown in the current tab session. |
On preference centers the widget also reads the iterableEmailCampaignId and iterableTemplateId cookies that Iterable sets on the customer’s domain so that a preference change can be attributed to the email that led you there. It also reads, without writing, any existing country or user_country entries on the customer’s site as a fallback for your country, and a jule_debug entry that turns on diagnostic logging in your browser’s console. You can remove all of these entries through your browser’s site data settings.
6.7 Email deliverability check
When you type an email address into a Jule form and move on, the widget sends the address to our API, which extracts the domain and looks up whether that domain publishes a mail exchanger (MX) record in DNS. The result is cached per domain (twenty-four hours for a positive result, one hour for a negative result). The address itself is not stored and is not echoed back. The check blocks a submission only when the domain does not exist or publishes no mail server record; any lookup failure or timeout lets the submission through. The check is not run on preference centers, for visitors who arrive on a signed link, or when the customer’s website supplied your email address, and a customer can turn it off for a project.
6.8 Third-party resources and customer scripts
On websites where a customer has embedded Jule, the widget script and its supporting files (such as the phone number input library) load from assets.jule.ai, which is served by Cloudflare. On a preference center served from a customer’s custom domain, the widget script is served from that domain by our web application and its supporting files still load from assets.jule.ai. If the customer has chosen a Google Font for their design, your browser fetches that font from Google Fonts. Images, fonts and links that a customer adds to an experience load from, or lead to, wherever the customer hosts them.
Customers can add their own HTML and JavaScript to experiences and to the header and footer of hosted preference centers. That code runs in your browser under the customer’s control. Jule does not control what it does or collects, and the customer is responsible for it.
6.9 Error reports from the widget
If the widget throws an error in your browser, a report may be sent to Sentry so that we can fix it. Reports are filtered so that only errors whose stack trace points to our widget script are sent, are passed through the scrubber described in section 3.2, do not include the address of the page you were on or its referrer, and are tagged with the customer’s public workspace key so that we know which customer’s site they came from. Because scripts a customer adds to an experience are run by our widget, an error raised by such a script can occasionally be included. The widget also reports a count of how many such reports it sent so that we can allocate the cost to the right customer; the count contains no personal information.
6.10 Hosted preference centers and unsubscribe pages
Preference centers and unsubscribe pages that a customer hosts through Jule are served by our infrastructure. When they are served on a customer’s custom domain through our web application, Google Analytics loads as described in section 3.1, our web application’s error monitoring described in section 3.2 runs, the phone number input library loads from assets.jule.ai, and our hosting provider Vercel receives the technical request information described in section 3.6. Because links to a preference center can carry your email address and other identifiers as parameters and Google Analytics records page addresses, those parameters may be sent to Google when such a page is served on a customer’s custom domain. Preference centers served from the default Jule address load only the widget script. The hosted unsubscribe page places your email address and user ID from the link you clicked into the page so that the widget can load your preferences, and when a verified custom domain is configured it redirects you there with the same parameters. We also process one-click unsubscribe requests that your mailbox provider sends on your behalf under RFC 8058: we read your subscription state in the customer’s Iterable account, apply the unsubscribe behavior the customer configured, and notify any webhook destinations the customer has configured of the unsubscribe together with your email address or user ID and the campaign and template identifiers.
7. How we use information
We use the information described above to provide, operate, secure and support the Services; to create and authenticate accounts and manage sessions and permissions; to review and approve new accounts; to deliver the data our customers collect to the destinations they choose; to create, hand out and track coupon codes; to produce analytics and A/B test results for our customers; to send the transactional emails described in section 4.9; to respond to your requests and support questions; to detect, prevent and investigate abuse, fraud and security incidents, including rate limiting by IP address; to monitor and fix errors; to measure and improve our websites; to meter our own infrastructure costs per organization; to comply with law and enforce our agreements; and to notify account holders of changes to the Services or to this policy.
We may use aggregated or de-identified information that does not identify any person, such as event counts and performance metrics, to operate and improve the Services.
8. How long we keep information
The following describes our retention rules as implemented in the Services. Where a rule is expressed in our code we state the exact figure.
| Information | Retention |
|---|---|
| Account, profile, organization and workspace data | For as long as your account exists. When you request deletion, the account is scheduled for permanent deletion thirty days later and you can cancel during that window. After the thirty days your user record, sessions, memberships and preferences are permanently deleted, the pending invitations you sent are removed, workspaces you owned are transferred to another member of that workspace (preferring an administrator) or to an administrator of your organization, and projects you created are re-attributed to a placeholder so that your organization keeps them. Your user identifier may remain on records such as project versions, uploaded assets and audit entries that belong to your organization. If a workspace you owned has no other member and your organization has no other administrator, the workspace is kept for our review. Deletion is carried out by a daily job, so it happens within about a day after the thirty days have passed. Our administrators can also delete an account immediately at your request or where required. |
| Sign-in sessions | Access tokens expire after fifteen minutes and refresh tokens after seven days. Signing out invalidates that session on our servers, and changing your password from the Dashboard invalidates all of your sessions. |
| Email verification codes and password reset links | Sign-up codes are valid for fifteen minutes, sign-up proof tokens and verification links for twenty-four hours, and reset links for one hour; expired tokens are cleared daily. |
| Team invitations | Links expire after seven days. Invitation records are deleted ninety days after they were created once they have been accepted or have expired; a declined invitation is deleted immediately. |
| Audit log | 2,190 days (six years) in the active log under our current configuration, after which entries are moved to an archive table that we do not currently purge. Audit entries are retained after an account is deleted because they record the history of the organization. |
| Project version history | The thirty most recent versions of each project; older versions are pruned automatically and the published version is always kept. |
| Uploaded assets | Until you delete them from the Dashboard. Assets belong to the workspace, so deleting your user account does not remove them. |
| Integration credentials | Until you disconnect the integration or the workspace or organization that holds it is deleted; deleting your individual user account does not remove integrations. Shopify credentials are also deleted when Shopify sends a shop/redact webhook. Parked Shopify install tokens expire after seven days. |
| Form submissions in transit | Removed from the job queue within one hour of successful delivery or twenty-four hours of failure. Analytics events wait in a separate queue for the same periods before they are written to our analytics store; those queued events are not encrypted, but they contain no email addresses, phone numbers or IP addresses. |
| Webhook delivery and Iterable sync logs | The encrypted payload is removed by an hourly job once it is twenty-four hours old. Webhook delivery records are deleted after thirty days under our current configuration, or earlier if you delete the destination. Iterable sync records keep only non-identifying metadata after the payload is removed. |
| SMS consent records | Kept as evidence of consent. These records are not deleted automatically when a project, workspace or account is deleted; we delete or de-identify them within thirty days after a customer’s agreement with us ends unless the law requires us to keep them longer. |
| SMS double opt-in duplicate check | A record that an opt-in text was requested for a number is kept for twenty-four hours so that duplicates are not sent. |
| Coupon assignment and redemption records | For as long as the customer’s coupon and account exist. Identifying fields are replaced with a placeholder on a Shopify customers/redact request. |
| Analytics events and sessions | Ninety days in our analytics store. |
| Returning-visitor email token | A server-issued token is valid for seven days and the widget removes it once our server rejects it. A locally encoded copy stored when no server token could be obtained does not expire and remains until you clear site data. |
| Email deliverability cache | Twenty-four hours for a domain that can receive mail, one hour for one that cannot. |
| Usage metering, coupon provider operation records and Iterable sync log metadata | Kept indefinitely; they contain identifiers of your organization and coupons but not visitor contact details. |
| Failed sign-in counters and revoked access tokens | Failed sign-in counters are kept for fifteen minutes per email address; an access token revoked at sign-out stays on a block list until it would have expired. |
| Newsletter subscription | Until you unsubscribe. |
| Database backups | Encrypted backups of our database are taken daily and stored in Cloudflare R2; deleted data may persist in backups for a period after deletion. |
| Server and error logs | For a limited period set by us and our providers for security and troubleshooting. |
When a customer’s agreement with us ends, or when a customer asks us to, we delete or de-identify the data we hold on that customer’s behalf within thirty days, unless a longer period is required by law or needed to resolve a dispute, prevent fraud or maintain security, or the data sits in encrypted backups that expire on their own schedule. Deleting an individual user account does not by itself delete data that belongs to the organization.
9. How we share information
We share personal information only in the following circumstances.
9.1 Service providers that process data for us
We use a small number of infrastructure and tooling providers, which act on our instructions under contracts that impose confidentiality and security obligations. They are listed below together with what they do for us.
| Provider | What it does for us | Location |
|---|---|---|
| Render | Hosts our API servers, our PostgreSQL database, our Redis cache and queue, and our backup jobs | United States |
| Vercel | Hosts our websites, documentation, Dashboard and hosted preference centers, and provisions customer custom domains | United States |
| Cloudflare | DNS, content delivery, DDoS protection, object storage for uploaded assets, the widget script and encrypted backups, and edge detection of visitor country | Global |
| Tinybird | Stores and queries analytics events | United States |
| Sentry (Functional Software, Inc.) | Error and performance monitoring | United States |
| Google (Google Analytics, Gmail, Google Fonts, Google Calendar) | Website analytics, sending of our transactional email, fonts that our customers choose for their designs, and demo scheduling | United States |
Render, Vercel, Cloudflare and Tinybird handle the data we process on behalf of our customers. Sentry may receive scrubbed error reports from the widget and from our web application. Google receives website analytics from visitors to our own sites and to hosted preference centers served from a customer’s custom domain, and otherwise handles only our transactional email, demo scheduling and the fonts a customer chooses to load. Our Data Protection Addendum commits us to give customers at least thirty days’ advance notice before we authorize any material new service provider to handle their data, during which they may object on reasonable data protection grounds. Content delivery networks that your browser contacts directly, such as unpkg for animation runtime files, Google Fonts for fonts a customer has chosen, and YouTube for a video embedded in the Dashboard, are described in sections 3.6, 4.8 and 6.8.
9.2 Services our customers connect
At our customers’ direction we send information to Iterable, Shopify, Stripe and the webhook destinations they configure, as described in section 5. These are services our customers select and contract with directly. They are not our service providers, and their handling of the information is governed by our customers’ agreements with them.
9.3 Within Jule
Our team members access personal information only when needed for their work and are bound by our internal data-handling policy, which requires unique credentials, two-factor authentication, encrypted devices, and reporting of any suspected incident to our security lead within twenty-four hours.
9.4 Legal, safety and business transfers
We may disclose information when required by law, subpoena or court order; to protect the rights, property or safety of Jule, our customers or others; to investigate fraud or security issues; or in connection with a merger, acquisition, financing or sale of assets, in which case this policy will continue to apply to your information until it is replaced.
We do not sell personal information and have not done so. We do not share personal information for cross-context behavioral advertising.
10. International transfers
Jule is based in the United States and our providers store data in the United States, with Cloudflare’s and Vercel’s networks operating globally to deliver content. If you access the Services from outside the United States your information will be transferred to and processed in the United States. Where a customer connects an Iterable account in Iterable’s European region, the data we send to Iterable goes to that region. For customers in the European Economic Area, the United Kingdom and Switzerland, our Data Protection Addendum commits us to work with the customer to put in place a lawful transfer mechanism where one is required, such as the European Commission’s Standard Contractual Clauses, the UK International Data Transfer Addendum or the Swiss adaptations of the Standard Contractual Clauses.
11. Security
We protect information with technical and organizational measures that are appropriate to the nature of the Services. Connections to our websites and API use TLS, our websites and API send HTTP Strict Transport Security and related security headers, and our pages send a Content Security Policy (except the hosted unsubscribe page, which must load the widget script from a different origin). Passwords are stored as bcrypt hashes; session tokens, backup codes and verification and reset tokens are stored as one-way hashes. Integration credentials, two-factor secrets, SMS consent phone numbers, webhook secrets and queued submission payloads are encrypted with AES-256-GCM. Access within the Dashboard is controlled by roles and permissions, requests are protected against cross-site request forgery by origin validation, public endpoints are rate limited per IP address (except signature-verified provider webhooks and the token-protected coupon data feed, which are authenticated by other means), and sign-in is temporarily locked after repeated failures. Security-relevant actions are written to an audit log that is protected against modification and deletion by a database trigger and linked by a chain of cryptographic hashes over each entry’s core fields, so that removed or reordered entries can be detected. Before an error report or log line is stored, our pipelines remove email addresses, phone numbers, long identifiers and URL query strings and replace them with placeholders. Uploaded images are re-encoded where the format allows it, uploaded SVG files are sanitized, and all uploaded files are stored under random identifiers. Our database is backed up daily to encrypted archives. Our personnel follow a written data-handling policy with an incident reporting requirement. We notify affected customers without unreasonable delay after we confirm that a failure of our own safeguards has led to unauthorized access to or acquisition of the data we hold for them. These are our current measures, and we may change them as technology and threats evolve provided the overall level of protection does not decrease.
No method of transmission or storage is perfectly secure, and we cannot guarantee absolute security. Please keep your password and two-factor codes confidential and tell us at hey@jule.ai immediately if you believe your account has been compromised.
12. Your rights and choices
12.1 Everyone
You may ask us to tell you what personal information we hold about you, to correct it, to delete it, to give you a copy in a portable format, to restrict or object to certain processing, and to withdraw any consent you have given. Write to hey@jule.ai. We will verify that the request comes from you, which may involve asking you to confirm from the email address on file, and respond within the time required by applicable law. You may authorize an agent to make a request for you; we will ask for evidence of that authority. We will not discriminate against you for exercising your rights.
If your request concerns information collected through one of our customers’ experiences, we will refer you to that customer, because they control it, and we will give that customer reasonable assistance in fulfilling your request.
12.2 Account holders
You can view and edit your profile, manage two-factor authentication and delete your account from the Dashboard settings; changing your password signs out every other device. Your account email address, company details and the interests you selected at registration cannot be edited in the Dashboard, so write to hey@jule.ai to correct them. Requesting deletion requires your password. Deletion takes effect thirty days after you request it; during that window your account stays active and you can cancel the request from the Delete Account section of your profile settings. Section 8 describes what is removed and what your organization keeps. We do not offer a self-service export, so requests for a copy of your information are fulfilled by us on request.
12.3 European Economic Area, United Kingdom and Switzerland
Where we act as controller we process your information on the following legal bases: performance of a contract when we provide the Services to you or your organization; our legitimate interests in operating, securing and improving the Services, in understanding how our websites are used, and in communicating with prospective and existing customers, balanced against your interests; your consent where we ask for it, for example when you subscribe to our newsletter, which you may withdraw at any time; and compliance with legal obligations. You have the right to lodge a complaint with your local supervisory authority, although we would appreciate the chance to address your concern first. You are not required by law to give us information, but we cannot open an account without the registration details in section 4.1 or hold a demo without the details you enter when booking. Account approval is carried out by a person, and we do not make decisions about you based solely on automated processing that have legal or similarly significant effects.
12.4 California and other United States states
Residents of California and of other states with comprehensive privacy laws have the rights described in section 12.1, including the right to know the categories and specific pieces of personal information we have collected, the categories of sources, our purposes, and the categories of third parties to whom we have disclosed it, and the right to appeal a decision on a request by writing to hey@jule.ai. In the twelve months before the effective date of this policy we collected the following categories of personal information from the people for whom we act as a business: identifiers (name, email address, phone number, IP address, account and session identifiers), professional information (your role, company name, company size, the Jule features you said you plan to use and any use case you described), internet and electronic network activity (pages visited and interactions with our sites, browser user agent strings, and approximate location derived from IP address, collected through Google Analytics, our server logs, our error monitoring and, for account holders, the audit log and session records described in section 4.2), commercial information about your organization’s plan tier and usage, a profile picture if you upload one, and account credentials (passwords, backup codes and session tokens stored only as one-way hashes, and two-factor secrets stored in encrypted form). We do not draw inferences about you from this information. We collected it from you directly, from your devices, from colleagues who invite you to join their organization on Jule, and from Google Calendar when you book a demo. We disclosed it to the service providers listed in section 9.1 for the purposes described in section 7. We have not sold or shared personal information, we do not use or disclose sensitive personal information for purposes other than those permitted by law, and we do not knowingly sell or share the personal information of anyone under sixteen. We treat a Global Privacy Control signal as a valid request to opt out of sale and sharing; because we do neither, it does not change how we process your information today, and if that changes we will update this policy.
12.5 Do Not Track
Our sites do not respond to browser Do Not Track signals because there is no accepted standard for how to interpret them. The choices in section 3.1 let you block Google Analytics.
13. Children
The Services are intended for businesses and are not directed to children. We do not knowingly collect personal information from anyone under sixteen, and our Terms of Service prohibit our customers from using Jule to collect information from children. If you believe a child has provided us with personal information, contact hey@jule.ai and we will delete it. If we learn that a customer is using Jule on a site or service directed to children under thirteen, or to collect information from a child, we will suspend the experience and delete the information we hold. Account holders must be at least eighteen.
14. Changes to this policy
We may update this policy from time to time. When we do, we will change the effective date at the top of the page. If a change materially affects how we handle information about account holders, we will notify account holders by email or in the Dashboard before the change takes effect. We will not use your information for a purpose materially different from those described here without first telling you and, where the law requires it, asking for your consent.
15. Contact
You can reach Jule LLC at hey@jule.ai with any question, request or complaint about this policy or our handling of personal information.
Questions about this document? Email hey@jule.ai.