Website Forms Integration
Connect your website contact forms to Mailoo for secure message processing and automated responses
Quick Start
- 1. Create a project and integration in your Mailoo dashboard
- 2. Copy your project API key from the integration settings
- 3. Add the form HTML to your website
- 4. Configure the JavaScript handler
- 5. Test your form submission
Prerequisites
Mailoo Account Setup
You need an active Mailoo account with a project and email integration configured.
Website Access
Ability to edit HTML and JavaScript on your website.
Step 1: Get Your API Key
Navigate to your integration settings in the Mailoo dashboard to find your API key:
Dashboard → [Your Project] → [Your Integration] → SettingsSecurity: Keep your API key secure and never expose it in client-side code.
Step 2: Create Your HTML Form
Add this HTML form to your website. The form will capture user messages and send them to Mailoo:
<form id="mailoo-contact-form" class="space-y-4">
<div>
<label for="name" class="block text-sm font-medium">Name *</label>
<input
type="text"
id="name"
name="name"
required
maxlength="100"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
/>
</div>
<div>
<label for="email" class="block text-sm font-medium">Email *</label>
<input
type="email"
id="email"
name="email"
required
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
/>
</div>
<div>
<label for="subject" class="block text-sm font-medium">Subject</label>
<input
type="text"
id="subject"
name="subject"
maxlength="200"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
/>
</div>
<div>
<label for="message" class="block text-sm font-medium">Message *</label>
<textarea
id="message"
name="message"
required
maxlength="5000"
rows="5"
class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2"
></textarea>
</div>
<button
type="submit"
class="w-full rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
>
Send Message
</button>
</form>
<div id="mailoo-status" style="display: none;" class="mt-4 p-3 rounded-md">
<span id="mailoo-status-text"></span>
</div>Step 3: Add JavaScript Handler
Add this JavaScript code to handle form submissions securely:
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('mailoo-contact-form');
const statusDiv = document.getElementById('mailoo-status');
const statusText = document.getElementById('mailoo-status-text');
// Replace with your actual values (project UID and integration ID from dashboard)
const MAILOO_API_URL = 'https://api.mailoo.app/api/v1';
const PROJECT_UID = 'your-project-uid';
const INTEGRATION_ID = 'your-form-integration-id';
const API_KEY = 'your-api-key';
form.addEventListener('submit', async function(e) {
e.preventDefault();
// Show loading state
const submitBtn = form.querySelector('button[type="submit"]');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Sending...';
submitBtn.disabled = true;
try {
// Collect form data (only email required; name optional; notification is built from template)
const formData = {
email: form.email.value.trim(),
name: form.name.value.trim() || undefined,
source: window.location.href,
metadata: {
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
referrer: document.referrer
}
};
// Submit to Mailoo (project UID and integration ID required)
const response = await fetch(`${MAILOO_API_URL}/webhooks/forms/${PROJECT_UID}/${INTEGRATION_ID}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
'Origin': window.location.origin
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (response.ok && result.success) {
// Success
showStatus('success', 'Message sent successfully! We\'ll get back to you soon.');
form.reset();
} else if (response.status === 503 && result.message?.includes('not ready')) {
showStatus('error', 'Subscription form is not ready. Please try again later or contact support.');
} else {
// API error
throw new Error(result.message || 'Failed to send message');
}
} catch (error) {
console.error('Form submission error:', error);
showStatus('error', 'Failed to send message. Please try again or contact us directly.');
} finally {
// Reset button
submitBtn.textContent = originalText;
submitBtn.disabled = false;
}
});
function showStatus(type, message) {
statusText.textContent = message;
statusDiv.className = `mt-4 p-3 rounded-md ${
type === 'success'
? 'bg-green-100 text-green-800 border border-green-200'
: 'bg-red-100 text-red-800 border border-red-200'
}`;
statusDiv.style.display = 'block';
// Auto-hide after 5 seconds
setTimeout(() => {
statusDiv.style.display = 'none';
}, 5000);
}
});
</script>Step 4: Configuration
Required Configuration
| MAILOO_API_URL | https://api.mailoo.app/api/v1 (production) |
| PROJECT_UID | Your project UID from dashboard |
| INTEGRATION_ID | Your form integration ID (from dashboard when viewing the integration) |
| API_KEY | Your integration API key |
Optional Fields
You can add custom fields to collect additional information:
<!-- Add to your form -->
<div>
<label for="company" class="block text-sm font-medium">Company</label>
<input type="text" id="company" name="company" maxlength="100" />
</div>
<div>
<label for="phone" class="block text-sm font-medium">Phone</label>
<input type="tel" id="phone" name="phone" maxlength="20" />
</div>
<!-- Update JavaScript to include custom fields -->
metadata: {
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
referrer: document.referrer,
company: form.company?.value || '',
phone: form.phone?.value || ''
}Security Best Practices
API Key Security
- Never expose API keys in client-side JavaScript
- Use environment variables in server-side implementations
- Rotate API keys regularly
- Restrict API key permissions to minimum required
CORS Configuration
Mailoo validates the Origin header to prevent unauthorized cross-origin requests. Configure allowed origins in your integration settings.
Rate Limiting
API endpoints are rate-limited to prevent abuse. Implement client-side throttling to avoid hitting rate limits during high traffic periods.
Input Validation
Always validate form inputs on both client and server side. Use appropriate maxlength attributes and sanitize user input before display.
Secure Server-Side Implementation
For better security, implement form processing on your server instead of client-side:
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('/contact', async (req, res) => {
try {
const { email, name } = req.body;
// Validate required fields (only email is required)
if (!email || !email.includes('@')) {
return res.status(400).json({
error: 'Valid email is required'
});
}
// Submit to Mailoo (project UID and integration ID required)
const response = await fetch(`${process.env.MAILOO_API_URL}/webhooks/forms/${process.env.PROJECT_UID}/${process.env.INTEGRATION_ID}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.MAILOO_API_KEY,
'Origin': process.env.WEBSITE_ORIGIN
},
body: JSON.stringify({
email: email.trim(),
name: name?.trim() || undefined,
source: req.headers.referer,
metadata: {
ip: req.ip,
userAgent: req.headers['user-agent']
}
})
});
const result = await response.json();
if (response.ok && result.success) {
res.json({ success: true, message: 'Message sent successfully' });
} else {
throw new Error(result.message || 'Failed to send message');
}
} catch (error) {
console.error('Contact form error:', error);
res.status(500).json({
error: 'Failed to send message'
});
}
});Environment Variables
# .env
MAILOO_API_URL=https://api.mailoo.app/api/v1
PROJECT_UID=proj_your_project_uid
INTEGRATION_ID=your_form_integration_id
MAILOO_API_KEY=mai_your_api_key_here
WEBSITE_ORIGIN=https://yourdomain.comAPI Reference
Form Submission Endpoint
POST /api/v1/webhooks/forms/{projectUid}/{integrationId}Submit form data from external websites. Both project UID and integration ID are required in the path.
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", // Required: 1-100 chars
"email": "john@example.com", // Required: valid email
"subject": "Contact inquiry", // Optional: 1-200 chars
"message": "Hello, I need help...", // Required: 1-5000 chars
"source": "https://yoursite.com/contact", // Optional: source URL
"metadata": { // Optional: additional data
"company": "Acme Corp",
"phone": "+1234567890"
}
}Response Format
// Success (200)
{
"success": true,
"messageId": "msg_abc123def",
"message": "Form submission processed successfully"
}
// Error (400/401/403/429)
{
"error": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format",
"code": "invalid_string"
}
]
}Testing Your Integration
1. Test Form Submission
Fill out your form and submit it. Check your Mailoo dashboard for the new message in the integration inbox.
2. Check Integration Status
Use the status endpoint to verify your integration is active:
curl -X GET "https://api.mailoo.app/api/v1/webhooks/status/{integrationId}" \
-H "X-API-Key: your-api-key"3. Monitor Logs
Check your browser's developer console and network tab for any JavaScript errors or failed requests.
Troubleshooting
401 - Invalid API Key
Verify your API key is correct and the integration is active in your dashboard.
403 - Origin Not Allowed
Add your website domain to the allowed origins list in your integration settings.
429 - Rate Limited
Too many requests. Wait before retrying and consider implementing client-side throttling.
CORS Errors
Ensure your domain is whitelisted and the Origin header matches exactly (including protocol and port).
Advanced Usage
Multiple Forms
You can use the same integration for multiple forms on your website:
// Add form identifier to metadata
metadata: {
formType: 'contact', // or 'newsletter', 'support', etc.
pageUrl: window.location.href,
formId: 'contact-page-form'
}Custom Success/Error Handling
// Custom success handler
if (response.ok && result.success) {
// Redirect to thank you page
window.location.href = '/thank-you';
// Or show custom modal
showCustomModal('Thank you for contacting us!');
// Or trigger analytics event
gtag('event', 'form_submit', {
event_category: 'contact',
event_label: 'success'
});
}Form Validation
// Client-side validation before submission (only email required; name optional)
function validateForm(formData) {
const errors = [];
if (!formData.email.trim() || !isValidEmail(formData.email)) {
errors.push('Valid email is required');
}
return errors;
}
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}Next Steps
Your form integration is ready! Consider setting up automated responses and email campaigns to engage with your form submissions.
Need Help?
If you run into issues or have questions about the integration, our support team is here to help.