Mail Service API
Multi-Tenant Mail-Weiterleitung für Kontaktformulare
Endpoint
POST /v1/mail/send
Zweck: Leitet Kontaktformular-Daten als E-Mail an konfigurierte Empfänger weiter. Jeder API-Key erhält seine eigene Mail-Konfiguration.
Authentication
X-API-Key: your-tenant-api-key
Warum Tenant-basiert: Jeder API-Key definiert:
- Eigenen Mail-Empfänger
- Eigene SMTP-Konfiguration
- Eigene Subject-Präfixe
- Isolierte Mail-Logs
Dadurch kann ein Furt-Gateway Kontaktformulare für mehrere Websites gleichzeitig verwalten.
Request Format
Required Fields
{
"name": "string (required, non-empty)",
"email": "string (required, valid email)",
"message": "string (required, non-empty, max 5000 chars)"
}
Optional Fields
{
"subject": "string (optional, max 200 chars)"
}
Complete Example
{
"name": "John Doe",
"email": "john@example.com",
"subject": "Partnership Inquiry",
"message": "Hello, I'm interested in discussing a potential partnership. Could we schedule a call this week?"
}
Validation Rules
Warum strenge Validation: Verhindert Spam und gewährleistet brauchbare Mails.
Name Validation
- Required: Feld muss vorhanden sein
- Non-empty: Keine leeren Strings oder nur Whitespace
- Type: Muss String sein
// Invalid examples
{"name": ""} // Empty string
{"name": " "} // Only whitespace
{"name": null} // Null value
{"name": 123} // Wrong type
Email Validation
- Required: Feld muss vorhanden sein
- Format: Basis-Regex-Validation
^[^@]+@[^@]+%.[^@]+$ - Type: Muss String sein
// Invalid examples
{"email": "notanemail"} // Missing @
{"email": "user@"} // Missing domain
{"email": "@domain.com"} // Missing user
{"email": "user@domain"} // Missing TLD
Message Validation
- Required: Feld muss vorhanden sein
- Non-empty: Keine leeren Strings oder nur Whitespace
- Length: Maximum 5000 Zeichen
- Type: Muss String sein
Subject Validation (Optional)
- Optional: Feld kann fehlen
- Length: Maximum 200 Zeichen wenn vorhanden
- Type: Muss String sein wenn vorhanden
- Default: "Contact Form Message" wenn nicht angegeben
Response Format
Success Response (HTTP 200)
{
"success": true,
"message": "Mail sent successfully",
"request_id": "1632150000-1234",
"tenant": {
"name": "your-website",
"recipient": "contact@your-website.com",
"smtp_server": "mail.your-provider.com"
}
}
Tenant-Info: Zeigt welche Konfiguration verwendet wurde. Nützlich für Debugging bei Multi-Tenant-Setups.
Error Responses
Validation Error (HTTP 400)
{
"success": false,
"error": "Name is required and cannot be empty",
"code": "VALIDATION_ERROR",
"request_id": "1632150000-1234"
}
Mögliche Validation-Errors:
"Name is required and cannot be empty""Valid email address is required""Message is required and cannot be empty""Subject must be a string with max 200 characters""Message too long (max 5000 characters)"
JSON Error (HTTP 400)
{
"success": false,
"error": "Invalid JSON",
"code": "INVALID_JSON",
"body": "the-invalid-json-string"
}
Missing Body Error (HTTP 400)
{
"success": false,
"error": "No request body",
"code": "MISSING_BODY"
}
Configuration Error (HTTP 500)
{
"success": false,
"error": "Mail configuration error: No recipient configured for this API key",
"code": "CONFIG_ERROR",
"request_id": "1632150000-1234"
}
Warum Config-Errors: Wenn ein API-Key keine vollständige Mail-Konfiguration hat (fehlender Empfänger, SMTP-Server, etc.).
SMTP Error (HTTP 500)
{
"success": false,
"error": "Failed to send email: SMTP connection failed",
"code": "SMTP_ERROR",
"request_id": "1632150000-1234",
"tenant": "your-website"
}
Multi-Tenant Configuration
Warum Multi-Tenant: Ermöglicht einem Furt-Gateway, Mails für verschiedene Websites zu verwalten.
Tenant-spezifische Features
Subject Prefix
Jeder Tenant kann ein Subject-Präfix konfigurieren:
Tenant-Config: subject_prefix = "[Website-A] "
User-Subject: "Partnership Inquiry"
Final-Subject: "[Website-A] Partnership Inquiry"
Mail Content
Die gesendete Mail enthält alle Kontext-Informationen:
Website: your-website (your-api-key)
From: John Doe <john@example.com>
Subject: Partnership Inquiry
Hello, I'm interested in discussing a potential partnership.
Could we schedule a call this week?
---
Sent via Furt Gateway
API Key: your-website
Request ID: 1632150000-1234
Warum detaillierte Mails: Empfänger sehen sofort von welcher Website die Mail kommt und haben alle nötigen Infos für die Antwort.
Rate Limiting
Mail-Requests unterliegen Rate-Limiting pro API-Key:
- Standard: 60 Requests pro Minute
- Konfigurierbar: Per Tenant anpassbar
- Headers: Rate-Limit-Status in Response-Headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1632150000
Rate-Limit-Exceeded Response (HTTP 429):
{
"success": false,
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED"
}
Integration Examples
HTML Form (Basic)
<form id="contact-form">
<input type="text" name="name" required>
<input type="email" name="email" required>
<input type="text" name="subject">
<textarea name="message" required maxlength="5000"></textarea>
<button type="submit">Send Message</button>
</form>
JavaScript Integration
document.getElementById('contact-form').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData);
try {
const response = await fetch('/v1/mail/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-api-key'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
alert('Message sent successfully!');
e.target.reset();
} else {
alert('Error: ' + result.error);
}
} catch (error) {
alert('Network error: ' + error.message);
}
});
Hugo Shortcode Integration
{{< furt-contact-form
api-endpoint="https://api.example.com/v1/mail/send"
api-key="your-api-key"
success-url="/contact/thanks/"
fields="name,email,subject,message"
>}}
curl Testing
# Valid request
curl -X POST https://api.example.com/v1/mail/send \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "Test User",
"email": "test@example.com",
"subject": "Test Message",
"message": "This is a test message from the API."
}'
# Test validation error
curl -X POST https://api.example.com/v1/mail/send \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"name": "",
"email": "invalid-email",
"message": ""
}'
Security Considerations
Input Sanitization
- HTML-Escaping: User-Input wird in der Mail HTML-escaped
- Length-Limits: Verhindert Memory-Exhaustion-Attacks
- Email-Validation: Verhindert Mail-Header-Injection
SMTP Security
- Per-Tenant-SMTP: Jeder Tenant nutzt eigene SMTP-Credentials
- Connection-Pooling: Wiederverwendung von SMTP-Connections
- Error-Isolation: SMTP-Failures eines Tenants beeinflussen andere nicht
Rate Limiting
- Spam-Protection: Verhindert Missbrauch als Mail-Relay
- Per-Key-Limits: Isolierte Limits pro Tenant
- Configurable: Limits können per Tenant angepasst werden
Troubleshooting
Common Issues
"Mail configuration error":
- API-Key hat keine vollständige Mail-Konfiguration
- Prüfe
/etc/furt/furt.confoder/usr/local/etc/furt/furt.conf - Tenant muss
to_address,from_address, SMTP-Details haben
"SMTP connection failed":
- SMTP-Server nicht erreichbar
- Falsche SMTP-Credentials
- Firewall blockiert SMTP-Port (587/465)
"Validation errors":
- Prüfe Request-Format gegen Validation-Rules
- Stelle sicher dass alle Required-Fields vorhanden sind
- Prüfe Field-Types (String vs. Number, etc.)
Debug Mode
Für Debugging können detaillierte Logs aktiviert werden:
# Server-Logs anzeigen
journalctl -fu furt # Linux
tail -f /var/log/daemon # OpenBSD
Log-Format:
Mail endpoint called - Method: POST, Path: /v1/mail/send
Authenticated as: your-website (your-api-key)
Sending mail for tenant: your-website
To: contact@your-website.com
From: noreply@your-website.com
SMTP: mail.your-provider.com:587