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.