GSC POD API

Stop

Stop Sync v23

Saves stop and product updates for one or more stops on a route. Handles stop status, product counts, OSD entries, driver comments, and signatures.

Endpoint: PUT /api/route/stop

Authentication: Required: headers: employee_id, api_token

Note (Route closure: behavior differs by environment as of v23): Whether to enable arrival-gating in production is an ongoing internal decision (still unresolved as of this writing), not a bug: both paths below are current and intentional for now.

Note (OSD): Both product.updates.osd_data and product.action.updates.osd_data use the same grouped format: [{ osd_id, osd_code, data: [{ osd_parent, comment, quantity, images_id, barcodes, quantity_type }] }]. barcodes is a single barcode string per entry (empty string if none). quantity_type v23 is "units", "cases", or omitted/null: written to the PDQTYIS column. osd_id (group-level) and osd_parent (entry-level) v23 are opaque char(6) values written to PDOSDID/PDOSDPAR and echoed back unchanged on GET: the API only stores and recalls them, it does not interpret them. Product-level OSD writes PDIDCODE = product_id, PDUPCCD = barcodes, PDOSDITMZ = 'N'. Action (itemized) OSD writes PDIDCODE = product_id, PDUPCCD = '', PDOSDITMZ = 'Y'; barcodes in data entries are not persisted.

Note (Overage Items): Items found at the stop that are not on the manifest go in stop.updates.overage_items: [{ barcode, osd_code, quantity, comment, images_id }]: no quantity_type on this shape. Each entry writes one GPODOSD row (PDIDCODE = '', PDUPCCD = barcode, PDOSDITMZ=N). On GET, rows with an empty PDIDCODE are returned in stop.updates.overage_items.

Note (Delivery Email): If the stop is non-warehouse (id !== 999), updates.status is "D", and the route is flagged GROUTEC.ROUTEPPOD = 'Y', a delivery summary email is sent automatically after all writes complete. See the email preview tool below.

Note (Training mode, v23+): Send "training": true at the top level of the body to run the request without changing any data. Auth, StopGuard, reads, the response shape and logging all run normally.

Note (Stop Guard, v22+): Before anything is written, the request is checked by lib/StopGuard. These checks never reject the request.


Request body:

{
  "id": "17140",
  "facility": "011",
  "week_end": "20251031",
  "stops": [
    {
      "id": 258,
      "arrived": false,
      "updates": {
        "status": "D",
        "followup_reason_code": "",
        "start_delivery_time": "2025-10-31T10:00:00Z",
        "end_delivery_time": "2025-10-31T10:15:00Z",
        "delivery_latitude": "41.8781",
        "delivery_longitude": "-87.6298",
        "delivered_by_driver_id": "T0048",
        "store_emp_id": "EMP001",
        "store_emp_name": "JOHN DOE",
        "driver_comments": "Left at dock",
        "skip_refuse_reason_code": "",
        "skip_refuse_timestamp": "",
        "skip_refuse_driver_comment": "",
        "signature_id": "",
        "osd_emails": [],
        "overage_items": [
          { "barcode": "012345678901", "osd_code": "85", "quantity": 1, "comment": "", "images_id": "" }
        ]
      },
      "products": [
        {
          "id": "038976",
          "invoice": "0806591",
          "updates": {
            "accounting_complete": false,
            "delivered": 6,
            "returned": 0,
            "delivered_pallets": null,
            "image_ids": null,
            "osd_data": [
              {
                "osd_id": "ABCDEF",
                "osd_code": 51,
                "data": [
                  { "osd_parent": "ABCDEF", "comment": "1 bag missing",  "quantity": 1, "images_id": "", "barcodes": "00016000148710", "quantity_type": "units" },
                  { "osd_parent": null,     "comment": "1 damaged box",  "quantity": 1, "images_id": "", "barcodes": "016000502789",  "quantity_type": null }
                ]
              }
            ]
          },
          "action": {
            "updates": { "delivered": 0, "osd_data": [] },
            "type": null,
            "open": false,
            "open_action": null,
            "item_name": null,
            "quantity": 7
          }
        },
        {
          "id": "9001",
          "invoice": "0806591",
          "updates": {
            "accounting_complete": false,
            "delivered": 10,
            "returned": 0,
            "delivered_pallets": null,
            "image_ids": null,
            "osd_data": []
          },
          "action": {
            "updates": { "delivered": 10, "osd_data": [] },
            "type": "count",
            "open": false,
            "open_action": null,
            "item_name": null,
            "quantity": 10
          }
        }
      ],
      "collections": [
        {
          "id": "9009",
          "invoice": "0806591",
          "updates": {
            "returned": 0,
            "accounting_complete": false,
            "image_ids": null,
            "osd_data": []
          },
          "action": {
            "updates": { "delivered": 0, "osd_data": [] },
            "type": "collect",
            "open": false,
            "open_action": null,
            "item_name": null,
            "quantity": 0
          }
        }
      ]
    }
  ]
}
		

Try It Out


Result:

...

Delivery Email Preview Debug

Renders the delivery summary email's generated HTML directly in the response: no email is sent. Useful for checking layout/content without triggering a real send (which is otherwise a side effect of PUT /api/route/stop, not directly callable).

Endpoint: GET /api/route/stop/email-preview?facility=&route_id=&stop_id=&week_end=

Authentication: None


Try It Out

Stop Skip-Refuse

Marks a stop as skipped or refused.

Endpoint: PUT /api/route/stop/skip-refuse

Authentication: Required: headers: employee_id, api_token

Required body fields: route_id, stop_id


Try It Out


Result:

...