Authentication
The Migrayt API uses JWT (JSON Web Token) Bearer authentication. All API requests (except health checks) must include a valid token in the Authorization header.
Obtaining a Token
Sign in with email and password
curl -X POST https://api.migrayt.ai/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "you@company.com",
"password": "your-password"
}'Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}A refresh_token cookie is also set as an httpOnly cookie for session persistence.
Sign in with Microsoft (SSO)
Enterprise customers using Microsoft SSO authenticate via the browser-based OAuth2 flow. API integrations using a service account should use email/password with a dedicated service account.
Using the Token
Include the token in every request:
curl https://api.migrayt.ai/api/projects \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Token Expiry and Refresh
Access tokens expire after 15 minutes. Refresh tokens expire after 30 days.
To refresh an access token:
curl -X POST https://api.migrayt.ai/api/auth/refresh \
-H "Cookie: refresh_token=your-refresh-token"The endpoint returns a new accessToken and rotates the refresh token cookie.
Token Claims
The JWT payload contains:
{
"sub": "user-uuid",
"email": "you@company.com",
"tenantId": "tenant-uuid",
"role": "owner",
"iat": 1720000000,
"exp": 1720000900
}| Claim | Description |
|---|---|
sub | User ID |
email | User email |
tenantId | Organisation ID — all data is scoped to this tenant |
role | owner, admin, or member |
Roles and Permissions
| Action | owner | admin | member |
|---|---|---|---|
| Create projects | ✅ | ✅ | ❌ |
| Start migrations | ✅ | ✅ | ✅ |
| Pause/cancel migrations | ✅ | ✅ | ✅ |
| View migration results | ✅ | ✅ | ✅ |
| Manage team members | ✅ | ✅ | ❌ |
| View billing | ✅ | ❌ | ❌ |
Error Responses
| HTTP Status | Code | Description |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid token |
401 | TOKEN_EXPIRED | Token has expired — refresh it |
403 | FORBIDDEN | Valid token but insufficient role |
{
"statusCode": 401,
"message": "Invalid or expired access token"
}Rate Limits
The authentication endpoints are rate-limited:
| Endpoint | Limit (production) | Limit (development) |
|---|---|---|
POST /api/auth/login | 10 req/min | 100 req/min |
POST /api/auth/refresh | 10 req/min | 100 req/min |
All other API endpoints are not rate-limited (they are protected by authentication).