Connect Shopify to MailOdds for email validation, product sync, campaign sending, revenue attribution, and deliverability monitoring.
Get your MailOdds API key
Create an account at signup.mailodds.com and generate an API key from the dashboard.
Connect your Shopify store
Call POST /v1/stores with your Shopify domain and access token. See the Store Connection section below.
Sync products and start tracking
Trigger a product sync, add event tracking to your storefront, and start sending campaigns.
Validate emails when customers create accounts. Tag verified vs unverified for segmentation.
Block discount abuse by detecting temporary/disposable email addresses at checkout.
Only send recovery emails to verified addresses. Reduce bounces and protect sender reputation.
Bulk validate your customer list before major campaigns. Remove invalid addresses to improve deliverability.
// Validate a Shopify customer email at registration
const response = await fetch('https://api.mailodds.com/v1/validate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ email: customerEmail })
});
const result = await response.json();
// result.status: "valid", "invalid", "risky", "unknown"
// result.action: "accept", "reject", "review"
// result.disposable: true if throwaway address Shopify merchants sending via MailOdds get automatic email authentication. Add one NS record for mo.yourdomain.com and MailOdds manages SPF, DKIM, MX, and DMARC automatically. No ongoing DNS maintenance.
Track email-to-purchase attribution using webhook events. When a customer clicks a link in your email, MailOdds fires a message.clicked event with the destination URL and message ID. Use this to correlate clicks with Shopify orders.
// Handle message.clicked webhook for attribution
// MailOdds POSTs this to your webhook URL on every click
function handleClickWebhook(payload) {
const { to, message_id, link_url, is_bot, timestamp } = payload;
// Filter bot clicks (security scanners, link prefetchers)
if (is_bot) return;
// Attribute this click to the email campaign
trackAttribution({
email: to,
message_id,
clicked_url: link_url,
clicked_at: timestamp
});
} MailOdds appends a mid parameter to links in your emails, enabling email-to-web attribution on your Shopify store:
Your Shopify storefront can capture mid from URL parameters to attribute web sessions and purchases back to specific email campaigns. Pair with the message.clicked webhook for complete funnel tracking.
Automatically suppress bounced customers to protect your sender reputation. When a bounce webhook fires, add the email to your suppression list via POST /v1/suppression to prevent future sends.
// Auto-suppress a bounced customer email
await fetch('https://api.mailodds.com/v1/suppression', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: bouncedEmail,
reason: 'hard_bounce',
source: 'webhook'
})
}); Validate large Shopify customer lists in one batch using POST /v1/jobs. Provide a callback_url to receive results when the job completes.
// Bulk Validate Shopify Customer Emails
const response = await fetch('https://api.mailodds.com/v1/jobs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
emails: customerEmails,
callback_url: 'YOUR_WEBHOOK_URL'
})
}); is_bot = true when the event came from a security scanner, link prefetcher, or corporate email gateway (not a human). Common with Barracuda, Proofpoint, and Mimecast.
is_mpp = true when the event came from Apple Mail Privacy Protection, which pre-fetches all images and inflates open counts. Affects roughly 50% of iOS/macOS mail users.
Both fields are Booleans on engagement events (opened, clicked). Always guard with == true since they may be absent on non-engagement events.
MailOdds connects to Shopify as a complete email platform. Sync your product catalog, send targeted campaigns, and attribute revenue back to specific emails.
Connect your Shopify store to MailOdds with a single API call. Once connected, your store is ready for product sync, event tracking, and revenue attribution.
// Connect your Shopify store to MailOdds
const response = await fetch('https://api.mailodds.com/v1/stores', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
platform: 'shopify',
shop_domain: 'your-store.myshopify.com',
access_token: 'YOUR_SHOPIFY_ACCESS_TOKEN'
})
});
const store = await response.json();
// store.id - use for product sync and event tracking
// store.status - "connected" when ready Related: E-commerce Email Integration
Import your Shopify product catalog into MailOdds. Use synced products for personalized campaign content, abandoned cart templates, and product recommendation emails.
// Sync products from your connected Shopify store
// Trigger sync to import your product catalog
await fetch('https://api.mailodds.com/v1/stores/' + storeId + '/sync', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
// Query synced products for campaign personalization
const products = await fetch('https://api.mailodds.com/v1/store-products?' + new URLSearchParams({
store_id: storeId,
limit: '20'
}), {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const catalog = await products.json();
// Use catalog.products in campaign templates for product recommendations Related: E-commerce Email Integration
GET /v1/stores/{id} returns: last_synced_at, product_count, status, last_error.
Store statuses: pending, connected, active, syncing, error, disconnected.
Auto-sync frequency controlled by sync_interval_seconds. Use GET /v1/stores/{id}/sync-jobs for per-job details and GET /v1/stores/{id}/sync-jobs/{job_id}/errors for error breakdowns.
| Plan | Requests/min |
|---|---|
| Free | 200 |
| Starter | 500 |
| Growth | 750 |
| Pro | 1,000 |
| Business | 2,000 |
| Enterprise | 5,000 |
Every response includes X-RateLimit-Limit and X-RateLimit-Remaining headers.
When rate-limited, you receive a 429 with Retry-After: 60.
Upgrade your plan before peak events to avoid throttling during critical traffic windows.
Track storefront events from your Shopify theme or pixel to attribute revenue back to email campaigns. Browse events capture the mid parameter, and purchase events close the attribution loop.
// Track Shopify storefront events for revenue attribution
// Browse event - product page view
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'browse',
email: customerEmail,
properties: {
product_id: productId,
product_url: window.location.href,
mid: new URLSearchParams(window.location.search).get('mid')
}
})
});
// Purchase event - attribute revenue to email campaign
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'purchase',
email: customerEmail,
idempotency_key: 'shopify_order_' + orderId,
properties: {
order_id: orderId,
value: orderTotal,
currency: 'USD',
mid: sessionMid
}
})
}); Related: E-commerce Email
Track wishlist additions and product reviews alongside browse and purchase events. Use occurred_at for historical backfills when importing past customer activity.
// Wishlist event
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'wishlist',
email: customerEmail,
properties: { product_id: productId }
})
});
// Review event with occurred_at for historical backfill
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'review',
email: customerEmail,
occurred_at: reviewDate.toISOString(),
properties: { product_id: productId, rating: 5 }
})
}); Server-side bot detection events that complement the is_bot field on engagement webhooks. shadow_dns_dwell fires when a hidden DNS probe in your email is triggered, and css_probe fires from CSS-based open detection.
// Bot detection signals (server-side only)
// shadow_dns_dwell - triggered by hidden DNS probe in email
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'shadow_dns_dwell',
email: emailAddress,
properties: { probe_id: probeId, dwell_ms: dwellTime }
})
});
// css_probe - triggered by CSS-based open detection
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'css_probe',
email: emailAddress,
properties: { probe_id: probeId, client: detectedClient }
})
}); Merge cross-device customer profiles by sending identity_stitch events at checkout. Link device fingerprints and Shopify session IDs to customer email addresses for unified attribution across mobile and desktop.
// Identity stitching - merge cross-device customer profiles
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'identity_stitch',
email: customerEmail,
properties: {
device_id: fingerprintId,
session_id: shopifySessionId,
source: 'shopify_checkout'
}
})
}); Include an idempotency_key to safely retry event submissions without creating duplicates. Combine with occurred_at to import historical Shopify orders for retroactive campaign attribution.
// Idempotent purchase event with historical import
await fetch('https://api.mailodds.com/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_type: 'purchase',
email: customerEmail,
idempotency_key: 'shopify_order_' + shopifyOrderId,
occurred_at: orderCreatedAt.toISOString(),
properties: {
order_id: shopifyOrderId,
value: orderTotal,
currency: orderCurrency
}
})
});
// Safe to retry: same idempotency_key returns existing event
// occurred_at enables importing historical Shopify orders | Shopify Field | MailOdds Field |
|---|---|
order.total_price | properties.value |
order.id | properties.order_id + idempotency_key |
order.currency | properties.currency |
product.id | properties.product_id |
product.url | properties.product_url |
customer.email | email |
checkout.abandoned_checkout_url | properties.checkout_url |
Create and send campaigns that include product recommendations from your synced Shopify catalog. Track opens, clicks, and revenue attribution in one workflow.
// Create a campaign with Shopify product recommendations
const campaign = await fetch('https://api.mailodds.com/v1/campaigns', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Weekly Product Picks',
subject: 'New arrivals you will love',
from_email: 'hello@yourdomain.com',
subscriber_list_id: listId,
html_body: productEmailHtml,
track_opens: true,
track_clicks: true
})
});
// Send the campaign
await fetch('https://api.mailodds.com/v1/campaigns/' + campaign.id + '/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}); Related: Email Campaigns
Block disposable and role-based emails during product launches using validation policies. Create a strict policy from a preset and apply it to validation requests. Test policies before enforcing to avoid blocking legitimate customers.
// Create a strict validation policy for product launches
const policy = await fetch('https://api.mailodds.com/v1/policies/from-preset', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ preset: 'strict' })
});
// Validate with the policy applied
const result = await fetch('https://api.mailodds.com/v1/validate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: customerEmail,
policy_id: policy.id
})
});
// Strict preset: blocks disposable, catch-all, and role-based emails See the API documentation for all available presets and policy options.
Run a pre-send spam check on your campaign content before hitting send. Analyze your sending domain reputation, subject line, and link safety to catch deliverability issues before they affect your inbox placement.
// Pre-send spam check for campaign content
const check = await fetch('https://api.mailodds.com/v1/spam-checks', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from_domain: 'yourdomain.com',
subject_preview: 'Flash sale: 50% off everything',
links: [
'https://store.example.com/sale',
'https://store.example.com/unsubscribe'
]
})
});
const result = await check.json();
// result.score: 0-10 (lower = better)
// result.verdict: "pass", "warning", or "fail"
// result.checks: domain_reputation, link_safety, subject_analysis Set-and-forget monitoring for your Shopify store's sending domain.
Register your sending domain and verify DNS records. MailOdds monitors aggregate DMARC reports and provides trend data, source analysis, and policy recommendations.
// Register your sending domain for DMARC monitoring
const domain = await fetch('https://api.mailodds.com/v1/dmarc-domains', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ domain: 'yourdomain.com' })
});
// Verify DNS records are in place
await fetch('https://api.mailodds.com/v1/dmarc-domains/' + domain.id + '/verify', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}); Related: DMARC Monitoring
Monitor your sending IPs and domains against major blacklists. Get alerted when a listing is detected and track delisting history over time.
// Monitor your sending IP for blacklist listings
await fetch('https://api.mailodds.com/v1/blacklist-monitors', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
target: '203.0.113.10',
target_type: 'ip'
})
}); Check your overall sender health score, graded A through F. Sub-scores cover delivery rate, bounce rate, and complaint rate over a configurable time period.
// Check your sender health score
const health = await fetch('https://api.mailodds.com/v1/sender-health?period=30d', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const result = await health.json();
// result.score: 0-100
// result.grade: A-F
// Sub-scores: delivery_rate, bounce_rate, complaint_rate Related: Sender Reputation
EU-hosted (Amsterdam), strictly account-scoped with no cross-account sharing.
DELETE /v1/stores/{id} deactivates products and removes the connection.
Shopify mandatory privacy webhooks handled: customers/redact, customers/data_request, shop/redact.
GDPR data purge available. Data retention configurable (30-730 days).
Use the MailOdds MCP server to manage your Shopify integration via AI agents. Learn more
Can't find what you're looking for? We're here to help you get Shopify working.
Get 1,000 free validations. Catch disposable addresses and improve deliverability.