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.
| Touch Point | Direction | Message | Status |
| Item Master — create | Client → WMS | ITEM_CREATE | Draft |
| Item Master — modify (no block) | Client → WMS | ITEM_UPDATE | Draft |
| Purchase Order / ASN — create | Client → WMS | ASN_CREATE | Live |
| Purchase Order / ASN — amend | Client → WMS | ASN_AMEND | Draft |
| Purchase Order / ASN — cancel | Client → WMS | ASN_CANCEL | Live |
| Sales Order — create | Client → WMS | ORDER_CREATE | Draft |
| Sales Order — amend | Client → WMS | ORDER_AMEND | Draft |
| Sales Order — cancel | Client → WMS | ORDER_CANCEL | Draft |
| Transfer Order — create | Client → WMS | TRANSFER_CREATE | Draft |
| Warehouse Receiving | WMS → Client | RECEIPT_CONFIRMED | Live |
| Warehouse Shipment | WMS → Client | SHIP_CONFIRMED | Draft |
| Item image sync (→ client DMS) | WMS → Client | ITEM_IMAGE_SYNC | Draft |
⚠ 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.
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.
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.
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.
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.
| Field | Type | Description |
| message_type | string | One of the types in the scope matrix required |
| client_reference | string | ERP document no. — PO No., SO No., Item No. required |
| warehouse_code | string | Target warehouse. Defaults to the assigned warehouse optional |
| payload | object | Message-specific body (see each type) required |
| Param | Description |
| reference | Your client_reference value optional |
| id | Message id returned from submit optional |
| status | PENDING / PROCESSED / FAILED optional |
| limit | Max 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
{
"success": true,
"message": "Message queued successfully",
"id": "e256bc06-b87e-4d3d-a5a5-7e98f0dc735d",
"status": "PENDING",
"reference": "PO-12345",
"queued_at": "2026-07-14T10:20:43Z"
}
{
"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" }
]
}
}
| Field | Type | Description |
| item_no | string | ERP Item No. — becomes WMS product_code required |
| base_uom | string | Base unit of measure required |
| tracking | string | Capture policy at receipt (lot / serial) required |
| hs_code | string | HS / tariff codeNEW optional |
| country_of_origin | string | ISO country code, e.g. AENEW optional |
| shelf_life_days | int | Total shelf life in daysNEW optional |
| volume_cbm | number | Unit volume in m³ optional |
| weights[] | array | UoM-wise weight in kgNEW optional |
| replenishment_min_qty | number | Min stock level in base UoMNEW optional |
| replenishment_max_qty | number | Max stock level in base UoMNEW optional |
| lottables.batch_applicable | Y / N | Is Batch / Lot No. captured at receiptNEW required |
| lottables.mfg_date_applicable | Y / N | Is Manufacturing Date captured at receiptNEW required |
| lottables.expiry_date_applicable | Y / N | Is Expiry Date captured at receiptNEW required |
| uoms[] | array | UoM-wise pack size + barcode required |
| variants[] | array | Variant 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:
| Condition | pickType | Behaviour |
| expiry_date_applicable = Y | FEFO | First Expiry, First Out — pick nearest expiry first |
| batch_applicable = Y (no expiry) | FIFO_BATCH | Batch-controlled — pick oldest batch / mfg date first |
| all flags = N | FIFO | Plain 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.
Send item_no plus only the fields that changed. RattusWMS accepts changes to a fixed set of fields — anything outside this set is ignored.
{
"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
| Field | Type | Notes |
| description | string | Item description / search name |
| item_category | string | Category / grouping |
| weights[] | array | Per-UoM weight in kg |
| volume_cbm | number | Unit volume in m³ |
| hs_code | string | HS / tariff code |
| uoms[].qty_per_base | number | Pack size, e.g. change CTN 24 → 20 |
| uoms[].barcode | string | UoM 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.
{
"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 field | Type | Description |
| asn_type | string | GENERAL or FTWZ — sets the receipt flowNEW required |
| po_number | string | PO number required |
| supplier_code | string | Vendor code (mapped) optional |
| expected_arrival | date | Expected arrival date optional |
| line_no | int | Client line no. — target for amend / partial cancel required |
| quantity | number | Expected quantity in the given UoM required |
| unit_price | number | Price per UoMNEW optional |
| line_amount | number | Extended line amountNEW optional |
| serial_numbers | array | Required 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.
| Field | Type | Applies to |
| gate_pass_number | string | Both |
| vehicle_number | string | Both |
| vehicle_type | string | Both |
| container_number | string | Both |
| container_type | string | Both |
| cargo_type | string | FCL / LCL |
| seal_number | string | Both |
| driver_name | string | Both |
| transporter_name | string | Both |
| entry_datetime | datetime | Gate entry timestamp |
| boe_number | string | FTWZ only — Bill of Entry |
| boe_date | date | FTWZ 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.
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.
{
"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.
{
"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.
{
"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"
}
}
]
}
}
| Field | Type | Description |
| order_number | string | SO number required |
| ship_date | date | Requested ship date optional |
| priority | string | Fulfillment priority optional |
| unit_price | number | Price per UoMNEW optional |
| line_amount | number | Extended line amountNEW optional |
| requested_lottables.batch_number | string | Allocate this batch / lot specificallyNEW optional |
| requested_lottables.expiry_date | date | Allocate stock of this expiryNEW optional |
| requested_lottables.mfg_date | date | Allocate 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.
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.
{
"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.
{
"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:
| Scenario | Behaviour |
| Before picking | Cancelled cleanly |
| After picking started | Triggers unpick / return handling in WMS |
| Remaining after partial ship | Cancels open balance only |
| After shipment complete | Rejected — no impact |
| Duplicate cancel | Idempotent — no further effect |
🔧 Proposal. Transfer Order support is planned; the touch-point scenarios are still being finalised. The shape below is a starting point.
{
"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" }
]
}
}
Posted per receipt event. receipt_type distinguishes full vs partial; a partial receipt leaves the balance open for a later confirmation.
{
"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.
{
"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"
}
}
| Field | Description |
| shipped_qty | Actual quantity shipped for the line |
| short_qty | Unfulfilled quantity on a short pick |
| serial_numbers | Lot / serial detail per line |
| carrier | Carrier / tracking / packing info |
| shipment_number | Idempotency key — reprocess-safe |
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:
{
"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
}
}
{
"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.
| ERP / Client Field | WMS Field | Notes |
| Purchase Order · No. | po_number / client_reference | Common reference |
| Sales Order · No. | order_number / client_reference | Common reference |
| Document Line · Line No. | line_no | Amend / partial-cancel target |
| Vendor · No. | supplier_code | Requires vendor map |
| Customer · No. | customer_code | Requires customer map |
| Item · No. | product_code / item_no | Direct |
| Variant Code | variant_code | Direct |
| Unit of Measure Code | uom | Requires UoM map |
| Item Reference / Barcode | uoms[].barcode | Per-UoM barcode |
| Location Code | warehouse_code | Warehouse-level |
| Bin Code | location | WMS bin ↔ ERP bin |
| Lot No. | batch_number | Direct |
| 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_amount | Extended amount |
| Gross Weight (per UoM) | weights[].weight_kg | Item master — UoM-wise |
| Unit Volume | volume_cbm | Item master |
| Tariff No. | hs_code | Item master |
| Country of Origin | country_of_origin | ISO country code |
| Shelf Life | shelf_life_days | Send as total days |
| Reorder Minimum | replenishment_min_qty | Base UoM |
| Reorder Maximum | replenishment_max_qty | Base 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.
| Status | Description |
| PENDING | Received and queued. Processed within 5 minutes. |
| PROCESSING | Being sent to the WMS. Do not resubmit. |
| PROCESSED | Done. See wms_reference_num for the WMS reference. |
| FAILED | Failed after 3 retries. See error_message. Safe to resubmit. |
| REJECTED | Invalid payload or unauthorized. Fix before resubmitting. |
| Code | Meaning | Action |
| 201 | Queued successfully | Store id, poll for status |
| 400 | Invalid body or message_type | Fix payload and retry |
| 401 | Missing / invalid API key | Check X-Kiban-API-Key |
| 429 | Rate limit exceeded | Wait 60s and retry |
| 500 | Server error | Contact RattusWMS support |
✓ Outbound webhooks are retried at 5, 10 and 15 minute intervals before being marked FAILED. Respond with HTTP 200 to acknowledge.
| Limit | Value |
| Requests per minute | 60 |
| Max payload size | 1 MB |
| Max lines per message | 500 |
| Status history | Last 100 messages |
ℹ Higher limits are available on request — relevant for bulk item-master loads and base64 image sync.