Rollout

A rollout plan for any integrator pushing data into FG.AI WMS through this contract. The most important section is the upsert order at onboarding — dependency violations are the dominant cause of onboarding pain, and they are entirely avoidable by sequencing correctly.

Suggested upsert order at onboarding

Run the initial load in this order. Each step depends only on prior steps.

  1. UoMsPOST /wms-ingest/v1/master/uoms?mode=bulk

  2. AddressesPOST /wms-ingest/v1/master/addresses?mode=bulk (warehouses + customers + suppliers + carriers)

  3. Locations: warehousesPOST /wms-ingest/v1/master/locations?mode=bulk (kind=WAREHOUSE)

  4. Locations: zonesPOST /wms-ingest/v1/master/locations?mode=bulk (kind=ZONE)

  5. Locations: binsPOST /wms-ingest/v1/master/locations?mode=bulk (kind=BIN)

  6. SKUsPOST /wms-ingest/v1/master/skus?mode=bulk

  7. BOMsPOST /wms-ingest/v1/master/boms?mode=bulk (only after all referenced SKUs are present)

  8. Lots / SerialsPOST /wms-ingest/v1/master/lots?mode=bulk, POST /wms-ingest/v1/master/serials?mode=bulk

  9. Inventory snapshotPOST /wms-ingest/v1/inventory/snapshot (scope=FULL per warehouse, at a clean cutover point)

  10. Documents — push only the documents still open at cutover (open POs, open receivers, open shippers, open work orders, in-transit transfer orders)

After this sequence, the FG.AI planner is ready to take over. Open documents start being planned and dispatched on the FG.AI side; the upstream continues to be the system of entry but stops planning.

Skip steps that do not apply to your operation. Most warehouses use lots or serials but not both; most do not use BOMs.

Implementation checklist

Use this as a rollout plan. Each item is independently verifiable.

  1. Map upstream natural keys to source_id for every entity class. For composite keys, pick a deterministic separator (. or :) and document the convention.

  2. Decide source_version semantics. Cheapest option: increment per row on every source-side update. Alternative: epoch milliseconds. Whichever you choose, ensure monotonicity.

  3. Build the initial-load orchestrator in the order above. Use ?mode=bulk for every step; poll /jobs/{job_id} for completion.

  4. Build the steady-state change emitter. Source-side changes to master data or documents trigger a ?mode=upsert call. Keep the same source_id and increment source_version.

  5. Build the inventory snapshotter. Full snapshot at cutover; partial snapshots periodically during the overlap period (if any).

  6. Implement the three webhook receivers. Verify HMAC over the raw body before parsing. Be idempotent on correlation_id.

  7. Build a quarantine triage UI (or surface GET /quarantine in your existing ops tool) so the data team can resolve conflicts without an FG.AI engineer in the loop.

  8. Add a mapping lookup utility so support can answer “what is FG.AI’s internal_id for our SKU X?”.

  9. Plan the cutover runbook. Freeze the upstream’s planning loop, run the initial bulk load, post the FULL inventory snapshot, switch operations to FG.AI.

  10. Verify with replay tests for every inbound and outbound endpoint. Confirm REPLAY semantics work on retries and that webhook receivers do not double-apply on at-least-once redelivery.

Joint verification before go-live

Test

What to verify

Cross-warehouse credential rejection

A credential for WH-A is rejected with 403 when posting for WH-B.

Webhook signature mismatch

A request with a wrong X-FGAI-Signature is rejected with 401.

Request replay

A second send of the same (partner_id, correlation_id) returns the original response, no re-processing.

Item replay

A second send of the same item with the same source_version returns REPLAY.

Quarantine triage

A deliberate unknown-UoM SKU upsert produces QUARANTINED. Fixing the UoM and re-upserting the SKU resolves to ACCEPTED.

Bulk job polling

A ?mode=bulk call returns 202 immediately; polling /jobs/{job_id} eventually returns COMPLETED or COMPLETED_WITH_ERRORS.

Webhook redelivery idempotency

A duplicate webhook with the same correlation_id produces no duplicate effect on the receiver.

Cutover snapshot accuracy

The full snapshot’s quantities exactly match the upstream’s known position before flipping FG.AI to authoritative.

Cutover day

Sequencing for the cutover day itself, after onboarding has been completed and verified in a non-production environment:

  1. Freeze the upstream’s planning loop. Stop releasing new work; let in-flight work settle.

  2. Drain in-flight movements. Wait for all expected open transactions to land in the upstream.

  3. Post the final FULL inventory snapshot. Use a deliberate operational pause (e.g. end of the shift) for a clean snapshot.

  4. Push all open documents as they stand at the snapshot timestamp.

  5. Switch FG.AI to authoritative. From this point, inventory writes flow through FG.AI WES → FG.AI WMS, not through this contract.

  6. Keep the upstream as the customer-visible system of entry. Continue ingesting new master and document upserts via this contract; stop pushing inventory.

  7. Monitor for 48–72 hours. Watch for unexpected quarantines or webhook redelivery failures. Roll back to upstream-authoritative if the numbers drift unacceptably.

The cutover snapshot is the single most-consequential payload — verify it twice.

Common rollout pitfalls

  • Pushing documents before master data. Documents quarantine because their SKU / location / party references resolve to nothing. Sequence per the upsert order.

  • Pushing bins before zones (or zones before warehouses). Hierarchy unresolved → quarantine. The order above prevents this.

  • Forgetting source_version. Out-of-order delivery silently overwrites newer state with older. Always send source_version if the upstream can produce one.

  • Using full-refresh for a partial change. A full-refresh of one item tombstones every other item in that collection. Use upsert for partial changes.

  • Skipping HMAC verification on webhooks. “We’re behind a VPC anyway” is not an answer — the contract requires it.

  • Re-using correlation_id across logically distinct requests. Request-level idempotency depends on the correlation_id being unique per logical action.

  • Cutover without a final FULL snapshot. FG.AI’s starting inventory position is whatever the most recent snapshot says. If you skip the final snapshot, FG.AI starts authoritative on stale data.

After cutover

The integration enters a stable steady state:

  • Master data flows on every change (low volume).

  • Documents flow on every state-relevant event (moderate volume).

  • Inventory writes flow from FG.AI to the upstream via the inventory.adjusted webhook (the upstream may choose to mirror or ignore).

  • Quarantines are rare; when they happen, the triage UI handles them without engineering involvement.

If the integration is operating cleanly, the only ongoing engineering work is reacting to upstream API changes and FG.AI minor-version upgrades.