Синхронізація
Три інструменти для двобічної синхронізації без дублів: ваш ключ запису (external_id), вибірка змін за updated_at і список видалених записів.
external_id: ваш ключ у записі Silium
Контакти, контрагенти, ліди, угоди, замовлення й рахунки мають поле external_id (рядок до 64 символів), тобто id запису у вашій системі: номер замовлення на сайті, код контрагента в 1С, id ліда з форми. Воно унікальне в межах сутності.
Створення з вашим ключем
POST /api/v1/order
{ "name": "Замовлення з сайту №1001", "external_id": "site-1001", "contact_id": 42, ... }Пошук за ключем
GET /api/v1/order?filter[external_id;eq]=site-1001
Ключ уже зайнятий: 409 з id власника
{
"error": {
"code": "conflict",
"message": "external_id уже використано іншим записом",
"existing_id": 85,
"deleted": false
}
}Схема «створи або онови»
POSTзexternal_id.201означає, що запис створено.409 conflictозначає, що запис уже є. Тоді надішлітьPUT /{сутність}/{existing_id}з тими самими даними.
- ●Порожній рядок зберігається як
null, тому записи без ключа не конфліктують між собою. - ●Кілька одночасних POST з однаковим ключем: рівно один отримає
201, решта отримають той самий409зexisting_id. - ●Видалений запис тримає свій ключ (у 409 буде
"deleted": true), тому повторно цей ключ не використати: створюйте запис з іншим (наприклад, із суфіксом). - ●Копіювання запису в інтерфейсі (клон, розділення замовлення) ключ не переносить.
- ●У товарів
external_idтеж є (до 100 символів), але не унікальний. Ідентифікуйте товари заsku(артикул унікальний) або перевіряйте наявність фільтром.
Зміни з моменту останньої синхронізації
Кожен запис має updated_at. Забирайте лише змінене, сортуючи за ним:
GET /api/v1/contact ?filter[updated_at;gte]=2026-09-30 12:00:00 &order=updated_at &per-page=100 &page=1
- ●Запам’ятовуйте найбільший
updated_atз отриманих і наступного разу стартуйте з нього (gte, неgt: записи з тією самою секундою не загубляться; повтори відсійте заid). - ●Беріть невелике перекриття (1–2 хвилини), щоб не пропустити транзакції, що завершились із запізненням.
- ●Час у фільтрі задається в часовому поясі кабінету.
Видалені записи
Видалений запис зникає зі списків, і за updated_at його не побачити. Тому є окремий маршрут:
/{сутність}/deleted?since=…since. Сутності: contact, account, lead, opportunity, task, product, order, invoice.GET /api/v1/order/deleted?since=2026-09-30T12:00:00+03:00
{
"items": [ { "id": 77, "deleted_at": "2026-09-30T13:05:11+03:00" } ],
"total": 1, "page": 1, "per_page": 20
}| Параметр | Опис |
|---|---|
since | Обов’язковий. RFC 3339 (2026-09-30T12:00:00+03:00), 2026-09-30 12:00:00 або 2026-09-30. |
page, per-page | Як у звичайних списках. |
Повний цикл
Python: інкрементальна синхронізація контактів
import requests
API = "https://<компанія>.silium.io/api/v1"
H = {"Authorization": f"Bearer {TOKEN}"}
def pages(path, params):
page = 1
while True:
r = requests.get(f"{API}{path}", headers=H, params={**params, "page": page, "per-page": 100})
r.raise_for_status()
data = r.json()
yield from data["items"]
if page * data["per_page"] >= data["total"]:
return
page += 1
since = load_checkpoint() # напр. "2026-09-30 12:00:00"
for c in pages("/contact", {"filter[updated_at;gte]": since, "order": "updated_at"}):
upsert_local(c)
for d in pages("/contact/deleted", {"since": since}):
delete_local(d["id"])
save_checkpoint(now_minus_2_minutes())Записуйте в Silium через external_id і Idempotency-Key: повтор після обриву зв’язку не створить дубль.