Inbound Calls
Have your outbound bot dial Noveum numbers so synthetic personas can test it, one run at a time.
In an inbound batch the direction is reversed: instead of NovaSynth calling your agent, your bot places the call. Each run in the batch is one persona-scenario test case. Your script claims a run, the platform parks the synthetic persona on one of your provisioned Noveum phone numbers, and hands that number to your dialler. Your bot calls it, talks to the persona, and the platform records and scores the conversation.
Install
pip install noveum-traceThe script
The loop below runs the calls sequentially, one at a time. Claim a run, dial the number it hands out, wait for the platform to mark the run finished, move on to the next.
"""Client-initiated NovaSynth calls: your outbound bot calls a Noveum number."""
from noveum_trace.novasynth import Call, CallQueue
# --- 1. Your details --------------------------------------------------------
NOVEUM_API_KEY = "nv_..." # or leave None and set the NOVEUM_API_KEY env var
ORGANIZATION_SLUG = "your-org-slug" # shown in the dashboard URL
# Paste the run ids from the Run IDs dialog (Copy all) between the brackets.
RUN_IDS = [
"run_id_1",
"run_id_2",
]
# --- 2. Your dialler --------------------------------------------------------
def place_call(call: Call) -> None:
"""Make your outbound bot dial ``call.dial_number``."""
raise NotImplementedError("dial call.dial_number with your bot here")
# --- 3. The loop (no changes needed) ---------------------------------------
if __name__ == "__main__":
queue = CallQueue(
RUN_IDS,
api_key=NOVEUM_API_KEY,
organization_slug=ORGANIZATION_SLUG,
)
for call in queue.iter_calls():
print(
f"[{call.run_id}] dial {call.dial_number} "
f"({call.persona_name} / {call.scenario_name}, "
f"{call.seconds_remaining:.0f}s left)"
)
try:
place_call(call)
except Exception as exc:
print(f"[{call.run_id}] dial failed: {exc}")
continue
print(f"[{call.run_id}] finished: {call.wait_until_finished()}")
print("summary:", queue.summary()) # e.g. {'completed': 5, 'expired': 1}Get your run ids
Go to the Runs page of NovaSynth in your desired project and select Start run. If the batch you configure is an inbound one, you will see a screen like this once the batch is created; the Run IDs dialog lists every run in the batch:

What you fill in
| Field | Contract |
|---|---|
NOVEUM_API_KEY | Your Noveum API key, or None with the NOVEUM_API_KEY env var set |
ORGANIZATION_SLUG | Your organization slug, shown in the dashboard URL |
RUN_IDS | The run ids from the Run IDs dialog, pasted between the brackets |
place_call | The only method you implement: make your bot dial call.dial_number |
Section 3 is the loop and needs no changes.
The place_call contract
Each claimed run hands your dialler a Call object:
| Attribute | Meaning |
|---|---|
call.dial_number | E.164 number to dial, e.g. "+918065481242" |
call.profile | Dict of this test's customer profile (name, phone, account details, situation). Pass it to your bot the same way you would for a real customer |
call.persona_name | For your logs |
call.scenario_name | For your logs |
call.seconds_remaining | Dial before this hits 0; the window is about 5 minutes |
Guidelines:
- Dial within
call.seconds_remaining. Late calls are rejected and the run is marked expired. - Return when the call has ended, or return right away; either is fine, the loop waits for the platform to mark the run finished.
- Raise on a dial failure (busy, no route, ...). The run is skipped and the number is released when its window closes.
Read the results
queue.summary() prints the terminal state of every run, e.g. {'completed': 5, 'expired': 1}. Finished runs appear on the batch detail page like any other batch and follow the same analysis lifecycle.
