Migration guide
Connect all your projects
to MailcowAI Engage
Old scripts (telemetry.10ips.com, support.tuaxo.cc) are replaced by a single engage.js from cdn.mailcowai.com. Follow these steps for every site you want to track.
On this page
  1. Fix Content Security Policy
  2. Replace the old script tag
  3. Create a project & get your key
  4. Identify users (optional)
  5. Verify the connection
  6. Migration checklist
1 Required first

Fix Content Security Policy

Most sites restrict which external scripts and API endpoints are allowed. If your site sends a Content-Security-Policy header (or has a <meta> CSP tag), you need to add MailcowAI domains before the snippet will load.

If you see "Loading the script '…' violates the following Content Security Policy directive: script-src 'self'" in the browser console, this step is blocking you. Fix it first — the snippet won't load otherwise.

Add these three directives to your CSP. Merge with existing values if you already have them.

Required CSP directives
script-srchttps://cdn.mailcowai.com
connect-srchttps://api.mailcowai.com https://support.mailcowai.com
frame-srchttps://support.mailcowai.com
script-src … https://cdn.mailcowai.com connect-src … https://api.mailcowai.com https://support.mailcowai.com frame-src … https://support.mailcowai.com

Where to set this depends on your server / framework:

# nginx server block
add_header Content-Security-Policy
  "default-src 'self';
   script-src  'self' 'unsafe-inline' https://cdn.mailcowai.com;
   connect-src 'self' https://api.mailcowai.com https://support.mailcowai.com;
   frame-src   'self' https://support.mailcowai.com;
   style-src   'self' 'unsafe-inline';
   img-src     'self' data:;" always;
# Caddyfile
header Content-Security-Policy "default-src 'self'; \
  script-src 'self' 'unsafe-inline' https://cdn.mailcowai.com; \
  connect-src 'self' https://api.mailcowai.com https://support.mailcowai.com; \
  frame-src 'self' https://support.mailcowai.com; \
  style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
// next.config.js — headers()
{
  key: 'Content-Security-Policy',
  value: [
    "default-src 'self'",
    "script-src 'self' 'unsafe-inline' https://cdn.mailcowai.com",
    "connect-src 'self' https://api.mailcowai.com https://support.mailcowai.com",
    "frame-src 'self' https://support.mailcowai.com",
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data:",
  ].join(';'),
}
# .htaccess or VirtualHost
Header always set Content-Security-Policy \
  "default-src 'self'; \
   script-src 'self' 'unsafe-inline' https://cdn.mailcowai.com; \
   connect-src 'self' https://api.mailcowai.com https://support.mailcowai.com; \
   frame-src 'self' https://support.mailcowai.com; \
   style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
<!-- In <head> — works but HTTP header is preferred -->
<meta http-equiv="Content-Security-Policy"
      content="default-src 'self';
               script-src 'self' 'unsafe-inline' https://cdn.mailcowai.com;
               connect-src 'self' https://api.mailcowai.com https://support.mailcowai.com;
               frame-src 'self' https://support.mailcowai.com;
               style-src 'self' 'unsafe-inline';
               img-src 'self' data:;">
If your site doesn't have a CSP header at all, you can skip this step — the snippet will load by default. Check your browser DevTools → Network → response headers to confirm.

2 Replace script

Replace the old script tag

Remove any existing sdk.js or widget.js tags. One unified engage.js now handles both telemetry collection and the chat widget.

Remove (old)
HTML
<script src="https://telemetry.10ips.com/sdk.js"
  data-project="..."></script>

<script src="https://support.tuaxo.cc/widget.js"
  data-project="..."></script>
Add (new)
HTML
<script src="https://cdn.mailcowai.com/engage.js"
  data-project="your-slug"
  data-public-key="pk_xxx"
  defer></script>

Place the tag just before </body> — or anywhere in <head> with the defer attribute.

Final snippet
<script src="https://cdn.mailcowai.com/engage.js"
        data-project="your-project-slug"
        data-public-key="pk_your_key"
        defer></script>
<script src="https://cdn.mailcowai.com/engage.js" data-project="your-project-slug" data-public-key="pk_your_key" defer></script>

3 Admin

Your project keys

Each site is a separate project. Below are all active projects — copy the slug and public key into your snippet.

data-project data-public-key Snippet
aiuroki pk_aiuroki_50211dbe7e94f8e3
demo pk_demo
gator pk_gator_c322674f9191f9d8
mailcowai pk_mailcowai
mailcowai-demo pk_demo_mailcowai
tenips pk_tenips_14857424adcc9d75
tsosx pk_tsosx_b23a1e1b4ae44477
tsxio pk_tsxio_8b7bceffcc8c98d5
tuaxo pk_tuaxo_e3e03fffb2e1eb59
tuniko pk_tuniko_b795d47544deb030

Need a new project for a site not listed above? Create it in the admin →

Each project gets a separate session stream and campaign set. Use one project per domain (or per environment for staging vs production).

4 Optional

Identify users

If you have authenticated users, call MailcowAI.identify() after login. This links session data to a real user, enabling the support context view in FreeScout.

JavaScript
// Call after the user logs in, or on any authenticated page
window.MailcowAI.identify("user-123", {
  email: "alice@example.com",
  name:  "Alice",
  plan:  "pro",          // any extra context for campaigns
});
window.MailcowAI.identify("user-123", { email: "alice@example.com", name: "Alice", plan: "pro", });

Track custom events the same way:

JavaScript
MailcowAI.track("billing.checkout.started", { plan: "pro", trial: false });
MailcowAI.track("onboarding.step.completed", { step: "connect_snippet" });
MailcowAI.track("billing.checkout.started", { plan: "pro", trial: false }); MailcowAI.track("onboarding.step.completed", { step: "connect_snippet" });

5 Confirm

Verify the connection

After deploying the snippet, open your site in a browser. Then check these three places:

Browser console — expected output
[MailcowAI] engage.js v1.1 loaded  project=my-site
[MailcowAI] session started  anon_id=anon_8f3c...
[MailcowAI] page_view → /  (200ms)

If you see those lines, the SDK is running. If you see a CSP error instead, go back to Step 1.

Then check the admin dashboard:

  1. Open /admin/sessions
  2. Filter by your project slug — you should see a new session within ~5 seconds
  3. Click the session row to see the event timeline
  4. If you called .identify() you'll see a green dot on that session
Enable debug mode in dev: add data-debug="true" to the script tag for verbose console output — no secrets are exposed, just event names and API responses.

Before you ship

Migration checklist

Ready to connect?

Create your first project, copy the snippet, and see your first session in under five minutes.