Cloud WMS · multi-warehouse, multi-client · dock to invoice LinkedIn X YouTube
EDI & API Integration Guide

RattusWMS
Integration API

Message contracts, field mappings and webhooks for two-way integration between your ERP / TMS and RattusWMS — master data, purchase & sales flows, and warehouse confirmations.

✓ REST · JSON ⚡ Queue + Webhook 🔐 API Key Auth ↻ Auto Retry
🌐
Overview
How your ERP and RattusWMS exchange data

Your ERP is the system of record for masters and documents. RattusWMS owns the physical warehouse operation. Two channels connect them:

Client → WMS · Inbound
Your ERP pushes messages
Item master, purchase orders (ASN), sales orders, transfer orders and their amendments / cancellations are POSTed to the EDI gateway and queued for processing.
WMS → Client · Outbound
RattusWMS calls your webhook
Receipt and shipment confirmations and captured item images are pushed back to your webhook endpoint as they occur.
ℹ Purchase Orders are represented in RattusWMS as ASNs, and Sales Orders as outbound Orders. This is the existing RattusWMS message vocabulary — the field mapping section shows the exact ERP ↔ WMS correspondence.
🗂️
Scope Matrix
Touch points covered by this specification
Touch PointDirectionMessageStatus
Item Master — createClient → WMSITEM_CREATEDraft
Item Master — modify (no block)Client → WMSITEM_UPDATEDraft
Purchase Order / ASN — createClient → WMSASN_CREATELive
Purchase Order / ASN — amendClient → WMSASN_AMENDDraft
Purchase Order / ASN — cancelClient → WMSASN_CANCELLive
Sales Order — createClient → WMSORDER_CREATEDraft
Sales Order — amendClient → WMSORDER_AMENDDraft
Sales Order — cancelClient → WMSORDER_CANCELDraft
Transfer Order — createClient → WMSTRANSFER_CREATEDraft
Warehouse ReceivingWMS → ClientRECEIPT_CONFIRMEDLive
Warehouse ShipmentWMS → ClientSHIP_CONFIRMEDDraft
Item image sync (→ client DMS)WMS → ClientITEM_IMAGE_SYNCDraft
⚠ Live = contract already in production with other RattusWMS EDI clients. Draft = newer message type, confirmed per client during onboarding. Transfer Order support is planned; its touch-point scenarios are still being finalised, so the payload shown is a starting proposal.
🔐
Authentication
API key inbound, shared secret outbound

Client → WMS

Every request to the EDI gateway carries an API key issued by the RattusWMS team. The key is scoped to your client code and warehouse.

HTTP Header
X-Kiban-API-Key: your-api-key-here

WMS → Client

Outbound webhook calls include the event type in a header. A shared HMAC secret for payload signing can be enabled on request.

HTTP Headers
Content-Type: application/json
X-Kiban-Event: RECEIPT_CONFIRMED
⚠ Keep the API key confidential — never place it in client-side code or public repositories. Contact RattusWMS immediately if a key may be compromised.
⚡
How it Works
Async queue-based processing

Inbound messages are queued on receipt and processed within 5 minutes. Poll the status endpoint for the outcome, or rely on the confirmation webhooks for warehouse events.

the ERP
→
POST /edi-gateway
→
Queue (PENDING)
→
RattusWMS
→
PROCESSED
ℹ Processing runs on a 5-minute cycle. For time-critical checks, poll the status endpoint after submitting.
📤
Submit & Status
The two inbound endpoints every message uses
POST /functions/v1/edi-gateway Queue a message
FieldTypeDescription
message_typestringOne of the types in the scope matrix required
client_referencestringERP document no. — PO No., SO No., Item No. required
warehouse_codestringTarget warehouse. Defaults to the assigned warehouse optional
payloadobjectMessage-specific body (see each type) required
GET /functions/v1/edi-status Query message status
ParamDescription
referenceYour client_reference value optional
idMessage id returned from submit optional
statusPENDING / PROCESSED / FAILED optional
limitMax results (default 20, max 100) optional
🔧 Base URL — to confirm at onboarding. Examples in this document use https://webui.rattusapps.com/functions/v1/…. The RattusWMS team will confirm the final gateway host and the ERP webhook URL before development testing begins.

Response — 201 Created

JSON
{
  "success":   true,
  "message":   "Message queued successfully",
  "id":        "e256bc06-b87e-4d3d-a5a5-7e98f0dc735d",
  "status":    "PENDING",
  "reference": "PO-12345",
  "queued_at": "2026-07-14T10:20:43Z"
}
🏷️
Item Create
New item master with UoMs, barcodes, dimensions
Client → WMS
JSON Payload
{
  "message_type":     "ITEM_CREATE",
  "client_reference": "SKU001",
  "payload": {
    "item_no":           "SKU001",
    "description":       "Widget Blue 500ml",
    "search_desc":       "WIDGET BLUE",
    "base_uom":          "PCS",
    "item_category":     "FG",
    "tracking":          "LOT",            // NONE | LOT | SERIAL | LOT_SERIAL
    "hs_code":           "3926.90",
    "country_of_origin": "AE",             // ISO country code
    "shelf_life_days":   365,              // with mfg date, derives expiry
    "volume_cbm":        0.0012,
    "weights": [
      { "uom": "PCS", "weight_kg": 0.45 },
      { "uom": "CTN", "weight_kg": 10.80 }
    ],
    "replenishment_min_qty": 20,           // base UoM
    "replenishment_max_qty": 200,          // base UoM
    "lottables": {
      "batch_applicable":       "Y",   // capture Batch / Lot No. at receipt
      "mfg_date_applicable":    "Y",   // capture Manufacturing Date
      "expiry_date_applicable": "Y"    // capture Expiry Date
    },
    "uoms": [
      { "uom": "PCS", "qty_per_base": 1,  "barcode": "8901234500017" },
      { "uom": "CTN", "qty_per_base": 24, "barcode": "8901234500024" }
    ],
    "variants": [
      { "variant_code": "BLUE", "description": "Widget Blue 500ml" },
      { "variant_code": "RED",  "description": "Widget Red 500ml" }
    ]
  }
}
FieldTypeDescription
item_nostringERP Item No. — becomes WMS product_code required
base_uomstringBase unit of measure required
trackingstringCapture policy at receipt (lot / serial) required
hs_codestringHS / tariff codeNEW optional
country_of_originstringISO country code, e.g. AENEW optional
shelf_life_daysintTotal shelf life in daysNEW optional
volume_cbmnumberUnit volume in m³ optional
weights[]arrayUoM-wise weight in kgNEW optional
replenishment_min_qtynumberMin stock level in base UoMNEW optional
replenishment_max_qtynumberMax stock level in base UoMNEW optional
lottables.batch_applicableY / NIs Batch / Lot No. captured at receiptNEW required
lottables.mfg_date_applicableY / NIs Manufacturing Date captured at receiptNEW required
lottables.expiry_date_applicableY / NIs Expiry Date captured at receiptNEW required
uoms[]arrayUoM-wise pack size + barcode required
variants[]arrayVariant codes, if the item has variants optional
✓ On success the response returns wms_reference_num — the WMS item id. If mandatory WMS fields are missing the message is REJECTED with the missing field named in error_message; fix in ERP and re-send.

Pick strategy derived from lottables

The three applicability flags determine the pickType RattusWMS assigns to the item — this is how batch / expiry control flows into picking behaviour:

ConditionpickTypeBehaviour
expiry_date_applicable = YFEFOFirst Expiry, First Out — pick nearest expiry first
batch_applicable = Y (no expiry)FIFO_BATCHBatch-controlled — pick oldest batch / mfg date first
all flags = NFIFOPlain first-in-first-out by location
⚠ Confirm this mapping — the exact pickType per condition is a warehouse-policy decision. Expiry implies batch (you cannot run FEFO without a lot to attach the expiry to), so expiry_date_applicable = Y is expected to be sent with batch_applicable = Y.
✏️
Item Update
Modify the fields the WMS allows to change
Client → WMS

Send item_no plus only the fields that changed. RattusWMS accepts changes to a fixed set of fields — anything outside this set is ignored.

JSON Payload
{
  "message_type":     "ITEM_UPDATE",
  "client_reference": "SKU001",
  "payload": {
    "item_no":       "SKU001",
    "description":   "Widget Blue 500ml v2",
    "item_category": "FG",
    "volume_cbm":    0.0013,
    "hs_code":       "3926.90",
    "weights": [
      { "uom": "CTN", "weight_kg": 11.00 }
    ],
    "uoms": [
      { "uom": "CTN", "qty_per_base": 20, "barcode": "8901234500031" }
    ]
  }
}

Editable fields

FieldTypeNotes
descriptionstringItem description / search name
item_categorystringCategory / grouping
weights[]arrayPer-UoM weight in kg
volume_cbmnumberUnit volume in m³
hs_codestringHS / tariff code
uoms[].qty_per_basenumberPack size, e.g. change CTN 24 → 20
uoms[].barcodestringUoM barcode number
⚠ No block / unblock. RattusWMS has no active/inactive status for items, so matrix scenario 8.2 (block / unblock item) is not supported through this integration. If item suppression is required, it must be handled on the the ERP side.
ℹ Changes that affect warehouse rules (weight / volume / category / pack size) are accepted while no transaction is open. If the item is locked by an open receipt or order, the update is returned FAILED with the blocking reference — resend after the transaction closes.
📦
ASN Create
Purchase Order → Advance Ship Notice
Client → WMS
JSON Payload
{
  "message_type":     "ASN_CREATE",
  "client_reference": "PO-12345",
  "payload": {
    "asn_type":         "FTWZ",          // GENERAL | FTWZ
    "storer_code":      "STORER01",
    "supplier_code":    "SUP001",
    "po_number":        "PO-12345",
    "po_date":          "2026-07-10",
    "expected_arrival": "2026-07-14",
    "currency":         "AED",

    "shipment": {
      "gate_pass_number": "GP-0042",
      "vehicle_number":   "MH46CR2386",
      "vehicle_type":     "40F",
      "container_number": "MSCU1234567",
      "container_type":   "40F",
      "cargo_type":       "FCL",           // FCL | LCL
      "seal_number":      "SL-12345",
      "driver_name":      "John Smith",
      "transporter_name": "XYZ Logistics",
      "entry_datetime":   "2026-07-14T08:30:00Z",

      "boe_number":       "BOE-2026-001",  // FTWZ only — Bill of Entry
      "boe_date":         "2026-07-13"     // FTWZ only
    },

    "lines": [
      {
        "line_no":        10000,
        "product_code":   "SKU001",
        "quantity":       100,
        "uom":            "CTN",
        "unit_price":     12.50,           // price per UoM
        "line_amount":    1250.00,         // extended amount
        "batch_number":   "BATCH001",
        "serial_numbers": ["SN001","SN002"],
        "mfg_date":       "2026-06-01",
        "expiry_date":    "2027-06-01"
      }
    ]
  }
}
Header fieldTypeDescription
asn_typestringGENERAL or FTWZ — sets the receipt flowNEW required
po_numberstringPO number required
supplier_codestringVendor code (mapped) optional
expected_arrivaldateExpected arrival date optional
line_nointClient line no. — target for amend / partial cancel required
quantitynumberExpected quantity in the given UoM required
unit_pricenumberPrice per UoMNEW optional
line_amountnumberExtended line amountNEW optional
serial_numbersarrayRequired when item is serial-trackedNEW optional

shipment — header shipment / vehicle details

All fields optional at creation. When sent, they pre-fill the receipt; the warehouse can still capture or correct them at the gate.

FieldTypeApplies to
gate_pass_numberstringBoth
vehicle_numberstringBoth
vehicle_typestringBoth
container_numberstringBoth
container_typestringBoth
cargo_typestringFCL / LCL
seal_numberstringBoth
driver_namestringBoth
transporter_namestringBoth
entry_datetimedatetimeGate entry timestamp
boe_numberstringFTWZ only — Bill of Entry
boe_datedateFTWZ only
⚠ FTWZ receipt rules. For an asn_type = FTWZ ASN, RattusWMS requires a linked gate pass, an LGP (landed-goods pallet/location), and the BOE before receipt can be confirmed, and validates the seal number at the gate. These are enforced on the warehouse floor — ERP only needs to send asn_type and any known shipment values; the rest is captured at receiving. GENERAL ASNs have no gate-pass / BOE requirement.
✓ Response returns wms_reference_num — the ASN number assigned by the warehouse (e.g. ASN-0042) — for reference only. The client system does not need to store it; all follow-up messages (amend, cancel) reference the po_number via client_reference, and RattusWMS resolves the internal ASN.
🔧
ASN Amend
Change qty / date, add or remove lines after send
Client → WMS

Each line carries an action. Reference the ASN by po_number — ERP never needs the WMS ASN number. One PO maps to exactly one ASN, so the PO resolves unambiguously. Header fields (expected_arrival, currency) may also be resent to update them.

JSON Payload
{
  "message_type":     "ASN_AMEND",
  "client_reference": "PO-12345",
  "payload": {
    "po_number": "PO-12345",         // WMS resolves the ASN from the PO
    "lines": [
      { "line_no": 10000, "action": "UPDATE", "quantity": 120 },
      { "line_no": 20000, "action": "ADD", "product_code": "SKU002", "quantity": 50, "uom": "CTN" },
      { "line_no": 30000, "action": "REMOVE" }
    ]
  }
}
⚠ Amend is accepted only while the ASN has not started receiving. Once receiving is in progress the message is returned FAILED with a status-lock reason. action: REMOVE also serves as partial cancellation.
❌
ASN Cancel
Cancel the whole ASN
Client → WMS
JSON Payload
{
  "message_type":     "ASN_CANCEL",
  "client_reference": "PO-12345",
  "payload": {
    "po_number": "PO-12345"          // WMS resolves the ASN from the PO
  }
}
ℹ Partial cancellation is handled by ASN Amend with action: REMOVE — cancel and amend operate in the same window (before receiving), so a separate partial-cancel would duplicate it. Use ASN Cancel only to void the entire ASN.
ℹ A duplicate cancel for an already-cancelled ASN returns PROCESSED with no further effect (idempotent, 2.2). Cancel is rejected once receiving has started.
📋
Order Create
Sales Order → outbound order for picking
Client → WMS
JSON Payload
{
  "message_type":     "ORDER_CREATE",
  "client_reference": "SO-98765",
  "payload": {
    "storer_code":   "STORER01",
    "customer_code": "CUST010",
    "order_number":  "SO-98765",
    "order_date":    "2026-07-12",
    "ship_date":     "2026-07-15",
    "priority":      "HIGH",           // LOW | NORMAL | HIGH
    "currency":      "AED",
    "ship_to": {
      "name":    "ABC Trading LLC",
      "address": "Warehouse 7, Al Quoz",
      "city":    "Dubai",
      "country": "AE"
    },
    "lines": [
      {
        "line_no":      10000,
        "product_code": "SKU001",
        "quantity":     40,
        "uom":          "CTN",
        "unit_price":   18.00,          // price per UoM
        "line_amount":  720.00,         // extended amount
        "requested_lottables": {        // optional — pick this stock specifically
          "batch_number": "BATCH001",
          "expiry_date":  "2027-06-01",
          "mfg_date":     "2026-06-01"
        }
      }
    ]
  }
}
FieldTypeDescription
order_numberstringSO number required
ship_datedateRequested ship date optional
prioritystringFulfillment priority optional
unit_pricenumberPrice per UoMNEW optional
line_amountnumberExtended line amountNEW optional
requested_lottables.batch_numberstringAllocate this batch / lot specificallyNEW optional
requested_lottables.expiry_datedateAllocate stock of this expiryNEW optional
requested_lottables.mfg_datedateAllocate stock of this mfg dateNEW optional
ℹ requested_lottables lets the ERP request specific stock — any combination of batch / expiry / mfg date. When present it overrides the item's default pickType (FEFO / FIFO); WMS allocates the matching stock. If the requested lottable has insufficient stock, the line short-picks against it rather than falling back to other stock — confirm this fallback rule with the INDU team.
⚠ Orders on credit hold or for blocked customers should not be sent. The ERP is expected to suppress these at source — RattusWMS has no visibility of credit status.
🔧
Order Amend
Change qty / date, add or remove lines
Client → WMS

Same line-level action model as ASN Amend. Reference the order by order_number — ERP never needs the WMS order number, and one SO maps to exactly one order.

JSON Payload
{
  "message_type":     "ORDER_AMEND",
  "client_reference": "SO-98765",
  "payload": {
    "order_number": "SO-98765",
    "ship_date":    "2026-07-16",
    "lines": [
      { "line_no": 10000, "action": "UPDATE", "quantity": 35 },
      { "line_no": 20000, "action": "ADD", "product_code": "SKU003", "quantity": 10, "uom": "CTN" }
    ]
  }
}
⚠ Accepted only before picking starts. After picking begins the amend is returned FAILED — handle the balance via cancel + new order. action: REMOVE also serves as partial cancellation.
🚫
Order Cancel
Cancel the whole order
Client → WMS
JSON Payload
{
  "message_type":     "ORDER_CANCEL",
  "client_reference": "SO-98765",
  "payload": {
    "order_number": "SO-98765"       // WMS resolves the order from the SO
  }
}
ℹ Partial cancellation is handled by Order Amend with action: REMOVE. Use Order Cancel only to void the entire order. Behaviour of a full cancel depends on order state:
ScenarioBehaviour
Before pickingCancelled cleanly
After picking startedTriggers unpick / return handling in WMS
Remaining after partial shipCancels open balance only
After shipment completeRejected — no impact
Duplicate cancelIdempotent — no further effect
🔁
Transfer Order
Warehouse-to-warehouse movement
Client → WMS
🔧 Proposal. Transfer Order support is planned; the touch-point scenarios are still being finalised. The shape below is a starting point.
JSON Payload
{
  "message_type":     "TRANSFER_CREATE",
  "client_reference": "TO-5001",
  "payload": {
    "transfer_number": "TO-5001",
    "from_warehouse":  "WH1",
    "to_warehouse":    "WH2",
    "transfer_date":   "2026-07-16",
    "lines": [
      { "line_no": 10000, "product_code": "SKU001", "quantity": 30, "uom": "CTN" }
    ]
  }
}
✅
Receipt Confirmed
Goods received against a PO / ASN
WMS → Client

Posted per receipt event. receipt_type distinguishes full vs partial; a partial receipt leaves the balance open for a later confirmation.

Webhook Payload
{
  "event":            "RECEIPT_CONFIRMED",
  "timestamp":        "2026-07-14T10:00:00Z",
  "client_reference": "PO-12345",
  "asn_number":       "ASN-0042",
  "receipt_number":   "RCP-0001",
  "warehouse_code":   "WH1",
  "receipt_type":     "PARTIAL",          // FULL | PARTIAL
  "lines": [
    {
      "line_no":         10000,
      "product_code":    "SKU001",
      "ordered_qty":     100,
      "received_qty":    98,
      "uom":             "CTN",
      "variance":        -2,
      "location":        "A1-P02",
      "batch_number":    "BATCH001",
      "serial_numbers":  ["SN001","SN002"],
      "mfg_date":        "2026-06-01",
      "expiry_date":     "2027-06-01",
      "inventory_state": "NORMAL"          // NORMAL | DAMAGED | QUARANTINE
    }
  ]
}
ℹ receipt_number makes each event idempotent on the client side — reprocessing the same number must not double-post. If the PO / line cannot be matched, WMS records the failure and no webhook is sent.
🚚
Shipment Confirmed
Order shipped, with short-pick and carrier detail
WMS → Client
Webhook Payload
{
  "event":            "SHIP_CONFIRMED",
  "timestamp":        "2026-07-15T14:00:00Z",
  "client_reference": "SO-98765",
  "order_number":     "SO-98765",
  "shipment_number":  "SHP-0001",
  "warehouse_code":   "WH1",
  "shipment_type":    "PARTIAL",          // FULL | PARTIAL
  "lines": [
    {
      "line_no":        10000,
      "product_code":   "SKU001",
      "ordered_qty":    40,
      "shipped_qty":    38,
      "short_qty":      2,
      "uom":            "CTN",
      "batch_number":   "BATCH001",
      "serial_numbers": ["SN010"]
    }
  ],
  "carrier": {
    "transporter_name": "Acme Logistics",
    "vehicle_number":   "TRK-4471",
    "tracking_number":  "TRK-9988",
    "container_number": "MSCU1234567",
    "seal_number":      "SL-12345"
  }
}
FieldDescription
shipped_qtyActual quantity shipped for the line
short_qtyUnfulfilled quantity on a short pick
serial_numbersLot / serial detail per line
carrierCarrier / tracking / packing info
shipment_numberIdempotency key — reprocess-safe
🖼️
Item Image Sync
WMS-captured image → ERP (client DMS)
WMS → Client

RattusWMS captures an image against an item and returns it to the ERP, which stores it against the item (in the client DMS). Two transport options — pick one at design:

Option A · inline base64
{
  "event":     "ITEM_IMAGE_SYNC",
  "timestamp": "2026-07-14T09:05:00Z",
  "item_no":   "SKU001",
  "image": {
    "filename":     "SKU001.jpg",
    "content_type": "image/jpeg",
    "encoding":     "base64",
    "data":         "/9j/4AAQSkZJRgABAQ..."   // base64 bytes
  }
}
Option B · URL reference
{
  "event":     "ITEM_IMAGE_SYNC",
  "timestamp": "2026-07-14T09:05:00Z",
  "item_no":   "SKU001",
  "image": {
    "filename": "SKU001.jpg",
    "url":      "https://webui.rattusapps.com/media/items/SKU001.jpg"
  }
}
ℹ Option A avoids a second fetch but inflates payload size; Option B keeps webhooks small but needs ERP to pull the file. Recommendation: Option B for anything above ~1 MB.
🔗
Field Mapping
Typical ERP ↔ RattusWMS correspondence
ERP / Client FieldWMS FieldNotes
Purchase Order · No.po_number / client_referenceCommon reference
Sales Order · No.order_number / client_referenceCommon reference
Document Line · Line No.line_noAmend / partial-cancel target
Vendor · No.supplier_codeRequires vendor map
Customer · No.customer_codeRequires customer map
Item · No.product_code / item_noDirect
Variant Codevariant_codeDirect
Unit of Measure CodeuomRequires UoM map
Item Reference / Barcodeuoms[].barcodePer-UoM barcode
Location Codewarehouse_codeWarehouse-level
Bin CodelocationWMS bin ↔ ERP bin
Lot No.batch_numberDirect
Serial No.serial_numbers[]Serial-tracked items
Direct Unit Cost (Excl. VAT)unit_price (ASN)Purchase side
Unit Price (Excl. VAT)unit_price (Order)Sales side
Line Amount (Excl. VAT)line_amountExtended amount
Gross Weight (per UoM)weights[].weight_kgItem master — UoM-wise
Unit Volumevolume_cbmItem master
Tariff No.hs_codeItem master
Country of Origincountry_of_originISO country code
Shelf Lifeshelf_life_daysSend as total days
Reorder Minimumreplenishment_min_qtyBase UoM
Reorder Maximumreplenishment_max_qtyBase UoM
⚠ Three lookup tables must be agreed before development: Vendor, Customer, and UoM. If ERP and WMS share the same codes, the maps are pass-through.
📊
Message Status Codes
Inbound message lifecycle
StatusDescription
PENDINGReceived and queued. Processed within 5 minutes.
PROCESSINGBeing sent to the WMS. Do not resubmit.
PROCESSEDDone. See wms_reference_num for the WMS reference.
FAILEDFailed after 3 retries. See error_message. Safe to resubmit.
REJECTEDInvalid payload or unauthorized. Fix before resubmitting.
⚠️
Error Handling
HTTP codes and retry behaviour
CodeMeaningAction
201Queued successfullyStore id, poll for status
400Invalid body or message_typeFix payload and retry
401Missing / invalid API keyCheck X-Kiban-API-Key
429Rate limit exceededWait 60s and retry
500Server errorContact RattusWMS support
✓ Outbound webhooks are retried at 5, 10 and 15 minute intervals before being marked FAILED. Respond with HTTP 200 to acknowledge.
⚡
Rate Limits
Default limits per client
LimitValue
Requests per minute60
Max payload size1 MB
Max lines per message500
Status historyLast 100 messages
ℹ Higher limits are available on request — relevant for bulk item-master loads and base64 image sync.