Prerequisites
Before you begin, ensure you have:
You’ll need a valid API token. If you haven’t created one yet, follow the authentication guide to generate your token.
Know your workspace tenant/subdomain. This is the subdomain in your Mihu workspace URL (e.g., if your URL is https://abc.mihu.ai, your tenant is abc).
You’ll need an Agent ID to initiate calls. You can find your agents in the Mihu dashboard under the Agents section. The Agent ID is a UUID format identifier.
Make Your First API Call
Let’s initiate an AI-powered voice call using the Mihu API. This example will show you how to start a conversation with a phone number.
Step 1: Set Up Your Environment
First, set up your credentials as environment variables:
Terminal
.env (Node.js)
.env (Python)
export MIHU_API_TOKEN = "your-api-token-here"
export MIHU_TENANT = "your-tenant-here"
export MIHU_AGENT_ID = "your-agent-id-here"
MIHU_API_TOKEN = your - api - token - here
MIHU_TENANT = your - tenant - here
MIHU_AGENT_ID = your - agent - id - here
MIHU_API_TOKEN = your - api - token - here
MIHU_TENANT = your - tenant - here
MIHU_AGENT_ID = your - agent - id - here
Step 2: Initiate Your First Call
cURL
JavaScript/Node.js
Python
TypeScript
curl -X POST https://{your-tenant}.mihu.ai/api/v1/call \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agentId": "your-agent-id-here",
"participant": {
"number": "+1234567890"
}
}'
// Using fetch (built-in in Node.js 18+)
const initiateCall = async () => {
const response = await fetch ( 'https://your-tenant.mihu.ai/api/v1/call' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . MIHU_API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
agentId: process . env . MIHU_AGENT_ID ,
participant: {
number: '+1234567890'
}
})
});
const data = await response . json ();
console . log ( 'Call initiated:' , data );
return data ;
};
initiateCall ();
import requests
import os
def initiate_call ():
url = f "https:// { os.getenv( 'MIHU_TENANT' ) } .mihu.ai/api/v1/call"
headers = {
"Authorization" : f "Bearer { os.getenv( 'MIHU_API_TOKEN' ) } " ,
"Content-Type" : "application/json"
}
data = {
"agentId" : os.getenv( 'MIHU_AGENT_ID' ),
"participant" : {
"number" : "+1234567890"
}
}
response = requests.post(url, headers = headers, json = data)
result = response.json()
print ( "Call initiated:" , result)
return result
# Execute the call
initiate_call()
interface CallRequest {
agentId : string ;
participant : {
number : string ;
};
}
interface CallResponse {
success : boolean ;
message : string ;
data : {
id : string ;
status : string ;
provider : string ;
};
}
const initiateCall = async () : Promise < CallResponse > => {
const response = await fetch (
`https:// ${ process . env . MIHU_TENANT } .mihu.ai/api/v1/call` ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . MIHU_API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
agentId: process . env . MIHU_AGENT_ID ,
participant: {
number: '+1234567890'
}
} as CallRequest )
}
);
const data = await response . json ();
console . log ( 'Call initiated:' , data );
return data ;
};
initiateCall ();
Step 3: Understanding the Response
When successful, you’ll receive a response like this:
{
"success" : true ,
"message" : "Call initiated successfully" ,
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"status" : "initiated" ,
"provider" : "twilio" ,
"agentId" : "your-agent-id-here" ,
"participant" : {
"number" : "+1234567890"
},
"createdAt" : "2025-01-15T10:30:00Z"
}
}
Indicates whether the call was initiated successfully
A human-readable message describing the result
Contains the call details Unique identifier for the call (UUID format). Save this to track the call status.
Current status of the call (e.g., “initiated”, “in-progress”, “completed”)
The telephony provider used for the call
The ID of the AI agent conducting the call
Advanced Call Options
You can customize your call with additional parameters:
cURL with Options
JavaScript
Python
curl -X POST https://your-tenant.mihu.ai/api/v1/call \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agentId": "your-agent-id-here",
"participant": {
"number": "+1234567890",
"name": "John Doe"
},
"greetingMessage": "Hello! This is an automated call from Mihu.",
"metadata": {
"campaign": "customer-survey",
"customerId": "12345"
}
}'
const response = await fetch ( 'https://your-tenant.mihu.ai/api/v1/call' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . MIHU_API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
agentId: process . env . MIHU_AGENT_ID ,
participant: {
number: '+1234567890' ,
name: 'John Doe'
},
greetingMessage: 'Hello! This is an automated call from Mihu.' ,
metadata: {
campaign: 'customer-survey' ,
customerId: '12345'
}
})
});
data = {
"agentId" : os.getenv( 'MIHU_AGENT_ID' ),
"participant" : {
"number" : "+1234567890" ,
"name" : "John Doe"
},
"greetingMessage" : "Hello! This is an automated call from Mihu." ,
"metadata" : {
"campaign" : "customer-survey" ,
"customerId" : "12345"
}
}
response = requests.post(url, headers = headers, json = data)
Checking Call Status
After initiating a call, you can check its status using the call ID:
curl -X GET https://your-tenant.mihu.ai/api/v1/calls/{call-id} \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
const getCallStatus = async ( callId ) => {
const response = await fetch (
`https://your-tenant.mihu.ai/api/v1/calls/ ${ callId } ` ,
{
headers: {
'Authorization' : `Bearer ${ process . env . MIHU_API_TOKEN } ` ,
'Content-Type' : 'application/json'
}
}
);
const data = await response . json ();
console . log ( 'Call status:' , data );
return data ;
};
def get_call_status ( call_id ):
url = f "https:// { os.getenv( 'MIHU_TENANT' ) } .mihu.ai/api/v1/calls/ { call_id } "
headers = {
"Authorization" : f "Bearer { os.getenv( 'MIHU_API_TOKEN' ) } " ,
"Content-Type" : "application/json"
}
response = requests.get(url, headers = headers)
return response.json()
Handling Errors
Always implement proper error handling:
const initiateCall = async () => {
try {
const response = await fetch ( 'https://your-tenant.mihu.ai/api/v1/call' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . MIHU_API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
agentId: process . env . MIHU_AGENT_ID ,
participant: {
number: '+1234567890'
}
})
});
if ( ! response . ok ) {
const error = await response . json ();
throw new Error ( `API Error: ${ error . message } ` );
}
const data = await response . json ();
return data ;
} catch ( error ) {
console . error ( 'Failed to initiate call:' , error . message );
throw error ;
}
};
def initiate_call ():
url = f "https:// { os.getenv( 'MIHU_TENANT' ) } .mihu.ai/api/v1/call"
headers = {
"Authorization" : f "Bearer { os.getenv( 'MIHU_API_TOKEN' ) } " ,
"Content-Type" : "application/json"
}
data = {
"agentId" : os.getenv( 'MIHU_AGENT_ID' ),
"participant" : {
"number" : "+1234567890"
}
}
try :
response = requests.post(url, headers = headers, json = data)
response.raise_for_status() # Raises an HTTPError for bad status codes
return response.json()
except requests.exceptions.HTTPError as e:
print ( f "HTTP Error: { e } " )
print ( f "Response: { e.response.json() } " )
raise
except requests.exceptions.RequestException as e:
print ( f "Request failed: { e } " )
raise
Common Error Responses
Status Code Error Solution
400 Bad Request Check your request body format and required fields 401 Unauthorized Verify your API token is correct 404 Not Found Check your tenant subdomain and endpoint URL 422 Validation Error Review the error message for invalid parameters
Next Steps
Congratulations! You’ve made your first API call. Here’s what to explore next:
Set Up Webhooks Receive real-time updates about your calls
Explore API Reference Discover all available endpoints and features
Monitor API Usage Track your API requests and responses
Error Handling Learn about error codes and troubleshooting
Complete Example
Here’s a complete working example that initiates a call and monitors its status:
Complete Example
Complete Example
require ( 'dotenv' ). config ();
const MIHU_CONFIG = {
tenant: process . env . MIHU_TENANT ,
token: process . env . MIHU_API_TOKEN ,
agentId: process . env . MIHU_AGENT_ID
};
const initiateAndMonitorCall = async ( phoneNumber ) => {
const baseUrl = `https:// ${ MIHU_CONFIG . tenant } .mihu.ai/api/v1` ;
const headers = {
'Authorization' : `Bearer ${ MIHU_CONFIG . token } ` ,
'Content-Type' : 'application/json'
};
try {
// Step 1: Initiate the call
console . log ( 'Initiating call to' , phoneNumber );
const callResponse = await fetch ( ` ${ baseUrl } /call` , {
method: 'POST' ,
headers ,
body: JSON . stringify ({
agentId: MIHU_CONFIG . agentId ,
participant: { number: phoneNumber }
})
});
if ( ! callResponse . ok ) {
throw new Error ( `Failed to initiate call: ${ callResponse . statusText } ` );
}
const callData = await callResponse . json ();
console . log ( 'Call initiated:' , callData . data . id );
// Step 2: Monitor call status
const callId = callData . data . id ;
const statusResponse = await fetch ( ` ${ baseUrl } /calls/ ${ callId } ` , {
headers
});
const statusData = await statusResponse . json ();
console . log ( 'Call status:' , statusData . data . status );
return statusData ;
} catch ( error ) {
console . error ( 'Error:' , error . message );
throw error ;
}
};
// Run the example
initiateAndMonitorCall ( '+1234567890' );
import os
import requests
from dotenv import load_dotenv
load_dotenv()
MIHU_CONFIG = {
'tenant' : os.getenv( 'MIHU_TENANT' ),
'token' : os.getenv( 'MIHU_API_TOKEN' ),
'agent_id' : os.getenv( 'MIHU_AGENT_ID' )
}
def initiate_and_monitor_call ( phone_number ):
base_url = f "https:// { MIHU_CONFIG [ 'tenant' ] } .mihu.ai/api/v1"
headers = {
"Authorization" : f "Bearer { MIHU_CONFIG [ 'token' ] } " ,
"Content-Type" : "application/json"
}
try :
# Step 1: Initiate the call
print ( f "Initiating call to { phone_number } " )
call_response = requests.post(
f " { base_url } /call" ,
headers = headers,
json = {
"agentId" : MIHU_CONFIG [ 'agent_id' ],
"participant" : { "number" : phone_number}
}
)
call_response.raise_for_status()
call_data = call_response.json()
print ( f "Call initiated: { call_data[ 'data' ][ 'id' ] } " )
# Step 2: Monitor call status
call_id = call_data[ 'data' ][ 'id' ]
status_response = requests.get(
f " { base_url } /calls/ { call_id } " ,
headers = headers
)
status_response.raise_for_status()
status_data = status_response.json()
print ( f "Call status: { status_data[ 'data' ][ 'status' ] } " )
return status_data
except requests.exceptions.RequestException as e:
print ( f "Error: { e } " )
raise
# Run the example
if __name__ == "__main__" :
initiate_and_monitor_call( "+1234567890" )