Get Your API Key
First, you’ll need to create a Migma.ai account and generate an API key:
Navigate to Settings
Go to Settings → API Integration → API Keys tab
Create API Key
Click Create API Key , select permissions, and save your key securely
Store your API key securely! It won’t be shown again after creation. Treat it like a password.
Prefer the terminal? Install the CLI with npm install -g @migma/cli and run migma login to get started — then use commands like migma generate, migma send, and migma validate directly from your shell.
Import Your Brand
Before generating emails, you need to import your brand information:
import Migma from 'migma' ;
const migma = new Migma ( process . env . MIGMA_API_KEY );
// importAndWait polls automatically until the brand is ready
const { data , error } = await migma . projects . importAndWait ({
urls: [ 'https://yourbrand.com' ]
});
console . log ( 'Project ID:' , data . projectId );
curl -X POST https://api.migma.ai/v1/projects/import \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": ["https://yourbrand.com"],
"name": "My Brand"
}'
const response = await fetch ( 'https://api.migma.ai/v1/projects/import' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
urls: [ 'https://yourbrand.com' ],
name: 'My Brand'
})
});
const data = await response . json ();
console . log ( 'Project ID:' , data . data . projectId );
import requests
response = requests.post(
'https://api.migma.ai/v1/projects/import' ,
headers = {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
json = {
'urls' : [ 'https://yourbrand.com' ],
'name' : 'My Brand'
}
)
data = response.json()
print ( f "Project ID: { data[ 'data' ][ 'projectId' ] } " )
Brand import is asynchronous. The SDK’s importAndWait handles polling automatically. With raw HTTP, save the projectId and poll the status endpoint or use webhooks.
Generate Your First Email
Once your brand is imported, generate an email:
// generateAndWait polls automatically until the email is ready
const { data , error } = await migma . emails . generateAndWait ({
projectId: 'your_project_id' ,
prompt: 'Create a welcome email for new subscribers' ,
languages: [ 'en' ]
});
const firstEmail = data . result . emails [ 0 ];
console . log ( 'Email ID:' , firstEmail . emailId );
console . log ( 'HTML:' , firstEmail . html );
console . log ( 'Screenshot:' , firstEmail . screenshotUrl );
curl -X POST https://api.migma.ai/v1/projects/emails/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "your_project_id",
"prompt": "Create a welcome email for new subscribers",
"languages": ["en"]
}'
const response = await fetch (
'https://api.migma.ai/v1/projects/emails/generate' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
projectId: projectId ,
prompt: 'Create a welcome email for new subscribers' ,
languages: [ 'en' ]
})
}
);
const data = await response . json ();
console . log ( 'Conversation ID:' , data . data . conversationId );
console . log ( 'Status:' , data . data . status ); // 'pending'
response = requests.post(
'https://api.migma.ai/v1/projects/emails/generate' ,
headers = {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
json = {
'projectId' : project_id,
'prompt' : 'Create a welcome email for new subscribers' ,
'languages' : [ 'en' ]
}
)
data = response.json()
print ( f "Conversation ID: { data[ 'data' ][ 'conversationId' ] } " )
print ( f "Status: { data[ 'data' ][ 'status' ] } " ) # 'pending'
Poll for Status
Email generation is asynchronous. The SDK’s generateAndWait handles polling automatically. For manual polling:
// generateAndWait already handles polling — but you can also poll manually:
const { data } = await migma . emails . getGenerationStatus ( 'conversation_id' );
if ( data . status === 'completed' ) {
const firstEmail = data . result . emails [ 0 ];
console . log ( 'Email ID:' , firstEmail . emailId );
console . log ( 'HTML:' , firstEmail . html );
}
async function waitForGeneration ( conversationId ) {
while ( true ) {
const response = await fetch (
`https://api.migma.ai/v1/projects/emails/ ${ conversationId } /status` ,
{
headers: {
'Authorization' : 'Bearer YOUR_API_KEY'
}
}
);
const data = await response . json ();
const status = data . data . status ;
if ( status === 'completed' ) {
console . log ( 'Email generated successfully!' );
const firstEmail = data . data . result . emails [ 0 ];
console . log ( 'Email ID:' , firstEmail . emailId );
console . log ( 'HTML:' , firstEmail . html );
return data . data ;
} else if ( status === 'failed' ) {
throw new Error ( `Generation failed: ${ data . data . error } ` );
}
// Wait 2 seconds before next poll
await new Promise ( resolve => setTimeout ( resolve , 2000 ));
}
}
Better approach : Use the SDK ’s generateAndWait or set up webhooks to get notified when generation completes.
Get, Edit, and Send the Generated Email
Use emailId from result.emails[] to fetch, prompt-edit, test-send, or send one generated email. This is required for email series because conversationId points at the whole generation.
const { data } = await migma . emails . getGenerationStatus ( conversationId );
if ( data . status === 'completed' ) {
const selected = data . result . emails [ 0 ];
const email = await migma . emails . get ( selected . emailId );
console . log ( 'HTML:' , email . data . html );
console . log ( 'Screenshot:' , email . data . screenshotUrl );
await migma . emails . edit ( selected . emailId , {
prompt: 'Make this welcome email shorter and more transactional'
});
await migma . sending . send ({
recipientType: 'email' ,
recipientEmail: 'sarah@example.com' ,
from: 'hello@yourbrand.migma.email' ,
fromName: 'Your Brand' ,
subject: selected . subject ,
emailId: selected . emailId
});
}
curl https://api.migma.ai/v1/emails/{emailId} \
-H "Authorization: Bearer YOUR_API_KEY"
curl -X POST https://api.migma.ai/v1/emails/{emailId}/edit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Make this welcome email shorter and more transactional"}'
curl -X POST https://api.migma.ai/v1/sending \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipientType": "email",
"recipientEmail": "sarah@example.com",
"from": "hello@yourbrand.migma.email",
"fromName": "Your Brand",
"subject": "Welcome",
"emailId": "EMAIL_ID"
}'
const response = await fetch (
`https://api.migma.ai/v1/projects/emails/ ${ conversationId } /status` ,
{
headers: {
'Authorization' : 'Bearer YOUR_API_KEY'
}
}
);
const data = await response . json ();
if ( data . data . status === 'completed' ) {
const selected = data . data . result . emails [ 0 ];
const emailHtml = selected . html ;
const emailId = selected . emailId ;
console . log ( 'Email ID:' , emailId );
console . log ( 'Generated HTML:' , emailHtml );
}
Complete Example
Here’s a complete workflow from import to generated HTML:
import Migma from 'migma' ;
const migma = new Migma ( process . env . MIGMA_API_KEY );
// 1. Import brand (waits for completion automatically)
const brand = await migma . projects . importAndWait ({
urls: [ 'https://yourbrand.com' ]
});
console . log ( 'Brand imported:' , brand . data . projectId );
// 2. Generate email (waits for completion automatically)
const email = await migma . emails . generateAndWait ({
projectId: brand . data . projectId ,
prompt: 'Create a welcome email for new subscribers' ,
languages: [ 'en' ]
});
console . log ( 'Subject:' , email . data . result . subject );
const selectedEmail = email . data . result . emails [ 0 ];
console . log ( 'Email ID:' , selectedEmail . emailId );
console . log ( 'HTML:' , selectedEmail . html . substring ( 0 , 200 ) + '...' );
const MIGMA_API_KEY = 'your_api_key_here' ;
const BASE_URL = 'https://api.migma.ai' ;
async function generateEmail () {
try {
// 1. Import brand
console . log ( 'Importing brand...' );
const importRes = await fetch ( ` ${ BASE_URL } /v1/projects/import` , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ MIGMA_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
urls: [ 'https://yourbrand.com' ],
name: 'My Brand'
})
});
const importData = await importRes . json ();
const projectId = importData . data . projectId ;
console . log ( 'Project created:' , projectId );
// 2. Wait for import to complete (simplified - use webhooks in production)
await new Promise ( resolve => setTimeout ( resolve , 10000 ));
// 3. Generate email
console . log ( 'Generating email...' );
const genRes = await fetch (
` ${ BASE_URL } /v1/projects/emails/generate` ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ MIGMA_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
projectId: projectId ,
prompt: 'Create a welcome email for new subscribers' ,
languages: [ 'en' ]
})
}
);
const genData = await genRes . json ();
const conversationId = genData . data . conversationId ;
console . log ( 'Generation started:' , conversationId );
// 4. Poll for completion
let completed = false ;
let emailData = null ;
while ( ! completed ) {
await new Promise ( resolve => setTimeout ( resolve , 2000 ));
const statusRes = await fetch (
` ${ BASE_URL } /v1/projects/emails/ ${ conversationId } /status` ,
{
headers: { 'Authorization' : `Bearer ${ MIGMA_API_KEY } ` }
}
);
const statusData = await statusRes . json ();
if ( statusData . data . status === 'completed' ) {
completed = true ;
emailData = statusData . data ;
} else if ( statusData . data . status === 'failed' ) {
throw new Error ( 'Generation failed: ' + statusData . data . error );
}
}
console . log ( 'Email generated successfully!' );
const selectedEmail = emailData . result . emails [ 0 ];
return {
emailId: selectedEmail . emailId ,
html: selectedEmail . html ,
screenshotUrl: selectedEmail . screenshotUrl
};
} catch ( error ) {
console . error ( 'Error:' , error );
throw error ;
}
}
// Run it
generateEmail (). then ( result => {
console . log ( 'Email ID:' , result . emailId );
console . log ( 'HTML:' , result . html . substring ( 0 , 200 ) + '...' );
});
Next steps
Node.js SDK Full SDK guide with error handling, polling, and all 14 resources
CLI Generate, send, and validate from your terminal
MCP Server Connect Migma to Claude Desktop, Cursor, and other AI tools
Skills Add Migma to AI coding assistants
Set Up Webhooks Real-time notifications instead of polling
API Reference Full endpoint documentation
Common Issues
Check that your API key is correct and included in the Authorization header as Bearer YOUR_API_KEY
Brand imports can take 30-60 seconds. Use webhooks to get notified when complete instead of polling.
Check the error message in the response. Common issues:
Invalid projectId (brand not imported yet)
Prompt is too vague or too long
Rate limit exceeded
The generated HTML is optimized for email clients. Test it in an actual email client or use a service like Litmus.