API Docs

REST API for AI agents and developers

Base URL: https://veruno.cz/api/v1
Discovery: GET /api/v1/capabilities
Auth: not required for read operations

Discovery Endpoints

GET /api/v1/capabilities

Returns API capabilities, available features, tenant list with per-tenant links, and a complete list of all API endpoints with methods, paths, auth requirements, and descriptions. This is the primary entry point for AI agents.

GET /api/v1/health

Health check endpoint. Returns API status and version.

GET /api/v1/tenants

List all available tenants (merchants/brands).

Tenant-Scoped Endpoints

All product data is scoped to a tenant. Replace {tenant} with tenant code (e.g., macooin).

Tenant Profile

GET /api/v1/{tenant}/profile

Public tenant profile — contact info, billing details, bank accounts.

Response:

{
  "code": "myshop",
  "name": "My Shop",
  "url": "https://myshop.com",
  "email": "[email protected]",
  "phone": "+420 123 456 789",
  "billing": {
    "company": "My Company s.r.o.",
    "street": "Hlavní 123",
    "city": "Praha",
    "zip": "110 00",
    "country": "Česká republika",
    "ic": "12345678",
    "dic": "CZ12345678"
  },
  "bank_accounts": [
    {
      "account_name": "My Company s.r.o.",
      "bank_name": "Fio banka",
      "currency": "CZK",
      "account_number": "2600123456/2010",
      "iban": "",
      "swift": "",
      "note": "Hlavní účet"
    },
    {
      "account_name": "My Company s.r.o.",
      "bank_name": "Raiffeisenbank",
      "currency": "EUR",
      "account_number": "",
      "iban": "CZ6555000000001234567890",
      "swift": "RZBCCZPP",
      "note": ""
    }
  ]
}

Products

GET /api/v1/{tenant}/products

List all products. Supports filtering and pagination.

Query params: category, limit, offset, include

GET /api/v1/{tenant}/products/{sku}

Get single product by SKU or ID.

Include: ?include=provenance,documents,media

Categories

GET /api/v1/{tenant}/categories

List product categories with hierarchy.

Sources & Provenance

GET /api/v1/{tenant}/sources

List material sources with origin and lifecycle information.

Authors

GET /api/v1/{tenant}/authors

List authors/creators with profiles and works.

GET /api/v1/{tenant}/authors/{slug}

Get author detail by slug.

Documents & Certificates

GET /api/v1/{tenant}/documents

List certificates and documents.

Verification

GET /api/v1/{tenant}/verify

Verify product authenticity using coin code and hash.

Query params: code, hash

Bulk Catalog (Wholesale)

For tenants with wholesale catalogs enabled:

GET /api/v1/{tenant}/bulk

Complete wholesale catalog with categories and products (public, no auth).

GET /api/v1/{tenant}/bulk/products

Paginated flat product list with stock quantities. Requires Bearer token.

Query params: page, limit (max 100), search, stock_status (in_stock|low_stock|out_of_stock), sort (name|stock_qty|price|updated), stock_qty_min, stock_qty_max

Numeric values (attributes, weight) are formatted without trailing zeros: 1.0000 → 1, 2.5000 → 2.5

Response:

{
  "data": [
    {
      "id": 4217,
      "sku": "ABC",
      "name": "Product Name",
      "price": 29.0,
      "stock_status": "in_stock",
      "stock_qty": 50,
      "category_name": "Category",
      "image_url": "https://..."
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 646,
    "pages": 33
  }
}
GET /api/v1/{tenant}/bulk/products/{id}

Single product detail with attributes. Requires Bearer token.

GET /api/v1/{tenant}/bulk/attributes

Attribute definitions for the catalog.

Pohoda (Stock Import)

For tenants with Pohoda module enabled. Import stock cards from Stormware Pohoda, manage SKU mappings, and compare inventory with the shop catalog.

All Pohoda endpoints require Bearer token authentication. Stock data (purchasing prices, quantities) is sensitive — never expose without auth.

Stock Import

POST /api/v1/{tenant}/pohoda/import

Upload Pohoda XML export and import stock cards. Accepts multipart file upload or raw XML body. Windows-1250 encoding is converted automatically.

Auth: Authorization: Bearer {token}

File upload:

curl -X POST -H "Authorization: Bearer TOKEN" \
  -F "[email protected]" \
  "https://veruno.cz/api/v1/{tenant}/pohoda/import"

Raw XML body:

curl -X POST -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/xml" \
  --data-binary @Zasoby.xml \
  "https://veruno.cz/api/v1/{tenant}/pohoda/import"

Response:

{
  "success": true,
  "import": {
    "id": 1,
    "total": 1066,
    "inserted": 1063,
    "updated": 3,
    "skipped": 0,
    "errors": 0
  }
}

Stock Data

GET /api/v1/{tenant}/pohoda/stock

List imported stock cards with pagination and filters.

Auth: Authorization: Bearer {token}

Query params: search, storage, is_internet (0|1), archived (0|1|all, default: 0), page, per_page (max 200)

Response:

{
  "items": [
    {
      "id": 1,
      "pohoda_code": "ABC123",
      "name": "Product Name",
      "unit": "ks",
      "storage_code": "SKLAD01",
      "count": "150.000",
      "selling_price": "560.00",
      "is_internet": 1,
      "is_archived": 0
    }
  ],
  "total": 1063,
  "page": 1,
  "per_page": 50,
  "pages": 22
}
GET /api/v1/{tenant}/pohoda/stock/{id}

Single stock item detail including price levels.

Auth: Authorization: Bearer {token}

POST /api/v1/{tenant}/pohoda/stock/{id}/archive

Toggle or set archived status. Archived items are excluded from diff comparison and hidden by default in stock list.

Auth: Authorization: Bearer {token}

Body (optional):

{"archived": true}

If body is empty, toggles the current state.

Import History

GET /api/v1/{tenant}/pohoda/imports

List import history with status and counters.

Auth: Authorization: Bearer {token}

Query params: limit (max 100, default: 20)

SKU Mappings

Map Pohoda stock codes to shop SKUs. Used for diff comparison when codes don't match directly.

GET /api/v1/{tenant}/pohoda/mappings

List all SKU mappings.

Auth: Authorization: Bearer {token}

POST /api/v1/{tenant}/pohoda/mappings

Create a new mapping.

Auth: Authorization: Bearer {token}

Body:

{
  "pohoda_code": "ABC123",
  "shop_sku": "SKU-001",
  "shop_source": "bulk",
  "multiplier": 1.0,
  "note": "Optional note"
}
PUT /api/v1/{tenant}/pohoda/mappings/{id}

Update an existing mapping.

Auth: Authorization: Bearer {token}

DELETE /api/v1/{tenant}/pohoda/mappings/{id}

Delete a mapping.

Auth: Authorization: Bearer {token}

Diff (Comparison)

GET /api/v1/{tenant}/pohoda/diff

Compare Pohoda stock with Bulk product catalog. Returns matched items (with and without differences), unmatched Pohoda items, and unmatched shop products. Archived items are excluded.

Auth: Authorization: Bearer {token}

Response:

{
  "matched": [
    {
      "pohoda_code": "ABC123",
      "bulk_sku": "SKU-001",
      "pohoda_name": "Product in Pohoda",
      "bulk_name": "Product in Shop",
      "diffs": [
        {"field": "stock", "pohoda": 150.0, "bulk": 120.0},
        {"field": "price", "pohoda": 560.0, "bulk": 590.0}
      ]
    }
  ],
  "unmatched_pohoda": [
    {"pohoda_code": "XYZ", "name": "Only in Pohoda", "count": "50.000"}
  ],
  "unmatched_bulk": [
    {"sku": "NEW-01", "name": "Only in Shop", "price": "299.00"}
  ]
}

Pohoda Order Export (XML)

GET /api/v1/{tenant}/pohoda/export-orders?ids=1,2,3

Export selected orders as Pohoda XML (receivedOrder dataPack, Windows-1250 encoding). Download the XML file and import it into Stormware Pohoda.

Auth: Authorization: Bearer {token}

Query params: ids (comma-separated order IDs, max 500)

Prerequisites: Pohoda IČO must be configured in Objednávky → Nastavení → Export do Pohody.

Response: XML file (Content-Type: application/xml; charset=windows-1250)

curl -H "Authorization: Bearer TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/pohoda/export-orders?ids=1,2,3" \
  -o orders.xml

Orders API

For tenants with orders module enabled. Requires Bearer token authentication.

Generate your API token in Profil projektu → API token.

⚠️ Important: Authorization Header Format
The Authorization header must include the word Bearer followed by your token:

Authorization: Bearer YOUR_TOKEN_HERE
Do NOT send just the token without "Bearer " prefix – you will get a 401 Unauthorized error.

Order Sync

POST /api/v1/{tenant}/orders/sync

Sync orders from WooCommerce. Called by WooCommerce Connector plugin or manually.

Auth: Authorization: Bearer {token}

Body:

{
  "shop_url": "https://your-shop.com",
  "orders": [
    {
      "id": 123,
      "order_number": "12345",
      "status": "processing",
      "customer_name": "Jan Novák",
      "customer_email": "[email protected]",
      ...
    }
  ]
}

Order List & Detail

GET /api/v1/{tenant}/orders

List orders synced from WooCommerce.

Query params: status, per_page, page

Auth: Authorization: Bearer {token}

GET /api/v1/{tenant}/orders/{id}

Get single order detail with items, addresses, and tracking info.

Order statuses: processing, on-hold, pending, shipped, completed, cancelled, refunded, failed, trash

GET /api/v1/{tenant}/orders/carriers

List active shipping carriers with tracking URL patterns. No auth required.

Tracking Management

POST /api/v1/{tenant}/orders/{id}/tracking

Add tracking number to a single order.

Body:

{
  "carrier": "DPD",
  "tracking_number": "0123456789",
  "package_index": 1
}
POST /api/v1/{tenant}/orders/tracking

Bulk import tracking numbers for multiple orders.

Body:

{
  "tracking": [
    {"order_number": "12345", "carrier": "DPD", "tracking_number": "0123456789"},
    {"order_number": "12346", "carrier": "GLS", "tracking_number": "9876543210"}
  ]
}
DELETE /api/v1/{tenant}/orders/{id}/tracking?tracking_id=X

Remove tracking from order.

Public Tracking Lookup

Customers can track their order without authentication using order number + postal code verification.

GET /api/v1/tracking/{order_number}?postcode={postcode}

Public tracking lookup. No authentication required.

Query params: postcode (required) - shipping postal code for verification

Response:

{
  "order_number": "12345",
  "status": "shipped",
  "tracking": [
    {
      "carrier": "DPD",
      "tracking_number": "0123456789",
      "tracking_url": "https://...",
      "status": "delivered",
      "status_label": "Doručeno",
      "shipped_at": "2026-02-25"
    }
  ]
}

Tracking Status API

GET /api/v1/{tenant}/orders/{order_number}/tracking/status

Get tracking status for all packages in an order. For AI agents to check delivery status and trigger notifications.

Auth: Authorization: Bearer {token}

Query params: refresh=1 - force status refresh from carrier API (rate limited)

Response:

{
  "order_number": "12345",
  "order_status": "completed",
  "all_delivered": true,
  "tracking_count": 1,
  "tracking": [
    {
      "id": 1,
      "carrier": "DPD",
      "tracking_number": "0123456789",
      "tracking_url": "https://...",
      "status": "delivered",
      "status_label": "Doručeno",
      "status_detail": "The parcel was delivered 24.02.2026, 08:35.",
      "status_checked_at": "2026-02-27T09:42:53Z",
      "shipped_at": "2026-02-26"
    }
  ],
  "refreshed": 1
}

Use cases for AI agents:

Tracking Status Values

Veruno automatically checks delivery status for DPD and GLS packages every 15 minutes until delivered.

StatusLabel (CZ)Description
acceptedPřijatoData received by carrier
in_transitNa cestěPackage in transit
out_for_deliveryDoručuje seOut for delivery
deliveredDoručenoSuccessfully delivered
at_pickup_pointNa výdejním místěWaiting at pickup point
not_deliveredNedoručenoDelivery failed
returnedVrácenoReturned to sender
Supported carriers: Automatic status checking works for DPD and GLS carriers. Manual status check is available in order detail admin page.

DPD Push Track & Trace

DPD can send real-time push notifications when parcel status changes. This eliminates the need for polling and provides instant updates.

POST /api/v1/dpd-push

Receive push tracking events from DPD. No tenant scope needed — tenant is identified by API key.

Auth: X-API-KEY: {dpd_push_api_key}

IP whitelist: Only DPD production (213.41.95.161) and pre-production (213.41.95.174) IPs are allowed.

Body: Array of parcel events:

[
  {
    "parcelNumber": "13825074964179",
    "event": {
      "statusId": "DEY",
      "eventDateTime": "2026-03-03T10:00:00Z",
      "country": "CZ",
      "city": "Praha"
    }
  }
]

Response:

{"ok": true, "processed": 1, "updated": 1}

When a push event matches a tracking number, Veruno:

Setup: Generate a DPD Push API key in Objednávky → Nastavení → Dopravci, then send the key and endpoint URL to DPD ([email protected]) for activation. Push complements cron polling — both run in parallel for maximum reliability.

Complete Examples (curl)

1. Get your API token from Bulk → Nastavení → API přístup

2. List orders:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/orders?per_page=10"

3. Get order detail:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/orders/{order_number}"

4. Get available carriers (no auth):

curl "https://veruno.cz/api/v1/{tenant}/orders/carriers"

5. Add tracking to order:

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"carrier":"DPD","tracking_number":"0123456789","package_index":1}' \
  "https://veruno.cz/api/v1/{tenant}/orders/{order_number}/tracking"

6. Delete tracking:

curl -X DELETE \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/orders/{order_number}/tracking?tracking_id={id}"

7. Public tracking lookup (no auth, for customers):

curl "https://veruno.cz/api/v1/tracking/{order_number}?postcode=12345"

8. Get tracking status (for AI agent notifications):

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/orders/{order_number}/tracking/status"

9. Force tracking status refresh:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://veruno.cz/api/v1/{tenant}/orders/{order_number}/tracking/status?refresh=1"

Response Examples

Order detail response:

{
  "order_number": "12345",
  "status": "processing",
  "customer": {
    "name": "Example Customer",
    "email": "[email protected]"
  },
  "totals": {
    "total": 1000.00,
    "currency": "CZK"
  },
  "items": [
    {
      "name": "Product Name",
      "sku": "SKU-001",
      "quantity": 2,
      "price": 450.00,
      "total": 900.00
    }
  ],
  "tracking": [
    {
      "carrier": "DPD",
      "tracking_number": "0123456789",
      "tracking_url": "https://tracking.example.com/0123456789",
      "status": "delivered",
      "status_label": "Doručeno",
      "status_checked_at": "2026-02-27T10:30:00Z"
    }
  ]
}

Add tracking response:

{
  "success": true,
  "action": "created",
  "tracking": {
    "id": 1,
    "carrier": "DPD",
    "tracking_number": "0123456789",
    "tracking_url": "https://tracking.example.com/0123456789"
  }
}

Shipping HUB

For tenants with Shipping HUB module enabled. Calculate shipping prices based on zones, methods, and pricing tiers. Supports weight-based, value-based, volume-based, and flat pricing models.

Quote and Methods are public endpoints (no authentication required) — shipping prices are not sensitive. Only /shipping/attach requires Bearer token.

Quote (Calculate Shipping)

POST /api/v1/{tenant}/shipping/quote

Calculate shipping prices for a given country and order parameters. Returns available shipping methods with calculated prices, zone info, and delivery estimates.

Auth: None (public endpoint)

Body:

{
  "country_code": "CZ",
  "weight_kg": 8,
  "value": 2000,
  "volume_m3": 0.05,
  "items_count": 1
}

Parameters:

  • country_code (required) — 2-letter ISO country code
  • weight_kg — package weight (in tenant's weight unit)
  • value — order value (for free-above-value rules)
  • volume_m3 — package volume in cubic meters
  • items_count — number of items (default: 1)

Response:

{
  "zone": {
    "id": 1,
    "name": "Domácí",
    "code": "domaci"
  },
  "delivery_days": {
    "min": 1,
    "max": 3,
    "season": false
  },
  "methods": [
    {
      "method_id": 1,
      "method_name": "DPD Private",
      "carrier_code": "DPD",
      "pricing_model": "weight",
      "price": 149.00,
      "is_free": false,
      "parcels": 1
    },
    {
      "method_id": 2,
      "method_name": "Osobní odběr",
      "carrier_code": "PICKUP",
      "pricing_model": "free",
      "price": 0,
      "is_free": true,
      "parcels": 1
    }
  ]
}

If the country is not in any zone, zone will be null and methods will be empty.

parcels indicates number of packages. When shipment weight exceeds the tier maximum, it is automatically split into multiple parcels (e.g. 50kg with 29kg tier limit → parcels: 2, price doubled).

Shipping Methods

GET /api/v1/{tenant}/shipping/methods

List all active shipping methods with their pricing tiers.

Auth: None (public endpoint)

Response:

[
  {
    "id": 1,
    "name": "DPD Private",
    "carrier_code": "DPD",
    "carrier_name": "DPD",
    "zone": {"code": "domaci", "name": "Domácí"},
    "pricing_model": "weight",
    "is_active": true,
    "tiers": [
      {"threshold_from": 0, "threshold_to": 5000, "price": 99.00, "multiplier": 1.00},
      {"threshold_from": 5000, "threshold_to": 15000, "price": 149.00, "multiplier": 1.00},
      {"threshold_from": 15000, "threshold_to": null, "price": 249.00, "multiplier": 1.00}
    ]
  }
]

Attach Method to Order

POST /api/v1/{tenant}/shipping/attach

Attach a selected shipping method and price to an order. Logs the selection in shipping quotes.

Auth: Authorization: Bearer {token}

Body:

{
  "order_ref": "12345",
  "method_id": 1,
  "price": 149.00
}

Response:

{
  "success": true,
  "order_ref": "12345",
  "method_id": 1,
  "price": 149.00
}

Complete Examples (curl)

1. Calculate shipping for CZ, 8kg package (no auth needed):

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"country_code":"CZ","weight_kg":8,"value":2000}' \
  "https://veruno.cz/api/v1/{tenant}/shipping/quote"

2. List all shipping methods (no auth needed):

curl "https://veruno.cz/api/v1/{tenant}/shipping/methods"

3. Attach method to order:

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order_ref":"12345","method_id":1,"price":149}' \
  "https://veruno.cz/api/v1/{tenant}/shipping/attach"
Pricing models: weight (by weight), value (by order value), volume (by volume), flat (fixed price), free (always free), manual (manual pricing). Rules like "free above value" are applied automatically during quote calculation.

Mobile App API

Endpoints for the Veruno mobile app (stock management, push notifications). Requires Bearer token authentication.

GET /api/v1/{tenant}/info

Tenant info for mobile app onboarding. Returns tenant name, settings, product/order counts.

POST /api/v1/{tenant}/devices

Register device for push notifications (Expo Push Service).

Body:

{
  "expo_push_token": "ExponentPushToken[xxxxxx]",
  "platform": "ios",
  "device_name": "iPhone 15",
  "notifications": {"new_order": true, "low_stock": true}
}
DELETE /api/v1/{tenant}/devices/{id}

Unregister device (soft delete).

Stock Management

PATCH /api/v1/{tenant}/products/{id}/stock

Update product stock. Supports two modes: set specific quantity or mark as always in stock (no quantity tracking). Logs change, triggers stock.updated webhook, and syncs to WooCommerce.

Mode 1 – Set quantity:

{
  "stock_quantity": 25,
  "reason": "inventory_count",
  "low_stock_threshold": 5
}

Mode 2 – Always in stock (no quantity tracking):

{
  "stock_status": "in_stock",
  "reason": "unlimited_stock"
}

Mode 2 sets stock_qty = NULL and stock_status = 'in_stock'. Product will always show as in stock without tracking inventory.

PATCH /api/v1/{tenant}/products/stock/bulk

Bulk stock update (max 100 products per request, transactional). Sends single sync notification to WooCommerce.

Body:

{
  "updates": [
    {"product_id": 1, "stock_quantity": 50},
    {"product_id": 2, "stock_quantity": 0}
  ]
}

Bidirectional Stock Sync

Stock updates via API are automatically synced to WooCommerce:

  1. Stock change is pushed to WooCommerce via /wp-json/veruno/v1/sync-notify
  2. WooCommerce updates its stock (source of truth for orders)
  3. Next cron sync pulls updated stock back from WooCommerce (including changes from orders)
Note: WooCommerce is the source of truth for stock. Cron sync always updates Veruno stock from WooCommerce. Changes made via Veruno API are immediately pushed to WooCommerce to keep both systems in sync.

Webhooks

Push notifications for AI agents. Veruno sends HTTP POST to your endpoint when events occur.

Setup: Configure webhooks in Bulk → Nastavení → Webhooks. Each webhook has a unique secret for signature verification.

Events

EventDescriptionTriggered When
order.createdNew orderOrder synced from WooCommerce
order.updatedOrder status changedStatus changes (e.g., processing → shipped)
tracking.addedTracking addedTracking number added via API or admin
tracking.deletedTracking removedTracking number deleted
stock.updatedStock changedStock quantity updated via app or API
tracking.status_updatedTracking status changedParcel status updated via DPD push or cron

Payload Format

{
  "event": "tracking.added",
  "tenant": "{tenant}",
  "timestamp": "2026-01-15T10:30:00Z",
  "data": {
    "order_number": "12345",
    "tracking_id": 1,
    "carrier": "DPD",
    "tracking_number": "0123456789",
    "tracking_url": "https://tracking.example.com/0123456789",
    "package_index": 1
  }
}

Security Headers

HeaderDescription
X-Veruno-EventEvent type (e.g., tracking.added)
X-Veruno-SignatureHMAC-SHA256 signature: sha256={hash}
X-Veruno-TimestampISO 8601 timestamp

Signature Verification

Verify the webhook authenticity using HMAC-SHA256:

# PHP
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_VERUNO_SIGNATURE'];
$expected = 'sha256=' . hash_hmac('sha256', $payload, $your_webhook_secret);
if (hash_equals($expected, $signature)) {
    // Valid webhook
}

# Python
import hmac, hashlib
expected = 'sha256=' + hmac.new(
    webhook_secret.encode(),
    request.data,
    hashlib.sha256
).hexdigest()
if hmac.compare_digest(expected, request.headers['X-Veruno-Signature']):
    # Valid webhook

Retry Policy

If your endpoint returns non-2xx status:

Tracking HUB

Group endpoint for importing tracking numbers across multiple tenants in a single API call. Useful when one shipping account handles orders for multiple shops.

POST /api/v1/tracking-hub/{group_code}/orders/tracking

Import tracking numbers across all tenants in the group. The system automatically matches each order number to the correct tenant.

Auth: Authorization: Bearer {group_api_key} (separate from tenant API tokens)

Body:

{
  "tracking": [
    {"order_number": "300123", "carrier": "DPD", "tracking_number": "01234567890"},
    {"order_number": "600456", "carrier": "GLS", "tracking_number": "09876543210"}
  ]
}

Response:

{
  "success": true,
  "group": "my-group",
  "tracking_imported": 1,
  "skipped": 0,
  "errors": [
    {"order_number": "600456", "reason": "Order not found in any tenant"}
  ],
  "detail": [
    {"order_number": "300123", "tenant": "inmart", "status": "imported"},
    {"order_number": "600456", "tenant": null, "status": "error"}
  ]
}
Setup: Create groups, assign tenants, and generate API keys in the admin panel (admin-only). Each group can have multiple API keys.

Status API

GET /api/v1/status

Public API status — returns real-time health of all monitored endpoints, grouped by service. No authentication required.

Response:

{
  "status": "operational",
  "groups": [
    {
      "name": "Core",
      "status": "operational",
      "endpoints": [
        {
          "name": "Health",
          "url": "/api/v1/health",
          "status": "operational",
          "response_time_ms": 45
        }
      ]
    }
  ],
  "uptime_7d": [
    {"date": "2026-03-09", "status": "operational", "checks": 96, "failures": 0}
  ]
}

Visual status page: /status

Automatic Synchronization

Veruno automatically synchronizes data with WooCommerce stores via scheduled cron jobs.

What Gets Synced Automatically

DataDirectionFrequencyDescription
OrdersWC → VerunoEvery 15 minNew and updated orders from WooCommerce
Order StockWC → VerunoEvery 15 minLightweight stock update for SKUs from new orders (plugin v2.4.0+)
ProductsWC → VerunoManual onlyFull product pull sync (excluded from auto-cron due to timeout)
Tracking StatusDPD/GLS API → VerunoEvery 15 minDelivery status updates for DPD and GLS shipments

Sync Requirements

For automatic sync to work, tenant must have configured:

Product Sync: Updates existing products by SKU match. New products are automatically imported with categories. Price and stock changes are reflected within 15 minutes.

WooCommerce Connector

WordPress plugin for bidirectional sync between WooCommerce and Veruno.

Push Sync (WooCommerce → Veruno)

POST /api/v1/{tenant}/import/woocommerce

Import products from WooCommerce. Requires API token.

Pull Sync (Veruno → WooCommerce)

Veruno can pull data directly from WooCommerce REST API:

GET {shop_url}/wp-json/veruno/v1/export

Export products from WooCommerce. Requires Bearer token.

Query params: page, per_page (max 200), status, include_variants

Orders Export (WooCommerce → Veruno)

GET {shop_url}/wp-json/veruno/v1/orders

Export orders from WooCommerce. All statuses are exported (including custom). Requires Bearer token.

Query params: page, per_page, status (default: any), created_after, modified_after

Response includes: order details, items (with subtotal, total_tax, tax_rate for Pohoda), billing/shipping addresses (with ico/dic), fees/tips, customer note.

POST {shop_url}/wp-json/veruno/v1/orders/tracking

Import tracking numbers into WooCommerce orders. Sets custom order status "Odesláno" (wc-shipped).

Stock Query (WooCommerce → Veruno) v2.4.0+

GET {shop_url}/wp-json/veruno/v1/stock

Lightweight stock query for specific SKUs. Used by Veruno cron to update bulk stock after order sync — instead of full product pull. Requires Bearer token.

Query params: skus — comma-separated SKU list (max 200)

// Response
{
  "stock": {
    "SKU-001": { "stock_qty": 25, "stock_status": "instock", "manage_stock": true },
    "SKU-002": { "stock_qty": 0, "stock_status": "outofstock", "manage_stock": true },
    "UNKNOWN": null
  },
  "count": 3
}

Stock Sync (Veruno → WooCommerce)

POST {shop_url}/wp-json/veruno/v1/sync-notify

Receive stock updates from Veruno and apply to WooCommerce products. Called automatically when stock is updated via Veruno API. Requires Bearer token.

Body:

{
  "type": "stock_updated",
  "products": [
    {"id": 1, "sku": "ABC", "stock_qty": 25, "wc_product_id": 456}
  ],
  "tenant": "inmart",
  "timestamp": "2026-03-01T14:30:00+01:00"
}

Products are matched by wc_product_id first, then by sku as fallback.

GET {shop_url}/wp-json/veruno/v1/health

Health check - returns shop info and plugin version.

Plugin Update API

GET /api/v1/plugin/update-check

Check for plugin updates. Returns latest version info.

GET /api/v1/plugin/info

Full plugin information including changelog.

Download

Latest plugin: veruno-connector.zip (v2.4.2)

Response Format

All responses are JSON with consistent structure:

{
  "meta": {
    "api_version": "2.6",
    "tenant": "macooin",
    "timestamp": "2026-02-25T12:00:00Z"
  },
  "data": { ... },
  "_links": {
    "self": "https://veruno.cz/api/v1/macooin/products",
    "next": "..."
  }
}

AI Signals

Products include AI-friendly signals for quick classification:

SignalDescription
handmadeHandcrafted product
limited_editionLimited availability
sustainableEco-friendly materials/process
certifiedHas quality certificates
traceableFull provenance available

Rate Limits

100 requests per minute per IP. Responses include headers:

Security

CORS Policy

API uses dynamic CORS based on tenant configuration:

CORS headers included in responses:

Access-Control-Allow-Origin: {matched_origin}
Access-Control-Allow-Methods: GET, POST, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-API-Key, If-None-Match, Authorization
Access-Control-Allow-Credentials: true

Authentication

Endpoint TypeAuth RequiredMethod
Public (products, categories, etc.)No-
Orders APIYesAuthorization: Bearer {api_token}
Mobile App APIYesAuthorization: Bearer {api_token}
Bulk Products (paginated)YesAuthorization: Bearer {api_token}
Pohoda APIYesAuthorization: Bearer {api_token}
WC ImportYesAuthorization: Bearer {wc_api_token}
Public TrackingNo*Postcode verification

* Public tracking requires correct postal code to prevent enumeration attacks.

Machine-Readable Discovery

For automated discovery, use:

For AI Agents: Start with /api/v1/capabilities to discover available tenants and features, then explore tenant-specific endpoints.