This guide walks you through creating your first sales order using the Wineshipping API. We recommend following this four-step workflow: discover inventory, test the payload, integrate with your software, then monitor the shipment.
Before creating an order, use the GetSellable endpoint to find available items and quantities.
{
"Authentication": {
"UserKey": "YOUR_USER_KEY",
"Password": "YOUR_PASSWORD",
"CustomerNo": "YOUR_CUSTOMER_NUMBER"
},
"Warehouses": ["APC01"]
}{
"TotalRecordCount": 145,
"SalesChannel": "DTC",
"Items": [
{
"ItemNo": "1466-SE",
"ItemDescription": "2016 CAB SAUV RESERVE NAPA VALLEY",
"ItemUnit": "bottle",
"SellableQuantity": 1250
},
{
"ItemNo": "A37B693E",
"ItemDescription": "Pinot Noir 2020",
"ItemUnit": "bottle",
"SellableQuantity": 450
},
{
"ItemNo": "5C7D8E9F",
"ItemDescription": "Chardonnay 2019 - Case",
"ItemUnit": "case",
"SellableQuantity": 12
}
]
}Key Takeaways:
- Note the
ItemNofor each product you want to include in your order - Verify
SellableQuantityis sufficient for your order - Pay attention to
ItemUnit(bottle, case, etc.) to match your order quantities
Before integrating with your application, test your order payload using Redocly Console, Postman, or curl.
Use this as your starting point:
{
"Authentication": {
"UserKey": "YOUR_USER_KEY",
"Password": "YOUR_PASSWORD",
"CustomerNo": "YOUR_CUSTOMER_NUMBER"
},
"OrderInfo": {
"OrderNo": "MYORDER-001",
"OrderDate": "2026-01-15T10:30:00Z",
"OrderType": "RETAIL"
},
"RecipientContactInfo": {
"FirstName": "John",
"LastName": "Doe",
"Address": "123 Main St",
"City": "Napa",
"State": "CA",
"ZipCode": "94558",
"Country": "US",
"PhoneNumber": "7071234567",
"EmailAddress": "customer@example.com"
},
"ShipmentInfo": {
"ShippingCarrier": "FEX",
"ShippingCarrierService": "GRND",
"RequestedShipmentDate": "01/20/2026",
"WineshippingWarehouseLocation": "APC01"
},
"ItemsInfo": [
{
"ItemNo": "1466-SE",
"ItemDescription": "2016 CAB SAUV RESERVE NAPA VALLEY",
"ItemQuantity": 6
}
]
}- Open the API Reference
- Navigate to Fulfillment > Create Sales Order
- Click the Try It Out button
- Select the "Quick Start" example or paste your payload
- Replace authentication credentials with your test credentials
- Click Execute
- Open your Postman workspace
- Create a new POST request to:
https://api-test.wineshipping.com/v3/api/SalesOrder/CreateSalesOrder - Set Content-Type header to
application/json - Paste the payload in the request body
- Click Send
curl -X POST https://api-test.wineshipping.com/v3/api/SalesOrder/CreateSalesOrder \
-H "Content-Type: application/json" \
-d '{
"Authentication": {
"UserKey": "YOUR_USER_KEY",
"Password": "YOUR_PASSWORD",
"CustomerNo": "YOUR_CUSTOMER_NUMBER"
},
"OrderInfo": {
"OrderNo": "MYORDER-001",
"OrderDate": "2026-01-15T10:30:00Z",
"OrderType": "DTC"
},
"RecipientContactInfo": {
"FirstName": "John",
"LastName": "Doe",
"Address": "123 Main St",
"City": "Napa",
"State": "CA",
"ZipCode": "94558",
"Country": "US",
"PhoneNumber": "7071234567",
"EmailAddress": "customer@example.com"
},
"ShipmentInfo": {
"ShippingCarrier": "FEX",
"ShippingCarrierService": "GRND",
"RequestedShipmentDate": "01/20/2026",
"WineshippingWarehouseLocation": "APC01"
},
"ItemsInfo": [
{
"ItemNo": "1466-SE",
"ItemDescription": "2016 CAB SAUV RESERVE NAPA VALLEY",
"ItemQuantity": 6
}
]
}'A successful request returns HTTP 201 with a transaction reference ID:
"D94BC05C-A1C3-4CBB-8DA1-E59C73AD2CAE"Store this ID! Use it to track the order and troubleshoot any issues.
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid credentials | Verify UserKey, Password, and CustomerNo |
400 Bad Request | Missing/invalid required fields | Check all required fields are populated and formatted correctly |
429 Too Many Requests | Rate limit exceeded | Wait before retrying; use webhooks instead of polling GetDetails for tracking updates |
| Order rejected | ItemNo unavailable or address invalid | Use GetSellable to verify items; validate address format |
Once your payload is verified in the console, integrate the request into your application using your preferred HTTP client library.
import requests
import json
from datetime import datetime
def create_sales_order(item_no, quantity):
url = "https://api-test.wineshipping.com/v3/api/SalesOrder/CreateSalesOrder"
payload = {
"Authentication": {
"UserKey": "YOUR_USER_KEY",
"Password": "YOUR_PASSWORD",
"CustomerNo": "YOUR_CUSTOMER_NUMBER"
},
"OrderInfo": {
"OrderNo": f"ORDER-{datetime.now().timestamp()}",
"OrderDate": datetime.utcnow().isoformat() + "Z",
"OrderType": "DTC",
"WineshippingWarehouseLocation": "APC01"
},
"RecipientContactInfo": {
"FirstName": "John",
"LastName": "Doe",
"Address": "123 Main St",
"City": "Napa",
"State": "CA",
"ZipCode": "94558",
"Country": "US",
"PhoneNumber": "7071234567",
"EmailAddress": "customer@example.com"
},
"ShipmentInfo": {
"ShippingCarrier": "FEX",
"ShippingCarrierService": "GRND",
"RequestedShipmentDate": "01/20/2026"
},
"ItemsInfo": [
{
"ItemNo": item_no,
"ItemQuantity": quantity
}
]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 201:
transaction_id = response.json()
print(f"Order created successfully. Transaction ID: {transaction_id}")
return transaction_id
else:
print(f"Error: {response.status_code} - {response.text}")
return None
# Usage
create_sales_order("1466-SE", 6)async function createSalesOrder(itemNo: string, quantity: number): Promise<string | null> {
const url = "https://api-test.wineshipping.com/v3/api/SalesOrder/CreateSalesOrder";
const payload = {
Authentication: {
UserKey: "YOUR_USER_KEY",
Password: "YOUR_PASSWORD",
CustomerNo: "YOUR_CUSTOMER_NUMBER"
},
OrderInfo: {
OrderNo: `ORDER-${Date.now()}`,
OrderDate: new Date().toISOString(),
OrderType: "DTC",
WineshippingWarehouseLocation: "APC01"
},
RecipientContactInfo: {
FirstName: "John",
LastName: "Doe",
Address: "123 Main St",
City: "Napa",
State: "CA",
ZipCode: "94558",
Country: "US",
PhoneNumber: "7071234567",
EmailAddress: "customer@example.com"
},
ShipmentInfo: {
ShippingCarrier: "FEX",
ShippingCarrierService: "GRND",
RequestedShipmentDate: "01/20/2026"
},
ItemsInfo: [
{
ItemNo: itemNo,
ItemQuantity: quantity
}
]
};
try {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
if (response.status === 201) {
const transactionId = await response.json();
console.log(`Order created successfully. Transaction ID: ${transactionId}`);
return transactionId;
} else {
console.error(`Error: ${response.status} - ${response.statusText}`);
return null;
}
} catch (error) {
console.error("Request failed:", error);
return null;
}
}
// Usage
createSalesOrder("1466-SE", 6);using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class WineshippingOrderService
{
private readonly HttpClient _httpClient;
private const string ApiUrl = "https://api-test.wineshipping.com/v3/api/SalesOrder/CreateSalesOrder";
public WineshippingOrderService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<string> CreateSalesOrderAsync(string itemNo, int quantity)
{
var payload = new
{
Authentication = new
{
UserKey = "YOUR_USER_KEY",
Password = "YOUR_PASSWORD",
CustomerNo = "YOUR_CUSTOMER_NUMBER"
},
OrderInfo = new
{
OrderNo = $"ORDER-{DateTime.UtcNow.Ticks}",
OrderDate = DateTime.UtcNow.ToString("o"),
OrderType = "DTC",
WineshippingWarehouseLocation = "APC01"
},
RecipientContactInfo = new
{
FirstName = "John",
LastName = "Doe",
Address = "123 Main St",
City = "Napa",
State = "CA",
ZipCode = "94558",
Country = "US",
PhoneNumber = "7071234567",
EmailAddress = "customer@example.com"
},
ShipmentInfo = new
{
ShippingCarrier = "FEX",
ShippingCarrierService = "GRND",
RequestedShipmentDate = "01/20/2026"
},
ItemsInfo = new[]
{
new
{
ItemNo = itemNo,
ItemQuantity = quantity
}
}
};
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(ApiUrl, content);
if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
var responseContent = await response.Content.ReadAsStringAsync();
var transactionId = JsonSerializer.Deserialize<string>(responseContent);
Console.WriteLine($"Order created successfully. Transaction ID: {transactionId}");
return transactionId;
}
else
{
var errorContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Error: {response.StatusCode} - {errorContent}");
return null;
}
}
}
public static class Program
{
public static async Task Main()
{
using var httpClient = new HttpClient();
var service = new WineshippingOrderService(httpClient);
await service.CreateSalesOrderAsync("1466-SE", 6);
}
}After creating an order, track its status using webhooks (recommended) or the GetDetails API.
For the best experience and to avoid rate limiting, use event-driven tracking via webhooks instead of polling.
Set up webhooks to receive real-time updates on:
- Order fulfillment status
- Package tracking events
- Carrier updates
- Delivery estimates
curl -X POST https://api-test.wineshipping.com/v3/api/Tracking/GetDetails \
-H "Content-Type: application/json" \
-d '{
"AuthenticationDetails": {
"UserKey": "YOUR_USER_KEY",
"Password": "YOUR_PASSWORD",
"CustomerNo": "YOUR_CUSTOMER_NUMBER"
},
"OrderNo": "MYORDER-001"
}'- Explore more examples: Check out the full CreateSalesOrder examples for advanced scenarios (international orders, multiple items, etc.)
- Set up webhooks: Configure Event-Driven Tracking for real-time updates
- Handle errors: Review common error codes in Codes & Descriptions
- Manage orders: Learn how to update or cancel orders
- Inventory management: Use GetInventoryStatus for detailed inventory information
For issues or questions:
- Email: api@wineshipping.com
- API Reference: Full specification
- Infrastructure: Learn about environments and rate limits