1. Introduction about Batch structure
All phone numbers should include the country prefix in E.164 format
All phone numbers should have contact_number
as the header
All other variables can be included in the CSV file in separate coloumns
contact_number, first_name, last_name
+11231237890, Bruce, Wayne
+91012345678, Bruce, Lee
+00021000000, Satoshi, Nakamoto
+44999999007, James, Bond
2. How to Export a CSV file from Excel or Google Sheets for Batch
In Excel, when you type a +
at the beginning of a cell, Excel interprets it as a formula.
To ensure the plus sign +
is retained when entering phone numbers with country codes,
please add an apostrophe ('
) before the plus sign.
Download an example CSV file
3. Step by step tutorial to use Batch APIs
i. Create a batch for agent
Once the CSV file is ready, upload it using the Create Batch API
curl --location 'https://api.bolna.ai/batches' \
--header 'Authorization: Bearer <api_key>' \
--form 'agent_id="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"' \
--form 'file=@"/my-first-batch.csv"'
ii. Scheduling the batch
After receiving your batch_id
, you can schedule a batch using Schedule Batch API
The scheduled date and time should be in ISO 8601 format with time zone.
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345/schedule' \
--header 'Authorization: Bearer <api_key>' \
--form 'scheduled_at="2024-03-20T04:05:00+00:00"'
iii. Retrieving batch status
Check the status of the batch using Get Batch API
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345' \
--header 'Authorization: Bearer <api_key>'
iv. Retrieving all batch executions
Once the batch has run, you can check all executions by the agent using List Batch Executions API
curl --location 'https://api.bolna.ai/batches/abcdefghijklmnopqrstuvwxyz012345/executions' \
--header 'Authorization: Bearer <api_key>'
4. Example Batch Application using the above flow with APIs
Example code using the above Batch APIs together
import asyncio
import os
from dotenv import load_dotenv
import aiohttp
# Load environment variables from .env file
load_dotenv()
# Load from .env
host = "https://api.bolna.ai"
api_key = os.getenv( "api_key" , None )
agent_id = 'ee153a6c-19f8-3a61-989a-9146a31c7834' #agent_id in which we want to create the batch
file_path = '/path/of/csv/file'
schedule_time = '2024-06-01T04:10:00+05:30'
async def schedule_batch ( api_key , batch_id , scheduled_at ):
print ( "now scheduling batch for batch id : {} " .format(batch_id))
url = f " { host } /batches/ { batch_id } /schedule"
headers = { 'Authorization' : f 'Bearer { api_key } ' }
data = {
'scheduled_at' : scheduled_at
}
try :
async with aiohttp.ClientSession() as session:
async with session.post(url, headers = headers, data = data) as response:
response_data = await response.json()
if response.status == 200 :
return response_data
else :
raise Exception ( f "Error scheduling batch: { response_data } " )
except aiohttp.ClientError as e:
print ( f "HTTP Client Error: { str (e) } " )
except Exception as e:
print ( f "Unexpected error: { str (e) } " )
async def get_batch_status ( api_key , batch_id ):
print ( "now getting batch status for batch id : {} " .format(batch_id))
url = f " { host } /batches/ { batch_id } "
headers = { 'Authorization' : f 'Bearer { api_key } ' }
try :
async with aiohttp.ClientSession() as session:
async with session.get(url, headers = headers) as response:
response_data = await response.json()
if response.status == 200 :
return response_data
else :
raise Exception ( f "Error getting batch status: { response_data } " )
except aiohttp.ClientError as e:
print ( f "HTTP Client Error: { str (e) } " )
except Exception as e:
print ( f "Unexpected error: { str (e) } " )
async def get_batch_executions ( api_key , batch_id ):
print ( "now getting batch executions for batch id : {} " .format(batch_id))
url = f " { host } /batches/ { batch_id } /executions"
headers = { 'Authorization' : f 'Bearer { api_key } ' }
try :
async with aiohttp.ClientSession() as session:
async with session.get(url, headers = headers) as response:
response_data = await response.json()
if response.status == 200 :
return response_data
else :
raise Exception ( f "Error getting batch executions: { response_data } " )
except aiohttp.ClientError as e:
print ( f "HTTP Client Error: { str (e) } " )
except Exception as e:
print ( f "Unexpected error: { str (e) } " )
async def create_batch ():
url = f " { host } /batches"
headers = { 'Authorization' : f 'Bearer { api_key } ' }
with open (file_path, 'rb' ) as f:
form_data = aiohttp.FormData()
form_data.add_field( 'agent_id' , agent_id)
form_data.add_field( 'file' , f, filename = os.path.basename(file_path))
async with aiohttp.ClientSession() as session:
async with session.post(url, headers = headers, data = form_data) as response:
response_data = await response.json()
if response_data.get( 'state' ) == 'created' :
batch_id = response_data.get( 'batch_id' )
res = await schedule_batch(api_key, batch_id, scheduled_at = schedule_time)
if res.get( 'state' ) == 'scheduled' :
check = True
while check:
# Checking the current status every 1 minute
await asyncio.sleep( 60 )
res = await get_batch_status(api_key, batch_id)
if res.get( 'status' ) == 'completed' :
check = False
break
if not check:
res = await get_batch_executions(api_key, batch_id)
print (res)
return res
if __name__ == "__main__" :
asyncio.run(create_batch())