Sandbox
A sandbox is a real Talki account that belongs to you, served by the same
/v1 contract as production and marked by livemode: false. Registering
an app in the console issues one immediately, with no
Talki customer involved.
What the account contains
Section titled “What the account contains”A hair salon in Verona, seeded with:
- four services with different durations and capacities, one of which takes only one booking at a time;
- opening hours with a real closing day — Monday and Sunday are shut;
- four weeks of answered calls with summaries, in all three inbox states (unread, read, archived);
- the appointments those calls booked, past and upcoming, plus one cancelled in each direction;
- a contact book where some callers are named and some are bare numbers;
- open follow-up questions the assistant could not answer.
display_name carries only a name the owner curated or imported; one the
assistant extracted from a transcript is not published, and that contact stays a
bare number. The seed contains both cases.
Locations
Section titled “Locations”The sandbox has multi_sede: true and three locations:
the main one, which holds the history above, and two branches, Borgo
Trento (active) and San Zeno (inactive). Each branch has its own copy of
the main location’s services, on a default resource of its own, and a quieter
history of calls, bookings, unresolved requests and one closure. San Zeno
behaves as a location switched off by a downgrade: its records are there, and
booking at it is refused with location_inactive.
No location has a Talki number. Scenario calls are always made at the main
location. If GET /v1/locations lists only the main location,
POST /v1/sandbox/reset adds the two branches.
Limits
Section titled “Limits”A sandbox has no phone number and cannot be given one. It cannot receive real calls, is never billed, and sends no email.
Its knowledge base holds at most 5 MB, with files of at most 1 MB, website imports of at most 5 pages and PDFs of at most 20 pages, or the plan’s own limits where lower. A partner’s test account has the same caps.
Trigger a call
Section titled “Trigger a call”curl --fail-with-body -X POST https://api.talki.it/v1/sandbox/calls \ -H "Authorization: Bearer $TALKI_API_KEY" \ -H "Content-Type: application/json" \ -d '{"scenario": "booking_created", "caller_phone": "+393480000001"}'Everything downstream is real: the call record, the appointment (subject to the same capacity rules as any booking), a pending contact for a caller who gives a name, and signed webhook deliveries to your endpoint.
Reuse a caller_phone to build a caller with history; vary it to exercise the
first-time path.
Scenarios
Section titled “Scenarios”scenario |
What happened | Events |
|---|---|---|
booking_created |
A caller books. The agent finds a slot and confirms it. | call.ringing, call.ended, appointment.created |
booking_rescheduled |
A caller moves an existing booking. | call.ringing, call.ended, appointment.updated |
booking_cancelled |
A caller cancels. The slot is released. | call.ringing, call.ended, appointment.cancelled |
caller_unresolved |
A question the agent cannot answer, taken down for a callback. | call.ringing, call.ended |
contact_created |
A first-time caller gives their name. | call.ringing, call.ended |
call_no_action |
Someone asks a question and rings off. | call.ringing, call.ended |
call_transferred |
The agent hands the caller to a person. | call.ringing, call.ended, call.transferred |
GET /v1/sandbox/scenarios returns the same list at runtime, so a test suite can
enumerate them instead of hard-coding this table. The events array is part of
the contract: assert that those events arrive. It lists the events the scenario
is about, not every event the call sends. A caller who gives a name
(booking_created, booking_rescheduled, booking_cancelled,
contact_created) is also proposed as a contact, as on a real call:
pending_contact.created for a number with no contact or pending contact yet,
pending_contact.updated when an existing pending contact’s name changes.
call.ringing carries the same ID in data.call_id as the response’s call_id.
It is sent after the scenario’s booking step, so an appointment.* event can
come before it, and a scenario refused with 400 sends nothing. caller.vip is
true when caller_phone is on the main location’s VIP list: add it with
POST /v1/caller_rules to see it. A caller_phone that is not a number behaves
like a withheld one, and caller.phone_number is null.
booking_rescheduled and booking_cancelled act on the next upcoming
appointment. If the agenda has none left, they answer 400 sandbox_not_ready;
reset to continue.
curl --fail-with-body -X POST https://api.talki.it/v1/sandbox/reset \ -H "Authorization: Bearer $TALKI_API_KEY"The history comes from a fixed seed, so it is identical every time and assertions against it hold across runs. A reset rebuilds data only: your API key keeps working, your app’s installation survives, the services and the locations are still there, and the branches’ history is rebuilt with the rest. The knowledge base is left as it is: delete the documents your tests create. Webhook endpoints are not kept: a reset deletes the sandbox’s endpoints and their deliveries, puts the seed’s one paused endpoint in their place, and drops the account events still queued for your app. Register your endpoints again after each reset.
livemode
Section titled “livemode”Every webhook envelope carries livemode:
{ "id": "evt_9f2c…", "type": "appointment.created", "account_id": "f7e39b9a-1ac8-45e4-93da-2600f17cb286", "livemode": false, "origin": { "source": "voice", "credential_id": null }, "data": { }}false means the event did not really happen: it came from a sandbox or a
test-mode credential. GET /v1/account reports the same flag for the credential
you are holding, so staging and production can share one receiver and still keep
fixtures out of the live system.
Going live
Section titled “Going live”Same code, same base URL; only the credential changes. Real businesses can install your app once it is approved.
