Appearance
Quick start (15 minutes)
Start here
You will run a mock AIOTIC tenant, a receive endpoint with the SDK's validation pipeline, upload an order, and watch it flow into a (demo) ERP. Nothing here touches a real tenant.
Prerequisites
Python 3.11+ and pip (or uv). No AIOTIC account needed for this exercise.
1. Install the SDK
bash
python -m venv .venv && source .venv/bin/activate
pip install "aiotic-sdk[all]"bash
uv venv && source .venv/bin/activate
uv pip install "aiotic-sdk[all]"2. Start a mock tenant
bash
aiotic mock
# Mock AIOTIC tenant on http://localhost:8080
# keys: mock-integration-key (all endpoints), mock-sync-key (master data only)The mock implements the public API with realistic behaviour: uploads move through Waiting → Processing → Processed in a few seconds, a file name containing attention produces an Attention order with an unresolved article, fail produces Failed, and /erp/send really calls your endpoint.
3. Bootstrap your service
In a second terminal:
bash
aiotic init # answers: base URL http://localhost:8080, key mock-integration-key
aiotic doctorinit writes a .env (base URL, keys, a freshly generated AIOTIC_ERP_RECEIVE_KEY) and a service.py. doctor checks connectivity, both keys and whether master data is present:
┃ check ┃ result ┃
│ GET /healthcheck │ OK ok │
│ GET /order_status/list (key) │ OK 0 orders │
│ master data: customers │ OK 1 records │
│ master data: products │ OK 3 records │4. Run the receive endpoint
bash
aiotic serve # http://localhost:9000 (POST /aiotic/orders, /aiotic/processing, /erp/events)service.py is three lines — the in-memory demo ERP behind the default pipeline:
python
from aiotic.service import build_app
from aiotic.erp.memory import InMemoryErp # replace with your adapter later
app = build_app(erp=InMemoryErp())Tell the mock tenant where your endpoint lives (in production you give this to the AIOTIC team; the mock has a helper):
bash
curl -X POST localhost:8080/_mock/config -H 'Content-Type: application/json' \
-d "{\"erp_url\": \"http://localhost:9000/aiotic/orders\", \"erp_key\": \"$(grep AIOTIC_ERP_RECEIVE_KEY .env | cut -d= -f2)\"}"5. Upload an order and send it
bash
echo "fake pdf" > PO-4711.pdf
aiotic orders upload PO-4711.pdf
# uploaded → request_id 7f0c… then: 7f0c…: PROCESSED — PO-4711, 2 lines
aiotic orders send 7f0c…
# sent — ERP reference SO-1000What happened, in sequence:
Rendering diagram…
The mock did what a real tenant does: locked the order, POSTed it to your endpoint with the key, read success, stored the ERP reference.
6. See a rejection
bash
echo "x" > PO-4712-attention.pdf
aiotic orders upload PO-4712-attention.pdf # → ATTENTION (one line has no article number)
aiotic orders send <request_id>
# ERP error: Line 3 has no article number (items[2].article_number)The pipeline rejected the order before it reached the ERP, and the message is exactly what an operator would see in the AIOTIC app. Change service.py to use DataApiAdapter (a SQLite demo ERP with only tables) and you will see why that matters:
python
from aiotic.service import build_app
from aiotic.erp.data_api import DataApiAdapter, sqlite_demo
app = build_app(erp=DataApiAdapter(sqlite_demo("erp-demo.db")))Where to go next
- Understand the contract you just implemented: The ERP receive endpoint
- Replace the demo ERP: ERP adapters
- Feed AIOTIC your real customers and products: Initial load → Event-driven sync
- Go to production: Onboarding checklist