How the VeraCore sync works
VeraCore is a warehouse management system your 3PL runs. SKU.io is where your catalogue, purchase orders, and sales orders live. The integration is the wire between them, and understanding which side owns what explains almost every behaviour on the other pages.
| Thing | Who owns it | Which way it moves |
|---|---|---|
| The Offer catalogue | VeraCore | In, always. SKU.io mirrors it and never edits it. |
| Stock in the 3PL's building | VeraCore | In, always. SKU.io mirrors balances and never writes them back. |
| Products | SKU.io | Out, on request. You push SKUs so VeraCore has something to receive against. |
| Sales orders | SKU.io | Out, automatically. SKU.io submits fulfillment requests. |
| Tracking and freight | VeraCore | In, on a schedule. |
| Purchase orders / arrivals | SKU.io | Out. You announce what is coming so the dock expects it. |
The one-line version: VeraCore owns the building, SKU.io owns the paperwork.
Nothing is pushed — everything is polled
VeraCore publishes no webhooks. There is no callback URL to configure, and nothing arrives because VeraCore decided to tell you. Every inbound piece of data exists because a scheduled job in SKU.io went and asked for it.
That single fact explains the shape of the whole integration:
- Latency is the schedule. A shipment that left the warehouse at 09:05 appears in SKU.io on the next tracking run, not at 09:05. See Scheduled syncs and commands for the timetable.
- "Nothing is happening" is almost always a gate, not a failure. If a job is disabled, paused, or never scheduled, no data moves and nothing errors — because nothing tried.
- A missed run has real cost. There is no queue at VeraCore's end holding your updates until you reconnect. A missed poll simply means the data waits for the next one.
Connecting: one login, sometimes two
Authentication is a bearer token. SKU.io posts your Server Name, System ID, Username, and Password to VeraCore's Login endpoint, gets a token back, and stores it on the connection with its expiry. Subsequent calls reuse that token until it is within five minutes of expiring, at which point it is renewed. You never see this happen.
There is an optional second login: the WMS credentials. A VeraCore web service user is bound to a single system, and warehouse-level product detail — barcodes in particular — lives behind a different one. When you supply WMS credentials, SKU.io caches a second token alongside the first and uses it only for those calls. Leave them blank and the barcode step is skipped, never failed. See How offers are matched to products.
Why the integration talks to several different APIs
VeraCore is old enough to have accumulated layers, and SKU.io uses all of them:
| Surface | Used for |
|---|---|
The OMS service (/pmomsws/oms.asmx) | Orders, offers, inventory, expected arrivals |
The public REST API (/VeraCore/Public.Api/api/…) | Login, package/tracking detail, orders |
| The reports API | Dynamic Reporting — the tracking pipeline |
| The order-adjustment service | Editing an order already at the warehouse |
This is invisible in normal use, but it is why some fields are shaped differently from others and why a credential problem can break one tab while another keeps working.
Rate limiting
VeraCore documents a ceiling of ten requests per second. SKU.io paces itself at eight, deliberately leaving headroom so that two of your own jobs running at once — say an inventory mirror and an order sync — cannot together trip the limit. Large syncs are therefore steady rather than fast, and that is on purpose.
The five pipelines
1. Catalogue in
The product sync pulls the Offer catalogue and mirrors it onto the Products tab, then runs the match ladder over anything unmapped. Offers are read-only in SKU.io — you cannot rename or delete one, only decide which SKU.io product sits behind it.
2. Inventory in
A daily mirror walks every Offer, records balances per facility, and writes a ledger row for anything that changed since the previous snapshot. Balances are never written back. See The inventory model.
3. Orders out
When a sales order is ready and Enable Fulfillment is on, SKU.io submits it to VeraCore as an order to pick and ship.
Submission is idempotent by lookup: before creating anything, SKU.io asks VeraCore whether an order with that id or reference already exists, and if it does, adopts the existing order rather than creating a second one. A retry after a timeout therefore cannot double-ship — a genuinely useful property when the network is the thing that failed.
4. Tracking in
The most important pipeline, and the one with the most moving parts — see below.
5. Receiving out
Approved purchase orders are announced to the warehouse as Expected Arrivals so the dock knows what is coming. See Receiving and expected arrivals.
Tracking: how a shipment actually materialises
This is the pipeline worth understanding in detail, because a SKU.io shipment does not exist until tracking comes back. Until then you have a fulfillment order the warehouse is working on, and nothing else. Stock is not deducted, the customer is not notified, and the sales order does not close.
VeraCore has no "give me tracking" endpoint. Instead it has Dynamic Reporting: your 3PL configures a report template on their side, and SKU.io asks for it by name.
One cycle looks like this:
- Submit. SKU.io asks VeraCore to run the report for a date window. VeraCore returns a task id, and SKU.io records a Report Task row.
- Poll inline. SKU.io waits ten seconds and asks whether the report is ready, up to twelve times — about two minutes. Most reports finish here.
- Hand off to the schedule. If it is still not ready, the task is left at Polling and the next hourly run picks it up. A task that is still not ready after twenty polls is marked Failed and a fresh report is submitted immediately.
- Fetch and process. Once VeraCore says
Done, SKU.io downloads the rows, matches them to VeraCore orders it already knows about, records the shipment against the fulfillment order, and marks the task Processed with the number of rows matched.
A new report is only submitted when there is no task still outstanding. That is why the Report Tasks tab usually shows a tidy sequence rather than a pile — and why a task stuck at Polling blocks new ones until it exhausts its twenty attempts.
The date window, and why it is short
The report window ends today. It starts one day before the end of the last processed report — a deliberate one-day overlap, so orders that shipped later on a day already covered are not missed. On a first run, it looks back three days. Whatever the arithmetic produces, the window is capped at seven days.
The cap exists because VeraCore's Dynamic Report API returns at most about 890 rows. A wide window does not fetch more history — it just lets old shipments crowd out today's, which is the failure mode that actually hurts. A narrow, overlapping window is more reliable than a wide one.
The overlap is also why Superseded report tasks are normal: consecutive reports genuinely do cover some of the same days.
The self-heal sweep
Every processing pass, after the fresh rows are handled, SKU.io re-attempts any order whose tracking payload was saved by an earlier run but which never produced a shipment. This exists because of a real incident: a single bad order used to abort the whole batch, and the already-saved rows then fell out of the "needs tracking" queries permanently — stranding twenty-one orders indefinitely.
Now each order is handled in isolation, and the sweep runs on every poll even when zero new rows matched. The practical effect: a transient failure heals itself on the next hourly run without anyone noticing.
What gates what
Each pipeline is behind its own switch, and everything is behind the schedule:
Sync schedule (Active / Paused)
└─ Capability switch (Tracking / Inventory / Products in, Orders / Products out)
└─ Feature toggle (Enable Fulfillment, Enable Inventory Sync, Dynamic Report Tracking)
└─ Credentials
A job checks all of them in that order and quietly does nothing if any is closed. When data is not moving, walk down that list — it is nearly always one of the four. The full mapping is in Scheduled syncs and commands, and the diagnosis order is in Troubleshooting.