Skip to main content

Changelog

Track changes, improvements, and updates to the Delivery Locker API.

Version 1.0.299 (2026-01-23)

⚠️ Breaking Changes

Webhook Payload Structure Overhaul (SD-3662)

The webhook payload structure has been updated to use a flat proto-based format instead of the previous envelope wrapper format. This is a breaking change that requires updates to your webhook handlers.

Key Changes:

  1. Payload Format: Changed from envelope wrapper to flat structure
  2. Event Type Field: Changed from event to event_type with proto enum values
  3. Event Type Values: Changed from dot notation to proto enum format
  4. New Header: Added X-Platform-Order-Id header to all webhook requests

Payload Structure Change

Before (Legacy Envelope Format):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"event": "reservation.dropped_off",
"timestamp": "2025-06-13T10:30:00Z",
"data": {
"reservation_id": "res_abc123",
"platform_order_id": "order_12345",
"machine_id": "kf_tangerang_001",
"cell_description": "A03",
"status": "DROPPED_OFF"
}
}

After (Flat Proto Format):

{
"event_id": "evt_550e8400-e29b-41d4-a716-446655440000",
"idempotency_key": "idem_abc123def456",
"event_time_unix_timestamp": 1718271000,
"event_time_timestamp": "2025-06-13T10:30:00Z",
"platform_order_id": "order_12345",
"reservation_id": "res_abc123",
"event_type": "EVENT_TYPE_DROPOFF",
"drop_off_event": {
"source_type": "SOURCE_TYPE_MACHINE",
"cell": {
"description": "A03",
"cell_id": "cell_kf_tan_001_a03"
},
"machine": {
"machine_id": "kf_tangerang_001",
"name": "Tangerang Station Locker",
"location": "Tangerang Train Station"
}
}
}

Event Type Value Changes

Old FormatNew Format (Proto Enum)
reservation.createdEVENT_TYPE_RESERVATION_CREATED
reservation.dropped_offEVENT_TYPE_DROPOFF
reservation.picked_upEVENT_TYPE_PICKUP
reservation.cancelledEVENT_TYPE_RESERVATION_CANCELLED
reservation.pickup_failedEVENT_TYPE_PICKUP_FAILED
reservation.door_manually_openedEVENT_TYPE_OPEN_DOOR_FULFILLED

New Webhook Header

HeaderDescriptionExample
X-Platform-Order-IdYour original order ID from the reservationorder_12345

This header is now included in all webhook requests.

Updated X-Webhook-Event Header

The X-Webhook-Event header now uses proto enum values:

Before: X-Webhook-Event: reservation.dropped_off

After: X-Webhook-Event: EVENT_TYPE_DROPOFF

🔄 Migration Guide

Step 1: Update Event Type Parsing

// Before
switch (payload.event) {
case 'reservation.dropped_off':
handleDropoff(payload.data);
break;
case 'reservation.picked_up':
handlePickup(payload.data);
break;
}

// After
switch (payload.event_type) {
case 'EVENT_TYPE_DROPOFF':
handleDropoff(payload.drop_off_event);
break;
case 'EVENT_TYPE_PICKUP':
handlePickup(payload.pick_up_event);
break;
}

Step 2: Update Payload Field Access

// Before - envelope format with flat data
const orderId = payload.data.platform_order_id;
const cellDesc = payload.data.cell_description;

// After - flat format with nested event data
const orderId = payload.platform_order_id;
const cellDesc = payload.drop_off_event.cell.description;

Step 3: Update Idempotency Handling

// Before - using envelope id
const eventId = payload.id;

// After - using idempotency_key for deduplication
const idempotencyKey = payload.idempotency_key; // Same across retries
const eventId = payload.event_id; // Unique per delivery

📍 Affected Webhooks

All webhook event types are affected:

  • EVENT_TYPE_RESERVATION_CREATED - Reservation created
  • EVENT_TYPE_DROPOFF - Package dropped off
  • EVENT_TYPE_PICKUP - Package picked up
  • EVENT_TYPE_RESERVATION_CANCELLED - Reservation cancelled
  • EVENT_TYPE_PICKUP_FAILED - Pickup attempt failed
  • EVENT_TYPE_OPEN_DOOR_FULFILLED - Door open request completed

📚 Updated Documentation

The Webhook Integration documentation has been updated to reflect the new payload structure and includes:

  • Complete payload examples for all event types
  • Field reference tables
  • Code examples for signature verification
  • Idempotency handling guidance

Version 1.0.288 (2025-11-13)

✅ New Features

RequestMaintenance Endpoint

Added endpoint for platforms to report cell or locker issues requiring operations team attention.

  • Endpoint: POST /api/delivery/external/v1/maintenances
  • Purpose: Report cell/locker malfunctions or maintenance needs
  • Features:
    • Create maintenance tickets in the system
    • Optional immediate cell blocking to prevent further reservations
    • Integration with operations team workflow
  • Use Cases:
    • Report broken doors or mechanisms
    • Flag cells with hardware issues
    • Escalate repeated failure patterns
    • Proactive maintenance requests

OpenDoor Endpoint (Out-of-Band)

Added asynchronous door opening endpoint for customer support and troubleshooting scenarios.

  • Endpoint: POST /api/delivery/external/v1/reservations/{reservation_id}/open-door
  • Purpose: Open locker door without changing reservation state
  • Behavior:
    • Async operation - request accepted immediately
    • Webhook EVENT_TYPE_OPEN_DOOR_FULFILLED sent when completed
    • Use request_id (from X-Request-ID header) to correlate API call with webhook
  • Time Window Constraints:
    • Cell allocation period (before drop-off)
    • Drop-off grace period
    • Awaiting pickup period (DROPPED_OFF state)
    • Pickup grace period
    • Extended window until cell is reallocated
  • Parameters:
    • reason (optional): Explanation for opening (e.g., "Customer support request")
    • platform_reference_id (optional): Your internal ticket/reference ID
  • Error Handling:
    • Immediate errors: Invalid reservation, auth failure, time window violation, device offline
    • Deferred errors: Hardware failure, door mechanism issues (via webhook)
  • Use Cases:
    • Customer support assistance
    • Door mechanism verification
    • Emergency access situations
    • Troubleshooting pickup issues

Cell Unique Identification

Added unique identifier for cells within machines.

  • New Field: cell_id in Cell message
  • Purpose: Provides stable unique identifier for each cell
  • Format: String, max length 128 characters
  • Generated by: KF delivery platform
  • Benefits:
    • Consistent cell identification across API calls
    • Better tracking and debugging
    • Foundation for cell-specific analytics

🔄 Enhanced Webhook Events

New OpenDoor Fulfilled Event

Added webhook event for out-of-band door opening operations.

  • Event Type: EVENT_TYPE_OPEN_DOOR_FULFILLED (6)
  • Trigger: Sent when OpenDoor API request completes (success or failure)
  • Payload (OpenDoorFulfilledEvent):
    • reservation_id: Reservation ID
    • request_id: Original X-Request-ID from OpenDoor call (for correlation)
    • cell: Cell that was opened (or attempted)
    • success: Boolean indicating if door opened successfully
    • fulfilled_at: Timestamp when operation completed
    • error_message: Optional error details if success = false
    • reason: Echoed reason from original request
    • platform_reference_id: Echoed reference ID from original request
    • machine: Machine information
  • Use Cases:
    • Confirm door opening for customer support
    • Track success rate of manual interventions
    • Alert on repeated failures
    • Audit trail for support actions

📚 Improved Documentation

Enhanced Grace Period Documentation

Significantly enhanced documentation for DropOff and PickUp operations to clarify grace period behavior.

Key Clarifications:

  • State transition timing:
    • DropOff: State changes to DROPPED_OFF immediately when door opens (not when it closes)
    • PickUp: State changes to PICKED_UP immediately when door opens
  • Grace period behavior:
    • Grace period starts AFTER first successful door open
    • Purpose: Allows re-opening the door during the period (not a delay)
    • Both API and physical code methods share the same grace period timer
    • Default: 120 seconds for both drop-off and pickup
  • Subsequent calls: During grace period, can call DropOff/PickUp again to re-open door without changing state

Time Window Documentation

Added comprehensive documentation for OpenDoor API explaining valid time windows:

  1. Cell allocation period
  2. Drop-off grace period
  3. Awaiting pickup period
  4. Pickup grace period
  5. Extended window until reallocation

📍 Affected Endpoints

  • New: POST /api/delivery/external/v1/maintenances - Request maintenance
  • New: POST /api/delivery/external/v1/reservations/{reservation_id}/open-door - Out-of-band door opening
  • Enhanced: POST /api/delivery/external/v1/reservations/{reservation_id}/dropoffs - Improved documentation
  • Enhanced: POST /api/delivery/external/v1/reservations/{reservation_id}/pickups - Improved documentation

📚 New Data Structures

  • RequestMaintenanceRequest: Request structure for maintenance tickets
    • cell_id or machine-level issue
    • Issue description and severity
    • Optional immediate cell blocking
  • RequestMaintenanceResponse: Response with maintenance ticket information
  • OpenDoorRequest: Request structure for out-of-band door opening
    • reservation_id (required)
    • reason (optional): Explanation for opening
    • platform_reference_id (optional): Your internal reference
  • OpenDoorResponse: Immediate response confirming request acceptance
    • Webhook sent later when operation completes
  • OpenDoorFulfilledEvent: Webhook event for completed door opening
    • See webhook section above for full details
  • Cell.cell_id: New string field (max 128 chars) for unique cell identification

Version 1.0.283 (2025-11-11)

✅ New Features

ListOngoingReservations Endpoint

Added comprehensive endpoint to retrieve all ongoing reservations with advanced filtering and pagination support.

  • Endpoint: GET /api/delivery/external/v1/reservations
  • Purpose: Query all ongoing reservations that are actively in use (not in terminal state)
  • Ongoing States:
    • PENDING: Cell reserved, waiting for drop-off
    • DROPPED_OFF: Package dropped off, waiting for pickup
    • PICKED_UP: Package picked up but still within grace period (consumer can re-open door)
  • Features:
    • Pagination support with configurable page size (default: 100, max: 1000)
    • Time-based filtering via created_after parameter (exclusive filter)
    • Results ordered by creation time (oldest first)
    • Lightweight response optimized for list displays
    • Total count of ongoing reservations
  • Grace Period Logic: Reservations in PICKED_UP state remain in the list only while (current_time - picked_up_at) <= grace_period_pickup_seconds
  • Use Cases:
    • Monitor active deliveries in progress
    • Track packages waiting for consumer pickup
    • Identify reservations needing attention
    • Build real-time dashboards
    • Support incremental sync workflows

Machine Occupancy Information

New real-time occupancy tracking for locker machines.

  • New Field: Machine.occupancy_information (type: OccupancyStatus)
  • Purpose: Provides real-time occupancy status including reserved cells
  • Occupancy Levels:
    • LOW: ≤30% occupied - Machine is essentially empty
    • MEDIUM: 31-70% occupied - Machine is partially occupied
    • HIGH: >70% occupied - Machine is almost full
    • OVERLOADED: >95% occupied - Machine is overloaded
  • Use Cases:
    • Smart machine selection based on availability
    • Capacity planning and monitoring
    • Alert on overloaded machines
    • Optimize delivery routing

Complete Cell Inventory

  • New Field: Machine.all_cells (repeated CellInformation)
  • Purpose: Returns complete list of all cells configured for the machine
  • Difference from preferred_cells:
    • preferred_cells: Non-exhaustive, KF-recommended cells blended by size. Only includes cells with status IDLE at the time of query (not reserved or occupied).
    • all_cells: Complete inventory of all configured cells
  • Use Cases:
    • Understand full machine capacity
    • Build custom cell selection logic
    • Display complete cell availability

Request ID Tracing

New request ID fields for improved tracing and debugging.

  • New Fields:
    • ReserveCellResponse.request_id: Stores the X-Request-ID header from ReserveCell API call
    • GetReservationResponse.request_id: Returns the stored request ID for tracing
  • Purpose: End-to-end request tracing and debugging support
  • Behavior: Automatically captured from X-Request-ID header if provided in reservation creation

🔄 Enhanced Webhook Events

New Pickup Failed Event

Added webhook event for failed pickup attempts.

  • Event Type: EVENT_TYPE_PICKUP_FAILED (5)
  • Trigger: Sent when a pickup attempt fails (door doesn't open)
  • Payload (PickUpFailedEvent):
    • source_type: How user interacted (API, QR code, numeric code)
    • request_id: Optional X-Request-ID header if from platform API
    • cell: Cell where pickup failed
    • machine: Machine information
    • error_message: Details about the failure
  • Use Cases:
    • Alert on failed pickup attempts
    • Track machine/door reliability
    • Proactive customer support
    • Detect potential fraud attempts

📚 Improved Documentation

Grace Period Behavior Clarification

Significantly enhanced documentation for grace period functionality in DropOff and PickUp operations.

Key Clarifications:

  • Grace period purpose: Allows re-opening the door during the period, not a delay
  • Drop-off grace period:
    • Starts AFTER first successful door open
    • Default: 120 seconds (configurable via grace_period_dropoff_in_seconds)
    • Allows rider/driver to re-open if door accidentally closed
    • State transition: State changes to DROPPED_OFF only when door closes (not when it opens)
  • Pickup grace period:
    • Starts AFTER first successful door open
    • Default: 120 seconds (configurable via grace_period_pickup_in_seconds)
    • Allows consumer to re-open if door accidentally closed
    • State transition: State changes to PICKED_UP immediately when door opens successfully
  • Shared timer: Both API and physical code methods share the same grace period

State Transition Documentation

Added comprehensive state transition diagrams and explanations highlighting asymmetric behavior:

Drop-off Flow (state changes on door close):

1. Call /dropoffs → Door opens (state: PENDING)
2. Driver places package
3. Door closes → State becomes DROPPED_OFF + webhook sent
└─ During grace period: Can call DropOff again (door re-opens, state stays DROPPED_OFF)

Pickup Flow (state changes on door open):

1. Call /pickups → Door opens + State becomes PICKED_UP + webhook sent
2. Consumer retrieves package
3. Door closes
└─ During grace period: Can call PickUp again (door re-opens, state stays PICKED_UP)
└─ After grace period: Reservation becomes terminal (excluded from ongoing list)

Why Asymmetric?

  • Dropoff: Delayed state transition ensures the driver has successfully placed the package before marking as dropped off
  • Pickup: Immediate state transition because opening the door means the consumer has accessed the package

🔧 Minor Improvements

  • Documentation fix: Fixed typo "not exhausted" → "non-exhaustive" in machine cell descriptions
  • Consistency: Updated "vot recommended" → "VoT recommended" in webhook messages

📍 Affected Endpoints

  • New: GET /api/delivery/external/v1/reservations - List ongoing reservations
  • Enhanced: POST /api/delivery/external/v1/reservations - Now returns request_id field
  • Enhanced: GET /api/delivery/external/v1/reservations/{reservation_id} - Now returns request_id field
  • Enhanced: GET /api/delivery/external/v1/machines/{machine_id} and POST /api/delivery/external/v1/machines/search - Now return all_cells and occupancy_information

📚 New Data Structures

  • ListOngoingReservationsRequest: Request with pagination and filtering
    • page_size (optional, default: 100, max: 1000)
    • page_token (optional, for pagination)
    • created_after (optional, unix timestamp for filtering)
  • ListOngoingReservationsResponse: Response with reservation list and pagination
    • reservations (array of ReservationInfo)
    • next_page_token (for pagination)
    • total_count (approximate total)
  • ReservationInfo: Lightweight reservation view
    • reservation_id, machine_id, platform_order_id
    • status, created_at, dropped_off_at, picked_up_at
    • cell (optional, only after drop-off)
  • OccupancyStatus: Enum for machine occupancy levels
    • OCCUPANCY_STATUS_LOW (1): ≤30%
    • OCCUPANCY_STATUS_MEDIUM (2): 31-70%
    • OCCUPANCY_STATUS_HIGH (3): >70%
    • OCCUPANCY_STATUS_OVERLOADED (4): >95%
  • PickUpFailedEvent: Webhook event for failed pickups
    • source_type, request_id, cell, machine, error_message

Version 1.0.236 (2025-07-10)

✅ New Features

  • GetReservation Endpoint: Added new endpoint to retrieve reservation details
    • Endpoint: GET /api/delivery/external/v1/reservations/{reservation_id}
    • Purpose: Allows platforms to query the current status and all information about a reservation
    • Response: Returns comprehensive reservation details including status, timestamps, codes, and cell information

🔄 Changed

  • Error Response Schema: Updated error response reference from ErrorResponse to #/definitions/rpcStatus
    • Impact: Error responses now follow the standard gRPC status format
    • Action Required: Update error handling to parse the new error format

📍 Affected Endpoints

  • New: GET /api/delivery/external/v1/reservations/{reservation_id}
  • Modified: All endpoints now return errors using the rpcStatus schema

📚 New Data Structures

  • GetReservationRequest: Request structure for retrieving reservation details
  • GetReservationResponse: Comprehensive response with all reservation information including:
    • Reservation status enum (PENDING, DROPPED_OFF, PICKED_UP, CANCELLED, ABANDONED)
    • Machine details
    • All timestamps (created, dropped off, picked up, cancelled, abandoned)
    • Drop-off and pickup access codes with QR codes
    • Assigned cell information (after drop-off)

Version 1.0.227 (2025-06-17)

🔄 Changed

  • Internal improvements and optimizations
  • No breaking changes or new features

Version 1.0.226 (2025-06-13)

🔄 Changed

  • QR Code URLs Domain Update: Updated QR code URLs from vendingontrack.com to kioskforce.com
    • Drop-off QR Code URLs: Now use https://api.delivery.kioskforce.com/qrcode/{code} (production) or https://api-staging.delivery.kioskforce.com/qrcode/{code} (staging/dev)
    • Pickup QR Code URLs: Now use https://api.delivery.kioskforce.com/qrcode/{code} (production) or https://api-staging.delivery.kioskforce.com/qrcode/{code} (staging/dev)
    • Impact: Existing QR codes will continue to work, but new reservations will receive updated URLs
    • Action Required: Update any hardcoded domain references in your applications

📍 Affected Endpoints

  • POST /api/delivery/external/v1/reservations - ReserveCell response includes updated QR code URLs
  • Webhook events for reservation creation now include updated QR code URLs

Version 1.0.225 (2025-06-13)

✅ Stable Features

  • Complete delivery locker reservation workflow
  • Machine search with location and packaging filters
  • Drop-off and pickup operations via API or physical codes
  • Real-time webhook notifications for delivery events
  • Support for both numeric codes and QR codes

🛠 Core Endpoints

  • Echo: POST /api/delivery/external/v1/echo
  • Search Machines: POST /api/delivery/external/v1/machines/search
  • Get Machine: GET /api/delivery/external/v1/machines/{machine_id}
  • Reserve Cell: POST /api/delivery/external/v1/reservations
  • Drop Off: POST /api/delivery/external/v1/reservations/{reservation_id}/dropoffs
  • Pick Up: POST /api/delivery/external/v1/reservations/{reservation_id}/pickups
  • Cancel Reservation: POST /api/delivery/external/v1/reservations/{reservation_id}/deletes
  • Abandon Pickup: POST /api/delivery/external/v1/reservations/{reservation_id}/abandons

🔗 Webhook Events

  • EVENT_TYPE_RESERVATION_CREATED - When a cell is reserved
  • EVENT_TYPE_DROPOFF - When a package is dropped off
  • EVENT_TYPE_PICKUP - When a package is picked up
  • EVENT_TYPE_RESERVATION_CANCELLED - When a reservation is cancelled

Migration Notes

Upgrading to v1.0.236

New GetReservation Endpoint

The new endpoint allows you to retrieve reservation details at any time:

GET /api/delivery/external/v1/reservations/{reservation_id}

Example response:

{
"reservation_id": "RES123456",
"machine_id": "MACH001",
"machine": { /* machine details */ },
"platform_order_id": "ORDER789",
"status": "RESERVATION_STATUS_DROPPED_OFF",
"created_at": "2025-07-10T10:00:00Z",
"drop_off_code": "1234",
"pickup_code": "5678",
"cell": { /* cell details if dropped off */ },
"dropped_off_at": "2025-07-10T10:30:00Z"
}

Error Response Format Change

Update your error handling to parse the new rpcStatus format:

Before (v1.0.227):

{
"error": "Invalid request",
"message": "Missing required field"
}

After (v1.0.236):

{
"code": 3,
"message": "Missing required field: reservation_id",
"details": []
}

Upgrading to v1.0.226

No breaking changes. The domain update is backward compatible:

  1. Existing QR codes from v1.0.225 will continue to work
  2. New reservations will receive updated QR code URLs with the new domain
  3. Webhook payloads will include the new QR code URLs for new events
  4. Update any hardcoded URLs in your application to use the new domain

Example Migration

Before (v1.0.225):

{
"drop_off_qrcode_url": "https://api.delivery.vendingontrack.com/qrcode/ABC123",
"pickup_code_qrcode_url": "https://api.delivery.vendingontrack.com/qrcode/DEF456"
}

After (v1.0.226):

{
"drop_off_qrcode_url": "https://api.delivery.kioskforce.com/qrcode/ABC123",
"pickup_code_qrcode_url": "https://api.delivery.kioskforce.com/qrcode/DEF456"
}

Staying Updated

  • API Changes: Subscribe to our developer newsletter for API updates
  • Documentation: This changelog is updated with each API release
  • Support: Contact api-support@kioskforce.com for migration assistance

Version History

VersionRelease DateKey Changes
1.0.2992026-01-23Breaking: Webhook payload structure overhaul - flat proto format, new event type values, X-Platform-Order-Id header
1.0.2882025-11-13RequestMaintenance and OpenDoor endpoints, cell_id field, OpenDoor fulfilled webhooks, enhanced grace period docs
1.0.2832025-11-11ListOngoingReservations endpoint, machine occupancy tracking, pickup failed webhooks, request ID tracing
1.0.2362025-07-10New GetReservation endpoint, updated error response schema
1.0.2272025-06-17Internal improvements
1.0.2262025-06-13QR code domain update to kioskforce.com
1.0.2252025-06-13Stable API release