The new OVHcloud Mail Migrator API v3
OVHcloud is investing in the improvement of its OVH Mail Migrator tool.
As part of a complete overhaul of our interface and a user experience enhancement, we need to modify the way our APIs are implemented.
You have until November 24, 2025, to update your scripts and applications accordingly.
v3 will completely replace the current API
This new version provides a modern and easier interface than the previous ones.
The legacy API is deprecated and will be removed on 24/11/2025.
You will not be able to create new migration, project, or file upload at this date and you will have to use the incoming API v3.
Meanwhile, you can still use the actual API by setting the HTTP header 'X-Ovh-Use-Deprecated-Api' to '1' in your calls."
Breaking change: create a project before creating migrations
In v3 you must first create a dedicated project. Only after the project exists can you define and run migrations within that project.
You do that by calling the /v3/Register route. Then you login to your project by calling the /v3/Login route.
Then when you are logged in and have received your JWT token, call the route /v3/Migration with your JWT token to create a migration inside your project.
Comparative table between v2 and v3
| v2 |
v3 |
| Creating a project was not mandatory in v2 |
/v3/Register (create project) |
| /Migration |
/v3/Login (get JWT) -> /v3/Migration (create migration in project) |
Example code snippets in python
Register to a project, login and create a migration
import requests
BASE_URL = "https://example.com/v3"
def register(email, password, user_language, agree_terms):
url = f"{BASE_URL}/v3/Auth/Register"
payload = {
"Email": email,
"Password": password,
"UserLanguage": user_language,
"AgreeTerms": agree_terms
}
response = requests.post(url, json=payload)
response.raise_for_status()
data = response.json()
# Returns access and refresh tokens
return data["AccessToken"], data["RefreshToken"]
def login(project_id, password):
url = f"{BASE_URL}/v3/Auth/Login"
payload = {
"ProjectId": project_id,
"Password": password
}
response = requests.post(url, json=payload)
response.raise_for_status()
data = response.json()
return data["AccessToken"], data["RefreshToken"]
def create_migration(access_token, source, destination, planned_date=None):
url = f"{BASE_URL}/v3/Migration"
headers = {"Authorization": f"Bearer {access_token}"}
payload = {
"Source": source, # Dict matching MigrationTaskAccountDTO
"Destination": destination, # Dict matching MigrationTaskAccountDTO
"PlannedDate": planned_date, # ISO8601 string or None
"MigrateMail": True,
"MigrateFolder": True,
"MigrateInboxRules": False,
"MigrateContact": True,
"MigrateContactGroup": False,
"MigrateTask": False,
"MigrateCalendar": True,
"MigrateOofSettings": False
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()["MigrationUniqueId"]
# Example usage:
email = "user@example.com"
password = "yourpassword"
user_language = "en"
agree_terms = True
# Register (returns JWT tokens)
access_token, refresh_token = register(email, password, user_language, agree_terms)
# Login is optional after registering since you get your tokens after registering
# project_id = "your-project-id"
# access_token, refresh_token = login(project_id, password)
# Prepare source and destination accounts
source = {
"ServerType": "Imap",
"ServerUrl": "https://imap.gmail.com",
"Mail": "source@example.com",
"Password": "sourcepassword"
}
destination = {
"ServerType": "Exchange",
"ServerUrl": "https://outlook.office365.com",
"Mail": "destination@example.com",
"Password": "destinationpassword"
}
# Create migration
migration_id = create_migration(access_token, source, destination)
print("Migration created with ID:", migration_id)
Refresh your JWT token
import requests
BASE_URL = "https://example.com/v3/"
def refresh_token(project_id, refresh_token):
url = f"{BASE_URL}/v3/Auth/Refresh"
payload = {
"ProjectId": project_id,
"RefreshToken": refresh_token
}
response = requests.post(url, json=payload)
response.raise_for_status()
data = response.json()
# Returns new access and refresh tokens
return data["AccessToken"], data["RefreshToken"]
# Example usage:
project_id = "your-project-id" # Replace with your project id
refresh_token_value = "your-refresh-token" # Replace with your refresh token
access_token, new_refresh_token = refresh_token(project_id, refresh_token_value)
print("New Access Token:", access_token)
print("New Refresh Token:", new_refresh_token)
Authentication relies on JWT tokens with an access and a refresh token
All API calls require a JSON Web Token (JWT). An access token for immediate calls and a refresh token to obtain new access tokens when needed.
OpenAPI schema and Swagger documentation
The OpenAPI JSON schema can be downloaded here.
Open it in the Swagger Editor to explore the full definition of the new API.