IMAP Migration API
Programmatische IMAP E-Mail-Migration: Migrationen starten, Status prüfen und Fortschritt überwachen per API.
Überblick
Die IMAP Migration API ermöglicht die programmatische Migration von E-Mails zwischen IMAP-Servern. Migrationen laufen in einem Queue-System mit maximal 4 gleichzeitigen Jobs für Stabilität.
Endpunkte
| Methode | Endpunkt | Beschreibung |
|---|---|---|
POST | /api/v1/imap/test-connection | IMAP-Verbindung testen |
POST | /api/v1/imap/list-folders | Ordner mit Nachrichtenanzahl listen |
POST | /api/v1/imap/migrate | Migration starten (Queue) |
GET | /api/v1/imap/migrate/{id} | Status & Fortschritt abfragen |
Features
- Vollständige Ordner-Migration mit Nachrichten, Flags und Zeitstempeln
- Optionaler Ziel-Prefix (alle Ordner in Unterordner routen)
- Queue-System mit Positions-Tracking (max 4 gleichzeitig)
- Echtzeit-Fortschritt via Polling
- Automatische Ordner-Hierarchie-Erstellung
Authentifizierung
Authorization: Bearer IHR_API_TOKEN
Typischer Workflow
- Quell-Verbindung testen:
POST /api/v1/imap/test-connection - Quell-Ordner listen:
POST /api/v1/imap/list-folders - Ziel-Verbindung testen:
POST /api/v1/imap/test-connection - Migration starten:
POST /api/v1/imap/migrate - Status pollen:
GET /api/v1/imap/migrate/{id}alle 2-5 Sekunden
Verbindung testen & Ordner listen
Verbindung testen
POST /api/v1/imap/test-connection
Authorization: Bearer IHR_API_TOKEN
Content-Type: application/json
{
"host": "imap.example.com",
"port": 993,
"user": "user@example.com",
"password": "ihr-passwort",
"secure": true
}
Antwort (Erfolg):
{
"success": true,
"connected": true,
"folderCount": 5,
"listFailed": false,
"statusOnly": false,
"server": { "host": "imap.example.com", "port": 993, "secure": true },
"message": "Connected successfully. 5 folders found."
}
Antwort (Erfolg mit LIST-Fallback — manche Server/Proxys lehnen LIST ab):
{
"success": true,
"connected": true,
"folderCount": 1,
"listFailed": true,
"statusOnly": false,
"server": { "host": "imap.example.com", "port": 993, "secure": true },
"message": "Connected but LIST command failed. Folders will be enumerated individually."
}
Antwort (Fehler):
{ "success": false, "error": "Authentication failed" }
Ordner listen
POST /api/v1/imap/list-folders
Authorization: Bearer IHR_API_TOKEN
Content-Type: application/json
{
"host": "imap.example.com",
"port": 993,
"user": "user@example.com",
"password": "ihr-passwort",
"secure": true
}
Antwort (Erfolg):
{
"success": true,
"data": {
"folders": [
{ "path": "INBOX", "name": "INBOX", "messages": 3200, "unseen": 42, "delimiter": "/", "flags": [], "specialUse": "\Inbox" },
{ "path": "Sent", "name": "Sent", "messages": 890, "unseen": 0, "delimiter": "/", "flags": [], "specialUse": "\Sent" },
{ "path": "Drafts", "name": "Drafts", "messages": 12, "unseen": 0, "delimiter": "/", "flags": [], "specialUse": "\Drafts" },
{ "path": "Trash", "name": "Trash", "messages": 421, "unseen": 0, "delimiter": "/", "flags": [], "specialUse": "\Trash" },
{ "path": "Archive", "name": "Archive", "messages": 0, "unseen": 0, "delimiter": "/", "flags": [], "specialUse": null }
],
"totalFolders": 5,
"totalMessages": 4523,
"server": { "host": "imap.example.com", "user": "user@example.com" },
"usedFallback": false,
"statusOnly": false
}
}
Antwort (Fehler — nichts gefunden):
{ "success": false, "error": "Connected but LIST failed and no folders could be found." }
Wichtig: Die Ordnerliste ist im data-Objekt eingebettet. Verwenden Sie data.folders[].path-Werte als Eingabe für das folders-Array beim Starten einer Migration.
Proxy-Fallback: Manche Server (z.B. Zimbra-Proxys) lehnen den LIST-Befehl ab. Die API findet Ordner dann über alternative LIST-Pattern und STATUS-Probes. In dem Fall ist usedFallback auf true gesetzt; wenn nur STATUS-basierte Erkennung möglich war, ist statusOnly auf true. Die Verbindung selbst ist trotzdem gültig.
Migration starten
POST /api/v1/imap/migrate
Authorization: Bearer IHR_API_TOKEN
Content-Type: application/json
{
"source": {
"host": "imap.alter-server.com",
"port": 993,
"user": "user@alter-server.com",
"password": "quell-passwort",
"secure": true
},
"destination": {
"host": "imap.neuer-server.com",
"port": 993,
"user": "user@neuer-server.com",
"password": "ziel-passwort",
"secure": true
},
"folders": ["INBOX", "Sent", "Drafts", "Archive"],
"destPrefix": "Alter-Account"
}
Antwort:
{
"success": true,
"migrationId": "abc-123-def",
"status": "pending",
"queue": { "position": 2, "totalInQueue": 3 },
"statusUrl": "/api/v1/imap/migrate/abc-123-def"
}
Parameter
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
source.host | string | ja | IMAP-Hostname des Quell-Servers |
source.port | number | nein | Port (Standard: 993) |
source.user | string | ja | Benutzername / E-Mail |
source.password | string | ja | Passwort |
source.secure | boolean | nein | SSL/TLS (Standard: true) |
destination.* | - | ja | Gleiche Felder wie source |
folders | string[] | ja | Array der zu migrierenden Ordner (max 200) |
destPrefix | string | nein | Optional: Prefix für Zielordner (z.B. "Backup" → INBOX wird zu Backup/INBOX) |
deduplicate | boolean | nein | Optional: Nachrichten überspringen, deren Message-ID im Zielordner bereits existiert (Standard: false) |
Monatliches Limit: Migrationen sind je Plan begrenzt (free: 1, starter: 5, pro: 20, business: 50, enterprise: unbegrenzt). Bei Überschreitung kommt HTTP 429 mit {"success": false, "error": "Monthly limit reached (n)"}.
Status abfragen
GET /api/v1/imap/migrate/{migrationId}
Authorization: Bearer IHR_API_TOKEN
Antwort:
{
"success": true,
"migrationId": "abc-123-def",
"status": "running",
"srcHost": "imap.alter-server.com",
"srcUser": "user@alter-server.com",
"dstHost": "imap.neuer-server.com",
"dstUser": "user@neuer-server.com",
"destPrefix": "Alter-Account/",
"folders": ["INBOX", "Sent", "Drafts", "Archive"],
"progress": {
"currentFolder": "INBOX",
"foldersDone": 1,
"foldersTotal": 4,
"messagesDone": 523,
"messagesTotal": 2841,
"skippedByDedup": 0,
"folderProgress": { "INBOX": { "lastUid": 523, "doneCount": 523 } },
"errors": []
},
"totalFolders": 4,
"totalMessages": 523,
"errorCount": 0,
"startedAt": "2026-01-15T10:30:00.000Z",
"completedAt": null,
"createdAt": "2026-01-15T10:29:55.000Z",
"queue": null
}
Status-Werte
| Status | Beschreibung |
|---|---|
pending | In Warteschlange, wartet auf freien Slot |
running | Migration läuft |
completed | Erfolgreich abgeschlossen |
failed | Fehlgeschlagen (siehe errorCount und progress.errors) |
Polling
Fragen Sie den Status-Endpoint alle 2-5 Sekunden ab. Das progress-Objekt aktualisiert sich in Echtzeit während der Migration.