On this page
Locations API#
Use the Locations API to manage branches, stores, outlets or service areas in your knowledge base. Locations power “where is your nearest…” answers, opening-hours questions, and proximity search, so coordinates and operating hours matter more here than anywhere else in the knowledge base.
Endpoints#
| Method | Path |
|---|---|
| GET | /knowledge-bases/{kbId}/locations |
| GET | /knowledge-bases/{kbId}/locations/{id} |
| POST | /knowledge-bases/{kbId}/locations |
| PUT | /knowledge-bases/{kbId}/locations/{id} |
| DELETE | /knowledge-bases/{kbId}/locations/{id} |
| POST | /knowledge-bases/{kbId}/locations/bulk |
| POST | /knowledge-bases/{kbId}/locations/bulk-delete |
| POST | /knowledge-bases/{kbId}/locations/upsert |
| POST | /knowledge-bases/{kbId}/locations/reconcile |
All endpoints require the locations:read or locations:write scope. Remember that a created or updated location is not answerable until a sync runs — see Sync & Embedding.
Create a Location#
Only name and address are required. Supply latitude and longitude whenever you have them: without coordinates a location can still be found by name or city, but it cannot take part in “nearest branch” answers.
curl -X POST https://api.infinichat.dev/knowledge-bases/{kbId}/locations \
-H "X-API-Key: api_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Bangsar Branch",
"address": "12 Jalan Maarof, 59000 Kuala Lumpur",
"city": "Kuala Lumpur",
"country": "Malaysia",
"latitude": 3.1319,
"longitude": 101.6841,
"phone": "+60 3 1234 5678",
"services": ["Repairs", "Trade-in"]
}'Operating Hours#
Hours are per weekday. Use isClosed for a day the location does not open, and slots when it closes for a break and reopens — a single open/close pair cannot express a lunch closure, and the chatbot will otherwise tell a customer you are open through it.
{
"operatingHours": {
"monday": { "open": "09:00", "close": "18:00" },
"saturday": {
"slots": [
{ "open": "09:00", "close": "13:00" },
{ "open": "14:00", "close": "17:00" }
]
},
"sunday": { "isClosed": true }
}
}Syncing from another system? Use upsert, not bulk create. Bulk create inserts unconditionally, so running it twice creates two copies of every row. Upsert matches on your own key and is safe to re-run.
Upsert Locations#
Push a batch of up to 100 locations, matching existing rows by your own externalId. Fields you omit are left untouched, so a store-management system can own addresses and hours while your team maintains descriptions in the Console.
matchBy must be "externalId" — there is no default, and locations have no equivalent of a product SKU.
curl -X POST https://api.infinichat.dev/knowledge-bases/{kbId}/locations/upsert \
-H "X-API-Key: api_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"matchBy": "externalId",
"items": [
{ "externalId": "store-042", "phone": "+60 3 9999 0000" }
]
}'Delete Locations#
Delete by Gydr id, or by your own externalId so you never have to store our ids. Closing a branch temporarily? Prefer status: "temporarily_closed" through the upsert — it is reversible and keeps the location's history.
This operation is permanent and cannot be undone. For bulk cleanups, run reconcile in dry-run mode first to preview which records will be removed.
curl -X POST https://api.infinichat.dev/knowledge-bases/{kbId}/locations/bulk-delete \
-H "X-API-Key: api_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "matchBy": "externalId", "keys": ["store-042", "store-043"] }'A delete takes effect in chat immediately — unlike a create or update, it does not wait for a sync.
Reconcile Locations#
Supply your complete store feed and the API deletes every stored location whose externalId is absent from it. Use this to keep the knowledge base in sync when branches close permanently. Three guards prevent accidental mass deletion:
modeis required — there is no default."dry-run"returns a preview without touching data."apply"performs the deletions.confirmmust equal the target knowledge-base id when applying, so a copy-pasted call against the wrong knowledge base fails closed.maxDeletionPercent(default 20, ceiling 50) aborts the call if planned deletions exceed that percentage of the live catalogue. Temporarily closed branches should usestatus: "temporarily_closed"through upsert instead.
curl -X POST https://api.infinichat.dev/knowledge-bases/{kbId}/locations/reconcile \
-H "X-API-Key: api_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"matchBy": "externalId",
"keys": ["store-001", "store-002", "store-003"],
"mode": "dry-run"
}'