Skip to content

Work with locations

A business can work from more than one place. Each location has its own Talki number, its own line that forwards to it, assistant settings, weekly hours, services, resources and bookings. Every account has exactly one main location, and every record the API publishes says which location it belongs to, so the same integration code serves an account with one location and an account with several.

Show locations only when multi_sede is true

Section titled “Show locations only when multi_sede is true”

multi_sede on GET /v1/account says whether the business works with locations. When it is false, the account has exactly one location, the main one: do not show a location picker or a location column to the owner. Every record still carries the main location’s location_id, and nothing changes shape if the flag later turns true.

GET /v1/locations returns every location in one page, active ones first and then in the owner’s order. It needs account:read.

Terminal window
curl --fail-with-body https://api.talki.it/v1/locations \
-H "Authorization: Bearer $TALKI_API_KEY"
  • is_default marks the main location. It is never switched off, and its phone_number and line are the account’s.
  • An inactive location was switched off in Talki, by the owner or because the plan has room for fewer locations. It stays in the list with its records, takes no calls or bookings, and has no Talki number.
  • name is unique among active locations only. Key on id.

Locations are created, renamed, reordered and switched off in Talki. The API has no write for them.

Object location_id
Call, RefusedCall The location whose number was dialled
UnresolvedRequest The location of the call it was raised on
Appointment The location of its service
Service, Resource The location that offers it
Document The location whose assistant uses it
CallerRule, BlockedCallAttempt The location whose calls the rule matches; a rule added without location_id is the main location’s
Closure The one location it applies at, or null for every location

Except on a closure, it is never null, and it never changes: a record does not move between locations. Calls from before the account had several locations belong to the main one. Contacts and tags belong to the account and carry no location_id. A number blocked or marked VIP at one location is not at the others: add a rule at each location it should apply at.

These lists take ?location_id=. Without it they return the records of every location; with it, those of that location only:

  • GET /v1/calls, /v1/calls/count, /v1/calls/stats, /v1/calls/export and POST /v1/calls/mark_all_read
  • GET /v1/refused_calls, /v1/refused_calls/count, /v1/refused_calls/summary
  • GET /v1/appointments, /v1/services, /v1/resources, /v1/unresolved_requests, /v1/documents, /v1/caller_rules, /v1/caller_rules/blocked_attempts
  • GET /v1/closures, which with a location returns that location’s closures together with those of every location

The id may be an inactive location’s. An id that is not one of the account’s locations answers 404 resource_not_found.

A change feed can be walked for one location, because a record never changes location. The cursor it returns is bound to that location: send it back with the same location_id. Under another location_id, or without one, it is refused with 400 invalid_cursor. To mirror the whole account, walk without the filter.

The configuration a location holds takes ?location_id= too. Without it, it is the main location’s:

  • GET and PATCH /v1/account — the assistant settings, the switches (unresolved_requests_enabled, remember_callers, store_transcripts, notify_on_every_call, notify_on_incoming_call), forwarding_number, phone_number and line of that location. A PATCH naming a location changes them at that location only. call_auto_archive_days is the account’s own setting: it reads the same at every location, and is written only without location_id or with the main location’s; another location’s is refused with 400 invalid_parameter.
  • GET and PUT /v1/working_hours — that location’s weekly hours.
  • GET and POST /v1/forwarding_check — rings that location’s line from its own Talki number. Each location runs one check at a time and at most 3 an hour. An inactive location has no number, so its check is refused with 409 phone_number_missing.

An inactive location’s settings and hours can still be read and changed; they apply once it is switched back on.

The ETag of /v1/account and /v1/working_hours belongs to the location it was read at. Send If-Match with the same location_id you read with.

Transfer targets are checked against every location’s line: a location’s transfer_numbers may not contain its own or the main location’s forwarding_number, nor another location’s, and a location’s forwarding_number may not be another location’s line, nor a transfer target of any location, unless the same request replaces this location’s own transfer_numbers. A non-empty transfer_numbers at any location needs the main location’s forwarding_number, already stored or sent in the same request to the main location, and the main location’s forwarding_number cannot be cleared while any location has transfer_numbers.

A closure takes location_id in the body of POST /v1/closures. Without it, the closure applies at every location. It cannot be moved to another location afterwards: a PATCH with a different location_id is refused with 400 invalid_parameter, so delete it and create another.

  • Appointments. A booking is made at its service’s location, against that location’s hours, closures and resources; a booking without a service is made at the main location. POST /v1/appointments takes no location_id: pick the service of the right location from GET /v1/services?location_id=. Each location has its own copy of a service, with its own id.
  • Services and resources. POST /v1/services and POST /v1/resources take ?location_id=, the main location without it. resource_ids and service_ids must belong to that location, or the create is refused with 400 invalid_parameter. A service sent with neither initial_capacity nor resource_ids draws on its location’s default resource.
  • Documents. POST /v1/documents takes ?location_id=, the main location without it, and location_ids for a copy at each other location named; see Copies at other locations.
  • Inactive locations. A location that is switched off takes no bookings. Booking a service of an inactive location, moving one of its bookings to a new time and restoring one of its cancelled bookings are refused with 400 location_inactive. Its bookings can still be renamed and cancelled.
Event When data.object
location.created A location is added Location
location.updated A location’s name, order, Talki number or line changes Location
location.deactivated A location is switched off Location
location.reactivated A location is switched back on Location
location.settings_updated A location other than the main one changes the assistant settings it keeps for itself Account, read at that location
location.working_hours_updated The weekly hours of a location other than the main one change WorkingHours of that location

All of them need account:read. The main location’s number and line, its settings and its hours stay on account.updated and working_hours.updated, and so does call_auto_archive_days: each change arrives under one type only.

A location can be switched off or on by the plan as well as by the owner, so expect these events with origin.source system. Switching a location off also clears its phone_number; that arrives as the one location.deactivated.