Skip to content

Initial load

Keeping data in sync

Before the first real order, AIOTIC needs your customers, your sellable articles and any customer item mappings you already know. This page is the one-time import; the next pages keep it current. If you are wondering why AIOTIC keeps a synchronised copy at all instead of querying your ERP live, see why AIOTIC synchronises your data.

Order of operations

A mapping must reference an existing customer and product (the API answers 404 otherwise), so load in this order:

  1. CustomersPUT /customer/{number} for every active debtor
  2. ProductsPUT /product/{item_number}/{language_code} for every sellable article, per language
  3. Customer item mappingsPUT /customer-product/{customer_number}/{customer_item_number}

Throughput

There is no batch endpoint today (one request per record) and no server-side rate limit. Upserts are cheap for products and mappings; customer upserts also update the identification index and take a little longer.

Data setRequestsWith 8 parallel requests
5 000 customers5 000~5 min
200 000 products200 000~1–2 h
20 000 mappings20 000~10 min

Run the initial load once, from a machine close to the tenant, with 4–8 concurrent requests. More does not help and hurts other tenants.

With the CLI

Export CSV/JSON from your ERP and let the SDK do the rest (only changed records are sent, so re-running is cheap):

bash
aiotic sync customers --from customers.csv
aiotic sync products  --from products.csv
aiotic sync mappings  --from mappings.csv

Column names follow the API field names:

csv
number,name,address,postal_code,city,vat_number,email,phone_number,contact_person,coc_number,home_page
58931,LUMITECH INSTALLATIES,Ambachtsweg 12,7327 AA,Apeldoorn,NL001234567B01,info@lumitech.example,+31 55 123 4567,J. de Boer,,
csv
item_number,language_code,description,remark
PROD-001,nl,LED Driver 48V 100W,
620206_01,nl,Kabel 3x1.5 mm² (100 m),
csv
customer_number,customer_item_number,item_number,language_code
58931,LT-ART-001,PROD-001,nl

With the SDK

python
from aiotic import AioticClient
from aiotic.sync import ChangeEvent, HashStateStore, SyncEngine

client = AioticClient()                                   # AIOTIC_* env vars
engine = SyncEngine(client, state=HashStateStore("sync-state.db"), concurrency=6)

report = engine.apply_many(
    [ChangeEvent.customer_upsert(c.number, name=c.name, address=c.street, postal_code=c.zip, city=c.city,
                                 vat_number=c.vat, email=c.email, phone_number=c.phone) for c in erp.customers()]
    + [ChangeEvent.product_upsert(p.sku, "nl", description=p.name) for p in erp.products()]
    + [ChangeEvent.mapping_upsert(m.debtor, m.their_code, item_number=m.sku, language_code="nl") for m in erp.mappings()]
)
print(report)          # sent=… deleted=0 unchanged=… failed=0 in …s

apply_many sorts by kind (customers → products → mappings), runs each kind in parallel, records a fingerprint per record, and reports failures with the reason. Re-running after a failure only sends what is still missing.

With plain HTTP

bash
curl -X PUT https://acme.aiotic.ai/customer/58931 -H "X-API-Key: $AIOTIC_SYNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"LUMITECH INSTALLATIES","address":"Ambachtsweg 12","postal_code":"7327 AA","city":"Apeldoorn","vat_number":"NL001234567B01","email":"info@lumitech.example"}'
# 202 Accepted

curl -X PUT https://acme.aiotic.ai/product/PROD-001/nl -H "X-API-Key: $AIOTIC_SYNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"description":"LED Driver 48V 100W"}'

curl -X PUT https://acme.aiotic.ai/customer-product/58931/LT-ART-001 -H "X-API-Key: $AIOTIC_SYNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"item_number":"PROD-001","language_code":"nl"}'

What to include, what to leave out

IncludeLeave out
Every debtor who can place an order, incl. branchesProspects, suppliers, employees
Every sellable article, every language you sell inDiscontinued articles (delete them — see Archiving)
Known customer codes from previous orders / EDIGuesses

Verify

bash
aiotic doctor                       # counts per table
curl -s "https://acme.aiotic.ai/customer-product/list?customer_number=58931" -H "X-API-Key: $KEY"
curl -s "https://acme.aiotic.ai/customer/search/lumitech%20apeldoorn?top_k=3" -H "X-API-Key: $KEY"

The search endpoint uses the same similarity AIOTIC uses for identification — a quick way to see whether a customer resolves from the text a document would contain.

Documentation revision 3 · Published 8 September 2026 · commit 6862d5e. Verified against AIOTIC API v1.0.0. AIOTIC is a product of DevOps Company.