Your connector keeps CrossUp up to date by sending each change as it happens. If your system deletes things silently, a snapshot once a day sweeps away what’s no longer there.

Your connector’s two routines

1 · Each change, as it happens

A price changed, stock came in, a product was deleted, an order was paid: your connector sends just that.

2 · Everything, once a day (optional)

Only if your system can’t report what it deletes: it sends the full catalog and whatever didn’t come is removed.
If your connector also sends the deletes, routine 1 is enough.

Routine 1: send what changed

CrossUp gives you an endpoint and your connector sends it a POST every time something changes. How your connector learns about the change depends on your system: CrossUp doesn’t need to know.
1

Something changes in your system

A price, a stock level, a new or deleted product, a new order or one that changed status.
2

Map it to CrossUp's format

Each entity carries its external_id (its id in your system) and an operation: upsert if it was created or changed, delete if it was deleted. Each one’s fields are in The canonical model.
3

Send it

A POST to /observations, with up to 500 entities. Each one comes back with its result, just like in the initial sync.
A delete carries no document. New orders, or orders that change status, go through here as order.

Routine 2 (optional): the daily snapshot

Use it only if your system can’t send the deletes. It’s the same sequence as the initial sync: you open one run per entity, send everything in pages and close it. On close, whatever of that type didn’t come is removed. Schedule it once a day, at your store’s quietest hour.
While the run is open, don’t send observations for that entity. A product that comes in through routine 1 during the run would be removed on close, and an old page could overwrite a newer change.
The daily snapshot is for the catalog, not for orders. A snapshot means “everything”: if you close an order run with today’s orders, the earlier ones are removed. After the initial sync, orders always go through routine 1.

If something fails, retry

Resending the same thing never duplicates anything, so after an outage or a timeout you can send the whole batch again.
  • With revision: an integer that only grows, like an updated_at in milliseconds. It’s applied only if it’s greater than the last one; if not, it comes back stale and overwrites nothing.
  • Without revision: CrossUp compares the content. If it’s identical to the last one, it comes back unchanged.
If your system has nothing that only grows, leave revision out.

What doesn’t validate: quarantine

An entity that doesn’t meet the contract comes back quarantined. Its reason names the field: document.quantity: required. The rest of the batch goes in. Fix that entity and resend it alone. Whatever comes back accepted belongs to CrossUp. It’s archived and reaches the catalog even if something on the other side is down. Your connector doesn’t need to retry it.

Glossary

  • Connection: your store in CrossUp. Its id is the connection_id (cn_…).
  • Observation: an entity that changed, with upsert or delete.
  • Snapshot: “here’s everything” for one entity type. When you close it, what didn’t come is removed.
  • Run: an open snapshot (snp_…). Left unclosed, it expires after 24 hours.
  • Revision: an integer that only grows and says which version is newest.
  • Quarantine: what didn’t validate; reason says why.

What you’ll see

Every change you send comes back accepted. A retry comes back unchanged or stale, and your catalog keeps the newest version.

If you don’t see it

The canonical model

Which fields each entity carries and which ones are omitted.

Connector SDK and protocol

The contract, and how to speak it in your language.