Inbound Deliveries

Inbound Deliveries Guide

This guide explains how to create inbound delivery records for inventory restocking and purchase order processing.

Overview

Inbound deliveries represent shipments arriving at the warehouse. They are used to:

  • Register incoming inventory
  • Process purchase orders
  • Update stock levels
  • Track supplier deliveries

Endpoint

POST /inbound

Full URL: https://api.spreetaileu.com/api/api/v1/inbound

Authentication

Requires Bearer token authentication. See the Authentication Guide for details.

Inbound Delivery Structure

An inbound delivery includes:

  • Delivery Information: Delivery number, received timestamp, status
  • Items: Products with barcodes and quantities
  • Optional Metadata: External references, transport IDs, document numbers

Required Fields

FieldTypeDescription
delivery_numberstringUnique delivery number (must be unique per client)
received_atstring (ISO 8601)When delivery was received (with microseconds: YYYY-MM-DDTHH:mm:ss.ffffff)
itemsarrayAt least one item required (each with barcode and qty)

Example: Complete Inbound Delivery

{
  "delivery_number": "DEL-2025-001",
  "received_at": "2025-10-29T10:00:00.000000",
  "status": "pending",
  "external_delivery_number": "EXT-DEL-001",
  "transport_id": "TRANS-001",
  "docnum": "DOC-001",
  "plant": "1300",
  "items": [
    {
      "barcode": "1234567890123",
      "qty": 100,
      "material": "MAT-001",
      "batch": "BATCH-A-2025",
      "itm_number": "10"
    },
    {
      "barcode": "9876543210987",
      "qty": 50,
      "material": "MAT-002",
      "batch": "BATCH-A-2025",
      "itm_number": "20"
    }
  ]
}

Example: Minimal Inbound Delivery

{
  "delivery_number": "DEL-2025-002",
  "received_at": "2025-10-29T10:00:00.000000",
  "items": [
    {
      "barcode": "5555666677778",
      "qty": 25
    }
  ]
}

Code Examples

Python

import requests
from datetime import datetime

def create_inbound_delivery(access_token, delivery_data):
    """Create an inbound delivery"""
    url = "https://api.spreetaileu.com/api/api/v1/inbound"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, json=delivery_data)
    response.raise_for_status()
    return response.json()

# Example usage
delivery = {
    "delivery_number": f"DEL-{datetime.now().strftime('%Y%m%d-%H%M%S')}",
    "received_at": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f"),
    "status": "pending",
    "items": [{
        "barcode": "1234567890123",
        "qty": 100,
        "material": "MAT-001"
    }]
}

result = create_inbound_delivery(access_token, delivery)
print(f"Inbound delivery created: {result}")

JavaScript/Node.js

async function createInboundDelivery(accessToken, deliveryData) {
  const url = 'https://api.spreetaileu.com/api/api/v1/inbound';
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(deliveryData)
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Inbound delivery creation failed: ${error.error || response.statusText}`);
  }
  
  return await response.json();
}

// Example usage
const delivery = {
  delivery_number: `DEL-${Date.now()}`,
  received_at: new Date().toISOString().replace('Z', '000'),
  status: 'pending',
  items: [{
    barcode: '1234567890123',
    qty: 100,
    material: 'MAT-001'
  }]
};

createInboundDelivery(accessToken, delivery)
  .then(result => console.log('Inbound delivery created:', result))
  .catch(error => console.error('Error:', error));

Response

Success Response (201)

{
  "success": true,
  "message": "Inbound created successfully",
  "data": {
    "delivery_number": "DEL-2025-001",
    "client": "USB",
    "status": "pending",
    "items_count": 2
  }
}

Error Responses

400 Bad Request - Validation error:

{
  "success": false,
  "error": "Missing required field 'delivery_number'"
}

401 Unauthorized - Invalid or expired token:

{
  "success": false,
  "error": "Unauthorized"
}

409 Conflict - Duplicate delivery number:

{
  "success": false,
  "error": "Inbound with delivery_number 'DEL-2025-001' already exists"
}

Important Notes

Delivery Number Uniqueness

  • Delivery numbers must be unique per client
  • If you submit the same delivery number twice, you'll receive a 409 Conflict error
  • Use a consistent format (e.g., DEL-YYYYMMDD-####)

Timestamp Format

The received_at field must be in ISO 8601 format with microseconds:

  • Format: YYYY-MM-DDTHH:mm:ss.ffffff
  • Example: 2025-10-29T10:00:00.000000
  • Note: Include microseconds (6 digits) even if they are zeros

Items Structure

Each item in the items array must have:

  • Required: barcode (string) and qty (integer, minimum: 1)
  • Optional: material (string), batch (string), itm_number (string)

Inventory Impact

  • Creating an inbound delivery will increase inventory levels
  • Items are added to available stock
  • Updates are reflected in inventory queries

Use Cases

1. Register Purchase Order Receipt

def register_po_receipt(access_token, po_number, items):
    """Register receipt of a purchase order"""
    delivery = {
        "delivery_number": f"PO-{po_number}",
        "received_at": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f"),
        "status": "pending",
        "external_delivery_number": po_number,
        "items": items
    }
    return create_inbound_delivery(access_token, delivery)

# Usage
po_items = [
    {
        "barcode": "1234567890123",
        "qty": 100,
        "material": "MAT-001"
    }
]

result = register_po_receipt(access_token, "PO-12345", po_items)

2. Batch Inbound Processing

def process_multiple_deliveries(access_token, deliveries):
    """Process multiple inbound deliveries"""
    results = []
    for delivery in deliveries:
        try:
            result = create_inbound_delivery(access_token, delivery)
            results.append({"success": True, "data": result})
        except Exception as e:
            results.append({"success": False, "error": str(e)})
    return results

Best Practices

  1. Use Descriptive Delivery Numbers: Include PO numbers or supplier references
  2. Include Optional Metadata: Add external_delivery_number, transport_id, etc. for tracking
  3. Validate Before Sending: Check all required fields and formats
  4. Track Delivery Status: Use GET /inbound/{deliveryNumber} to check delivery status
  5. Handle Errors Gracefully: Implement error handling for validation failures
  6. Use Proper Timestamp Format: Ensure received_at includes microseconds

Related Endpoints

  • GET /inbound/{deliveryNumber} - Retrieve inbound delivery details
  • GET /inventory - Check updated inventory levels after delivery