Noveum.ai
Noveum Docs
Test with NovaSynthInbound Calls

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-trace

The 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:

The Run IDs dialog shown after creating an inbound batch, with the Copy all button

What you fill in

FieldContract
NOVEUM_API_KEYYour Noveum API key, or None with the NOVEUM_API_KEY env var set
ORGANIZATION_SLUGYour organization slug, shown in the dashboard URL
RUN_IDSThe run ids from the Run IDs dialog, pasted between the brackets
place_callThe 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:

AttributeMeaning
call.dial_numberE.164 number to dial, e.g. "+918065481242"
call.profileDict 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_nameFor your logs
call.scenario_nameFor your logs
call.seconds_remainingDial before this hits 0; the window is about 5 minutes

Guidelines:

  1. Dial within call.seconds_remaining. Late calls are rejected and the run is marked expired.
  2. Return when the call has ended, or return right away; either is fine, the loop waits for the platform to mark the run finished.
  3. 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.