Tote developers
All guides

Integrations

Sync agent

The Windows program that keeps a store's prices and stock in step with its own system — how it authenticates, syncs, reports in and updates itself.

Stores that run their own point-of-sale or ERP use Tote's sync agent, a Windows program installed in the shop. It reads prices and stock from the store's system and pushes them to Tote, so the store never edits inventory by hand.

sequenceDiagram
    participant ERP as Store system
    participant Agent as Sync agent
    participant API as Tote API

    loop every sync run
        Agent->>ERP: read products
        Agent->>API: POST stores/products/sync<br/>X-Agent-Version: 1.4.0
        API-->>Agent: summary + per-line results
    end
    loop periodically
        Agent->>API: POST stores/agent/heartbeat
        Agent->>API: GET init/agent-update
        API-->>Agent: release to install, if any
    end

Authentication#

The agent logs in as the store's owner through merchant login and sends the token like the merchant app. Staff accounts cannot sync (403).

Syncing#

The agent calls POST stores/products/sync. Matching by barcode, what is updated and what is left alone are described in Store catalog & inventory.

Send the running version in an X-Agent-Version header on every sync. It keeps Tote's view of the fleet current even when heartbeats fail, and never changes the sync result.

Heartbeat#

POST stores/agent/heartbeat tells Tote the agent is alive and how its updates are going:

Field
store_id, version required
update_status optional, the agent's own update state, shown to Tote's team as sent (up to 32 characters)
update_error optional, the error text when an update failed
target_version optional, the version being installed

The response echoes what Tote has recorded: reported_version, last_seen_at, the store's update channel and any pinned_version.

Updating itself#

GET init/agent-update answers which build a store should run. It needs no token, so an agent whose login expired can still fetch a fix.

GET /api/v1/init/agent-update?store_id=7&version=1.4.0
{
  "status": "success",
  "data": {
    "resolved_by": "channel:stable",
    "update_available": true,
    "release": {
      "version": "1.5.0",
      "file_url": "https://…/agent-releases/v1.5.0/crystal-sync.exe",
      "file_size": 31457280,
      "sha256": "9f2c…",
      "signature": "…",
      "manifest": "…",
      "release_notes": "…"
    }
  }
}
  • Which build: a version pinned for this store wins; otherwise the build its channel (stable or beta) points at; otherwise none (release: null). Tote controls both in the dashboard, which is how a release is rolled out to a few stores first.
  • Verify before installing. Check the download against sha256 and file_size, and verify the ed25519 signature over manifest — byte for byte, trailing newline included — with the public key built into the agent. Never install a file that fails either check.
  • The response may be cached for 5 minutes, and the endpoint allows 60 calls a minute, so poll every few minutes at most.
  • An unknown store_id gets the stable answer; the endpoint never reveals whether a store exists.

Publishing a new build is done by Tote's release pipeline (POST agent-releases, with its own X-Release-Token), not by the agent.