End-to-end Seller API walkthrough with one consistent scenario:
Example#
curl -s -X GET "https://api.avrix.io/api/seller/v1/catalog/snapshot" \
-H "Authorization: Bearer $AVRIX_API_KEY"curl -s -X GET "https://api.avrix.io/api/seller/v1/allocations" \
-H "Authorization: Bearer $AVRIX_API_KEY"| Field | Value |
|---|---|
| API key | avrix_sk_sbx_your_key_here |
| SKU | SANDBOX-ALWAYS-001 |
orderReference | store-order-10432 |
| Country | US |
| Currency | USD |
| Base URL | https://api.avrix.io |
Replace the key placeholder with a sandbox secret from the Console. All paths are under /api/seller/v1.
Golden path in one diagram#
The call sequence below is the same golden path as the sequence diagram on
Overview: sync catalog + allocations → preview (canFulfill) →
charge at your PSP → POST /orders with a stable Idempotency-Key → persist keys from the HTTP
response → webhooks + reconcile. Use that diagram for the picture; this page is the worked sandbox
example.
For region-locked SKUs, fail before payment: GET /availability with the buyer country at product-page time (hide the buy button) → preview with the real buyer IP at cart → reserve or hold → then charge and commit. Geo failure at commit should be rare. See Territory enforcement.
1. Authenticate#
curl -s -X GET "https://api.avrix.io/api/seller/v1/whoami" \
-H "Authorization: Bearer $AVRIX_API_KEY"Confirm environment is sandbox, required scopes are present, and read capabilities (for example checkoutHoldEnabled) and integrationReadiness.
2. Catalog sync#
Snapshot (or paginated products) plus allocations — then merge to the sellable set:
curl -s "https://api.avrix.io/api/seller/v1/catalog/snapshot" \
-H "Authorization: Bearer avrix_sk_sbx_your_key_here"
curl -s "https://api.avrix.io/api/seller/v1/allocations" \
-H "Authorization: Bearer avrix_sk_sbx_your_key_here"
Keep only SKUs that appear in catalog and have sellable: true on allocations. Persist SANDBOX-ALWAYS-001 when present.
Optional delta loop:
curl -s "https://api.avrix.io/api/seller/v1/catalog/changes?since=2026-08-01T00:00:00.000Z" \
-H "Authorization: Bearer avrix_sk_sbx_your_key_here"
3. Availability#
curl -s -X GET "https://api.avrix.io/api/seller/v1/availability?skuCode=SANDBOX-ALWAYS-001&quantity=1&country=US" \
-H "Authorization: Bearer $AVRIX_API_KEY"Use this for commit-time accuracy. List expand fields are advisory.
4. Preview#
curl -s -X POST "https://api.avrix.io/api/seller/v1/orders/preview" \
-H "Authorization: Bearer $AVRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"skuCode": "SANDBOX-ALWAYS-001",
"quantity": 1,
"countryCode": "NL",
"orderReference": "store-order-10432",
"integrationOrderContext": {
"schemaVersion": 1,
"salesCountryCode": "NL",
"currencyCode": "EUR",
"salesPriceGrossMinor": 7999,
"priceIncludesTax": true,
"salesTaxRatePercent": 21,
"salesChannel": "web",
"salesTaxAmountMinor": 1388
}
}'Gate: proceed only when canFulfill is true. Store unitPriceCents (example below uses 5999 for SANDBOX-ALWAYS-001).
5. Charge at your PSP#
Create and confirm the payment at your PSP for the retail amount (example retail gross 2999 USD cents). Keep the PSP payment id for paymentProcessorReference.
Avrix is not in this transaction.
6. Create the order#
curl -s -X POST "https://api.avrix.io/api/seller/v1/orders" \
-H "Authorization: Bearer $AVRIX_API_KEY" \
-H "Idempotency-Key: store-order-10432" \
-H "Content-Type: application/json" \
-d '{
"skuCode": "SANDBOX-ALWAYS-001",
"quantity": 1,
"orderReference": "store-order-10432",
"expectedUnitPriceCents": 5999,
"countryCode": "NL",
"deliveryMode": "key",
"integrationOrderContext": {
"schemaVersion": 1,
"salesCountryCode": "NL",
"currencyCode": "EUR",
"salesPriceGrossMinor": 7999,
"priceIncludesTax": true,
"salesTaxRatePercent": 21,
"salesChannel": "web",
"salesTaxAmountMinor": 1388,
"paymentProcessorReference": "pay_3QxK2mB9",
"checkoutSessionId": "cs_sandbox_10432",
"consumerIp": "198.51.100.42"
}
}'Persist data.keys[] (with matching keyIds[]) before responding to the buyer.
7. Webhook#
Register (once) and handle order.fulfilled:
curl -s -X POST "https://api.avrix.io/api/seller/v1/webhooks" \
-H "Authorization: Bearer $AVRIX_API_KEY" \
-H "Idempotency-Key: webhook-create-1" \
-H "Content-Type: application/json" \
-d '{
"url": "https://store.example.com/avrix/webhooks",
"events": [
"order.fulfilled",
"order.failed",
"allocation.depleted"
]
}'Verify X-Avrix-Signature. Dedupe on eventId. Expect no key plaintext in the payload.
8. Reconcile#
curl -s -X GET "https://api.avrix.io/api/seller/v1/orders?orderReference=store-order-10432" \
-H "Authorization: Bearer $AVRIX_API_KEY"Compare aggregates to your OMS. Schedule this even when webhooks succeed.
Failure paths#
Out of stock after charge#
POST /orders → 409 NO_AVAILABLE_KEYS.
Action: Refund the buyer at your PSP. Do not retry with a new idempotency key hoping for stock.
Price changed#
422 CATALOG_PRICE_MISMATCH or WHOLESALE_PRICE_MISMATCH.
Action: Re-preview, decide whether to re-price or cancel the retail charge, then submit a corrected order (new payment / new idempotency key if the prior attempt never committed).
Duplicate request (same key, same body)#
200 with the original response (may include Idempotency-Replayed: true).
Action: Treat as success; do not pull again.
Duplicate request (same key, different body)#
409 IDEMPOTENCY_KEY_MISMATCH with details.requestBodyHash.
Action: Fix the client. Do not force a new key against the same payment.
Timeout after submit#
No HTTP response after POST /orders.
Action: Retry with the same Idempotency-Key and body. If still unclear, GET /orders?orderReference=store-order-10432. Never open a second order for the same charge.
Duplicate webhook#
Same logical fulfilment delivered twice with different or repeated attempts.
Action: Dedupe on eventId. Side effects must be idempotent.
Unauthorized SKU#
404 / contract errors when the SKU is not shared or not sellable to you.
Action: Re-sync catalog + allocations. Do not hard-code SKUs outside your sellable set.