Website Forms Integration
Website Forms Integration
Connect your website contact and subscription forms to Mailoo for secure message processing and automated email campaigns.
Quick Start
- Create a project and form integration in your Mailoo dashboard
- Generate an API key for your project
- Add the subscription form HTML to your website
- Configure the JavaScript handler with your API credentials
- Test your form submission
Prerequisites
Mailoo Account Setup
: You need an active Mailoo account with a project and form integration configured.
Website Access
: Ability to edit HTML and JavaScript on your website.
API Key
: A valid API key generated from your Mailoo dashboard.
Step 1: Create Your Integration
Navigate to your Mailoo dashboard and create a new form integration:
- Go to Dashboard → Projects → [Your Project] → Integrations
- Click "Create New Integration"
- Select "Form Integration"
- Configure your integration:
- Name: Give your integration a descriptive name (e.g., "Newsletter Signup")
- Status: Set to Active
- Form Endpoint URL: Your website URL where the form is located
- Email Field Name: The HTML name attribute for your email field (usually "email")
- Success Redirect URL: Optional URL to redirect users after successful submission
Step 2: Generate API Key
- In your integration settings, navigate to the API Keys section
- Click "Generate New API Key"
- Give your API key a descriptive name (e.g., "Website Forms")
- Important: Copy and securely store your API key - it's only shown once!
:::: warning ::: title Warning :::
Security: Never expose your API key in client-side JavaScript. For production use, implement server-side form processing. ::::
Step 3: "Stay Updated" Subscription Form
Here's a complete example of a "Stay Updated" subscription form:
HTML Structure:
<section class="newsletter-signup">
<div class="container">
<h2>Stay Updated</h2>
<p>
Get the latest features, tips, and mindfulness insights delivered to your
inbox.
</p>
<form id="mailoo-subscribe-form" class="subscribe-form">
<div class="form-group">
<label for="email" class="sr-only">Enter your email</label>
<input
type="email"
id="email"
name="email"
placeholder="Enter your email"
required
class="email-input"
/>
</div>
<div class="form-group">
<input
type="text"
id="name"
name="name"
placeholder="Your name (optional)"
class="name-input"
/>
</div>
<button type="submit" class="subscribe-btn">Subscribe</button>
</form>
<div id="mailoo-status" class="status-message" style="display: none;">
<span id="mailoo-status-text"></span>
</div>
</div>
</section>
CSS Styling:
.newsletter-signup {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 0;
text-align: center;
}
.subscribe-form {
max-width: 400px;
margin: 2rem auto 0;
display: flex;
flex-direction: column;
gap: 1rem;
}
.email-input,
.name-input {
padding: 12px 16px;
border: none;
border-radius: 8px;
font-size: 16px;
width: 100%;
box-sizing: border-box;
}
.subscribe-btn {
background: #ff6b6b;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
.subscribe-btn:hover {
background: #ff5252;
}
.subscribe-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.status-message {
margin-top: 1rem;
padding: 10px;
border-radius: 4px;
text-align: center;
}
.status-success {
background: rgba(76, 175, 80, 0.1);
color: #4caf50;
border: 1px solid #4caf50;
}
.status-error {
background: rgba(244, 67, 54, 0.1);
color: #f44336;
border: 1px solid #f44336;
}
Step 4: JavaScript Implementation
Add this JavaScript code to handle form submissions:
document.addEventListener('DOMContentLoaded', function () {
const form = document.getElementById('mailoo-subscribe-form')
const statusDiv = document.getElementById('mailoo-status')
const statusText = document.getElementById('mailoo-status-text')
// Replace with your actual values from Mailoo dashboard
const MAILOO_CONFIG = {
apiUrl: 'https://api.mailoo.com/api/v1', // Production URL
projectUid: 'your-project-uid-here', // From dashboard
apiKey: 'your-api-key-here', // From API Keys section
}
form.addEventListener('submit', async function (e) {
e.preventDefault()
// Show loading state
const submitBtn = form.querySelector('.subscribe-btn')
const originalText = submitBtn.textContent
submitBtn.textContent = 'Subscribing...'
submitBtn.disabled = true
try {
// Collect form data
const formData = {
name: form.name.value.trim() || 'Subscriber',
email: form.email.value.trim(),
subject: 'Newsletter Subscription',
message: `New newsletter subscription from ${form.name.value.trim() || form.email.value}`,
source: window.location.href,
metadata: {
type: 'newsletter_subscription',
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
referrer: document.referrer || 'direct',
},
}
// Validate required fields
if (!formData.email) {
throw new Error('Email is required')
}
// Submit to Mailoo
const response = await fetch(
`${MAILOO_CONFIG.apiUrl}/webhooks/forms/${MAILOO_CONFIG.projectUid}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': MAILOO_CONFIG.apiKey,
Origin: window.location.origin,
},
body: JSON.stringify(formData),
}
)
const result = await response.json()
if (response.ok && result.success) {
// Success
showStatus(
'success',
'Thank you for subscribing! Check your email for confirmation.'
)
form.reset()
// Optional: Track conversion with analytics
if (typeof gtag !== 'undefined') {
gtag('event', 'newsletter_signup', {
event_category: 'engagement',
event_label: 'success',
})
}
} else {
// API error
throw new Error(result.message || 'Subscription failed')
}
} catch (error) {
console.error('Subscription error:', error)
showStatus(
'error',
'Subscription failed. Please try again or contact us directly.'
)
// Optional: Track error with analytics
if (typeof gtag !== 'undefined') {
gtag('event', 'newsletter_signup_error', {
event_category: 'error',
event_label: error.message,
})
}
} finally {
// Reset button
submitBtn.textContent = originalText
submitBtn.disabled = false
}
})
function showStatus(type, message) {
statusText.textContent = message
statusDiv.className = `status-message status-${type}`
statusDiv.style.display = 'block'
// Auto-hide success messages after 5 seconds
if (type === 'success') {
setTimeout(() => {
statusDiv.style.display = 'none'
}, 5000)
}
}
})
Step 5: Configuration
Required Configuration Values:
Variable Description
MAILOO_CONFIG.apiUrl Production: https://api.mailoo.com/api/v1
MAILOO_CONFIG.projectUid Your project UID from the dashboard URL
MAILOO_CONFIG.apiKey API key generated in Step 2
: Configuration Options
Finding Your Configuration Values:
- Project UID: Found in your dashboard URL:
/dashboard/projects/[PROJECT_UID] - API Key: Generated in your project's API Keys section
- API URL: Use production URL for live websites
Secure Server-Side Implementation
For production websites, implement form processing on your server to keep API keys secure:
Node.js/Express Example:
// server.js
const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.post('/api/subscribe', async (req, res) => {
try {
const { email, name } = req.body
// Validate required fields
if (!email || !email.includes('@')) {
return res.status(400).json({
error: 'Valid email is required',
})
}
// Submit to Mailoo
const response = await fetch(
`${process.env.MAILOO_API_URL}/webhooks/forms/${process.env.PROJECT_UID}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.MAILOO_API_KEY,
Origin: process.env.WEBSITE_ORIGIN,
},
body: JSON.stringify({
name: name?.trim() || 'Subscriber',
email: email.trim(),
subject: 'Newsletter Subscription',
message: `Newsletter subscription from ${name || email}`,
source: req.headers.referer || 'server-side-form',
metadata: {
type: 'newsletter_subscription',
ip: req.ip,
userAgent: req.headers['user-agent'],
timestamp: new Date().toISOString(),
},
}),
}
)
const result = await response.json()
if (response.ok && result.success) {
res.json({
success: true,
message: 'Subscription successful!',
})
} else {
throw new Error(result.message || 'Subscription failed')
}
} catch (error) {
console.error('Subscription error:', error)
res.status(500).json({
error: 'Subscription failed. Please try again.',
})
}
})
Environment Variables (.env):
MAILOO_API_URL=https://api.mailoo.com/api/v1
PROJECT_UID=your-project-uid-here
MAILOO_API_KEY=your-api-key-here
WEBSITE_ORIGIN=https://yourdomain.com
Client-Side JavaScript (Secure Version):
// Updated form handler for server-side processing
form.addEventListener('submit', async function (e) {
e.preventDefault()
const submitBtn = form.querySelector('.subscribe-btn')
const originalText = submitBtn.textContent
submitBtn.textContent = 'Subscribing...'
submitBtn.disabled = true
try {
const response = await fetch('/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: form.email.value.trim(),
name: form.name.value.trim(),
}),
})
const result = await response.json()
if (response.ok && result.success) {
showStatus('success', 'Thank you for subscribing!')
form.reset()
} else {
throw new Error(result.error || 'Subscription failed')
}
} catch (error) {
showStatus('error', 'Subscription failed. Please try again.')
} finally {
submitBtn.textContent = originalText
submitBtn.disabled = false
}
})
Testing Your Integration
-
Test Form Submission Fill out your subscription form and submit it. Check your Mailoo dashboard for the new message in the integration inbox.
-
Check Integration Status Use the status endpoint to verify your integration is active:
curl -X GET "https://api.mailoo.com/api/v1/webhooks/status/{integrationId}" \ -H "X-API-Key: your-api-key" -
Monitor Logs Check your browser's developer console and network tab for any JavaScript errors or failed requests.
-
Verify Email Collection Confirm that email addresses are being stored properly in your Mailoo message inbox.
Troubleshooting
401 - Invalid API Key
: - Verify your API key is correct and hasn't been regenerated
- Ensure the API key is active in your dashboard
- Check that you're using the correct project UID
403 - Origin Not Allowed
: - Add your website domain to the allowed origins in your integration settings
- Ensure the Origin header matches your domain exactly (including protocol)
429 - Rate Limited
: - Too many requests from the same API key
- Wait before retrying and consider implementing client-side throttling
CORS Errors
: - Ensure your domain is whitelisted in integration settings
- Verify the Origin header is being sent correctly
- Check that protocol and port match exactly
Form Validation Errors
: - Ensure email field contains valid email address
- Check that required fields (name, email, message) are not empty
- Verify field lengths don't exceed maximum limits
Advanced Usage
Multiple Form Types
: Use the same integration for different forms by adding identifiers:
``` javascript
metadata: {
formType: 'newsletter', // or 'contact', 'support'
pageUrl: window.location.href,
formId: 'newsletter-sidebar'
}
```
Custom Success Actions
: Handle successful submissions with custom actions:
``` javascript
if (response.ok && result.success) {
// Show thank you modal
showThankYouModal();
// Redirect to thank you page
setTimeout(() => {
window.location.href = '/thank-you';
}, 2000);
// Add to email list for further marketing
addToEmailList(formData.email);
}
```
Enhanced Analytics
: Track detailed subscription metrics:
``` javascript
// Track subscription source
gtag('event', 'newsletter_signup', {
event_category: 'engagement',
event_label: 'homepage-hero',
custom_parameters: {
form_location: 'above-fold',
user_type: 'first-time-visitor'
}
});
```
API Reference
Form Submission Endpoint
POST /api/v1/webhooks/forms/{projectUid}
Request Headers:
Header Required Description
Content-Type Yes application/json
X-API-Key Yes Your project API key
Origin Recommended For CORS validation
Request Body:
{
"name": "John Doe",
"email": "john@example.com",
"subject": "Newsletter Subscription",
"message": "Please add me to your mailing list",
"source": "https://yoursite.com/newsletter",
"metadata": {
"type": "newsletter_subscription",
"timestamp": "2024-01-15T10:30:00Z"
}
}
Response Format:
{
"success": true,
"messageId": "msg_abc123def456",
"message": "Form submission processed successfully"
}
Error Response:
{
"error": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format",
"code": "invalid_string"
}
]
}
Security Best Practices
- API Key Security
- Never expose API keys in client-side code
- Use environment variables for server-side implementations
- Rotate API keys regularly
- Use different keys for development and production
- Input Validation
- Validate email addresses on both client and server
- Sanitize user input before processing
- Set appropriate field length limits
- Implement rate limiting on your forms
- CORS Configuration
- Configure allowed origins in integration settings
- Use specific domains rather than wildcards
- Validate Origin headers server-side
- Data Privacy
- Comply with GDPR and other privacy regulations
- Provide clear opt-in mechanisms
- Include unsubscribe options in all communications
- Secure transmission with HTTPS
Next Steps
Once your form integration is working:
- Set Up Automation: Configure automated welcome emails and drip campaigns
- Create Email Templates: Design professional email templates for your communications
- Monitor Performance: Track subscription rates and engagement metrics
- A/B Testing: Test different form designs and copy to optimize conversions
Need Help?
If you encounter issues or have questions:
- Check our Troubleshooting Guide
- Review the API Documentation
- Contact our support team through the dashboard
The integration should now be collecting email addresses securely and enabling you to build your subscriber list effectively.