# ShipStation Integration REST API Documentation ## Table of Contents 1. [Overview](#overview) 2. [Getting Started](#getting-started) 3. [Authentication](#authentication) 4. [Rate Limiting](#rate-limiting) 5. [Error Handling](#error-handling) 6. [API Endpoints](#api-endpoints) 7. [Data Models](#data-models) 8. [Examples](#examples) 9. [SDKs and Libraries](#sdks-and-libraries) 10. [Support](#support) --- ## Overview The ShipStation Integration REST API provides programmatic access to order management and shipping label generation through ShipStation. This API enables third-party applications to create orders, manage shipping, and track packages with enterprise-grade security and reliability. ### Base URL ``` Production: https://your-domain.com/api/v1 Development: http://localhost:5000/api/v1 ``` ### API Version Current Version: **v1.0.0** ### Data Format - **Request Format**: JSON - **Response Format**: JSON - **Date Format**: ISO 8601 (`2024-01-15T10:30:00`) - **Charset**: UTF-8 --- ## Getting Started ### 1. Create a User Account Contact your system administrator to create a user account and obtain API credentials. ### 2. Generate API Key ```bash curl -X POST https://your-domain.com/api/v1/auth/api-keys \ -H "Authorization: Bearer YOUR_INITIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "My Application API Key", "rate_limit_tier": "standard", "expires_in_days": 90 }' ``` ### 3. Test Connection ```bash curl -X GET https://your-domain.com/api/v1/health \ -H "Authorization: Bearer YOUR_API_KEY" ``` --- ## Authentication ### API Key Authentication All API requests must include an API key in the Authorization header: ``` Authorization: Bearer sk_your_api_key_here ``` ### API Key Tiers | Tier | Requests/Hour | Requests/Minute | Description | |------|---------------|-----------------|-------------| | **Standard** | 100 | 10 | Default tier for most applications | | **Premium** | 500 | 25 | For high-volume applications | | **Admin** | 1000 | 50 | Administrative access | ### Security Features - **API keys are hashed** using SHA-256 before storage - **Automatic key expiration** (configurable) - **Usage tracking** for monitoring and analytics - **IP-based rate limiting** fallback for unauthenticated requests --- ## Rate Limiting ### Limits by Tier Rate limits are enforced per API key and reset every hour/minute. ### Rate Limit Headers All responses include rate limit information: ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1641398400 ``` ### Rate Limit Exceeded Response ```json { "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Rate limit exceeded. Please try again later.", "retry_after": 60, "limit": 100, "remaining": 0, "reset_time": "2024-01-15T11:00:00Z" } } ``` --- ## Error Handling ### Standard Error Response Format ```json { "success": false, "error": { "code": "ERROR_CODE", "message": "Human-readable error message", "details": "Additional error details", "timestamp": "2024-01-15T10:30:00Z", "request_id": "req_12345678" } } ``` ### HTTP Status Codes | Code | Meaning | Description | |------|---------|-------------| | **200** | OK | Request successful | | **201** | Created | Resource created successfully | | **400** | Bad Request | Invalid request format | | **401** | Unauthorized | Missing or invalid API key | | **403** | Forbidden | Insufficient permissions | | **404** | Not Found | Resource not found | | **422** | Unprocessable Entity | Validation failed | | **429** | Too Many Requests | Rate limit exceeded | | **500** | Internal Server Error | Server error | | **502** | Bad Gateway | External service unavailable | ### Common Error Codes | Code | Description | |------|-------------| | `VALIDATION_ERROR` | Request data validation failed | | `UNAUTHORIZED` | Authentication required | | `FORBIDDEN` | Access denied | | `NOT_FOUND` | Resource not found | | `RATE_LIMIT_EXCEEDED` | Rate limit exceeded | | `SHIPSTATION_API_ERROR` | ShipStation API error | | `INTERNAL_ERROR` | Unexpected server error | --- ## API Endpoints ### Authentication Endpoints #### Create User ```http POST /api/v1/auth/users ``` **Request Body:** ```json { "email": "user@company.com", "company": "Company Name", "is_admin": false } ``` **Response:** ```json { "success": true, "data": { "id": 1, "email": "user@company.com", "company": "Company Name", "is_active": true, "is_admin": false, "created_at": "2024-01-15T10:30:00Z" } } ``` #### Create API Key ```http POST /api/v1/auth/api-keys ``` *Requires Authentication* **Request Body:** ```json { "name": "My API Key", "rate_limit_tier": "standard", "expires_in_days": 90 } ``` **Response:** ```json { "success": true, "data": { "api_key": "sk_7WVk17PjvPYEqNAQ575tJ00XAUgis5fs", "key_info": { "id": 1, "name": "My API Key", "key_prefix": "sk_7WVk1", "rate_limit_tier": "standard", "expires_at": "2024-04-15T10:30:00Z", "created_at": "2024-01-15T10:30:00Z" } } } ``` #### Get Current User ```http GET /api/v1/auth/me ``` *Requires Authentication* **Response:** ```json { "success": true, "data": { "user": { "id": 1, "email": "user@company.com", "company": "Company Name", "is_active": true, "is_admin": false }, "rate_limits": { "per_hour": 100, "per_minute": 10 } } } ``` ### Order Management Endpoints #### Create Order ```http POST /api/v1/orders ``` *Requires Authentication* **Request Body:** ```json { "orderNumber": "ORDER-001", "orderDate": "2024-01-15T10:30:00", "orderStatus": "awaiting_shipment", "customerEmail": "customer@example.com", "shipTo": { "name": "John Doe", "company": "Customer Company", "street1": "123 Main Street", "street2": "Suite 100", "city": "Toronto", "state": "ON", "postalCode": "M5V 3A8", "country": "CA", "phone": "416-555-1234", "residential": true }, "billTo": { "name": "John Doe", "street1": "123 Billing Street", "city": "Toronto", "state": "ON", "postalCode": "M5V 3A8", "country": "CA" }, "weight": { "value": 1.5, "units": "pounds" }, "dimensions": { "length": 10.0, "width": 8.0, "height": 4.0, "units": "inches" }, "items": [ { "sku": "PRODUCT-001", "name": "Premium Widget", "quantity": 2, "unitPrice": 29.99, "weight": { "value": 0.5, "units": "pounds" } } ], "requestedShippingService": "Wizmo Canada Express", "internationalOptions": { "contents": "merchandise", "customsItems": null } } ``` **Response:** ```json { "success": true, "data": { "id": 1, "orderNumber": "ORDER-001", "orderKey": "order_key_12345", "orderDate": "2024-01-15T10:30:00", "orderStatus": "awaiting_shipment", "customerEmail": "customer@example.com", "shipstationOrderId": 12345, "trackingNumber": null, "trackingLink": null, "totalValue": 59.98, "createdAt": "2024-01-15T10:30:00Z", "updatedAt": "2024-01-15T10:30:00Z" } } ``` #### List Orders ```http GET /api/v1/orders?page=1&per_page=20&status=awaiting_shipment ``` *Requires Authentication* **Query Parameters:** | Parameter | Type | Description | Default | |-----------|------|-------------|---------| | `page` | integer | Page number | 1 | | `per_page` | integer | Items per page (1-100) | 20 | | `status` | string | Filter by order status | - | | `customer_email` | string | Filter by customer email | - | | `order_number` | string | Filter by order number | - | | `date_from` | date | Filter orders from date | - | | `date_to` | date | Filter orders to date | - | **Response:** ```json { "success": true, "data": { "orders": [ { "id": 1, "orderNumber": "ORDER-001", "orderDate": "2024-01-15T10:30:00", "customerEmail": "customer@example.com", "orderStatus": "awaiting_shipment", "totalValue": 59.98 } ], "pagination": { "page": 1, "per_page": 20, "total": 1, "pages": 1, "has_next": false, "has_prev": false } } } ``` #### Get Order ```http GET /api/v1/orders/{order_id} ``` *Requires Authentication* #### Update Order ```http PUT /api/v1/orders/{order_id} ``` *Requires Authentication* #### Delete Order ```http DELETE /api/v1/orders/{order_id} ``` *Requires Authentication* #### Create Shipping Label ```http POST /api/v1/orders/{order_id}/label ``` *Requires Authentication* **Request Body (Optional):** ```json { "carrierCode": "wizmo", "serviceCode": "canada_zone_skip_express" } ``` **Response:** ```json { "success": true, "data": { "labelData": "base64_encoded_pdf_label", "trackingNumber": "1Z999AA1234567890", "trackingLink": "https://tools.usps.com/go/TrackConfirmAction?tLabels=1Z999AA1234567890" } } ``` ### System Endpoints #### Health Check ```http GET /api/v1/health ``` **Response:** ```json { "success": true, "data": { "status": "healthy", "timestamp": "2024-01-15T10:30:00Z", "version": "v1.0.0", "service": "ShipStation Integration API" } } ``` #### Detailed Health Check ```http GET /api/v1/health/detailed ``` **Response:** ```json { "success": true, "data": { "status": "healthy", "timestamp": "2024-01-15T10:30:00Z", "version": "v1.0.0", "components": { "database": { "status": "healthy", "message": "Database connection successful" }, "shipstation_api": { "status": "healthy", "message": "ShipStation API connection successful" } } } } ``` #### Version Information ```http GET /api/v1/version ``` --- ## Data Models ### Address Model ```json { "name": "string (required, max 100)", "company": "string (optional, max 100)", "street1": "string (required, max 100)", "street2": "string (optional, max 100)", "street3": "string (optional, max 100)", "city": "string (required, max 50)", "state": "string (required, max 50)", "postalCode": "string (required, max 20)", "country": "string (required, 2-letter ISO code)", "phone": "string (optional, max 20)", "residential": "boolean (default: true)" } ``` ### Weight Model ```json { "value": "number (required, min 0.01, max 1000)", "units": "string (required: 'pounds', 'ounces', 'grams', 'kilograms')" } ``` ### Dimensions Model ```json { "length": "number (required, min 0.1, max 300)", "width": "number (required, min 0.1, max 300)", "height": "number (required, min 0.1, max 300)", "units": "string (required: 'inches', 'centimeters')" } ``` ### Order Item Model ```json { "lineItemKey": "string (optional, max 50)", "sku": "string (required, max 50)", "name": "string (required, max 200)", "quantity": "integer (required, min 1, max 1000)", "unitPrice": "number (required, min 0, max 10000)", "weight": "Weight (optional)", "productId": "string (optional, max 50)", "fulfillmentSku": "string (optional, max 50)" } ``` --- ## Examples ### Complete Order Creation Example ```javascript const orderData = { orderNumber: "WEB-" + Date.now(), orderDate: new Date().toISOString(), customerEmail: "customer@example.com", shipTo: { name: "Jane Smith", company: "Smith Industries", street1: "456 Oak Avenue", city: "Vancouver", state: "BC", postalCode: "V6B 1A1", country: "CA", phone: "604-555-9876", residential: false }, weight: { value: 2.5, units: "pounds" }, dimensions: { length: 12.0, width: 10.0, height: 6.0, units: "inches" }, items: [ { sku: "WIDGET-PRO", name: "Professional Widget", quantity: 1, unitPrice: 149.99, weight: { value: 2.0, units: "pounds" } }, { sku: "MANUAL-001", name: "User Manual", quantity: 1, unitPrice: 9.99, weight: { value: 0.5, units: "pounds" } } ], requestedShippingService: "Wizmo Canada Express" }; // Create order const response = await fetch('https://your-domain.com/api/v1/orders', { method: 'POST', headers: { 'Authorization': 'Bearer sk_your_api_key_here', 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }); const result = await response.json(); if (result.success) { console.log('Order created:', result.data); // Create shipping label const labelResponse = await fetch(`https://your-domain.com/api/v1/orders/${result.data.id}/label`, { method: 'POST', headers: { 'Authorization': 'Bearer sk_your_api_key_here', 'Content-Type': 'application/json' } }); const labelResult = await labelResponse.json(); if (labelResult.success) { console.log('Label created:', labelResult.data.trackingNumber); } } ``` ### Python SDK Example ```python import requests import json class ShipStationAPI: def __init__(self, api_key, base_url="https://your-domain.com/api/v1"): self.api_key = api_key self.base_url = base_url self.headers = { 'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json' } def create_order(self, order_data): response = requests.post( f"{self.base_url}/orders", headers=self.headers, json=order_data ) return response.json() def get_orders(self, page=1, per_page=20, **filters): params = {'page': page, 'per_page': per_page, **filters} response = requests.get( f"{self.base_url}/orders", headers=self.headers, params=params ) return response.json() def create_label(self, order_id, carrier_code=None, service_code=None): data = {} if carrier_code: data['carrierCode'] = carrier_code if service_code: data['serviceCode'] = service_code response = requests.post( f"{self.base_url}/orders/{order_id}/label", headers=self.headers, json=data if data else None ) return response.json() # Usage api = ShipStationAPI('sk_your_api_key_here') order = { "orderNumber": "PYTHON-001", "orderDate": "2024-01-15T10:30:00", "customerEmail": "python@example.com", "shipTo": { "name": "Python User", "street1": "123 Code Street", "city": "Toronto", "state": "ON", "postalCode": "M5V 3A8", "country": "CA" }, "weight": {"value": 1.0, "units": "pounds"}, "dimensions": {"length": 10, "width": 8, "height": 4, "units": "inches"}, "items": [{ "sku": "PY-WIDGET", "name": "Python Widget", "quantity": 1, "unitPrice": 25.99 }] } result = api.create_order(order) print(f"Order created: {result}") ``` --- ## SDKs and Libraries ### Official SDKs - **Python SDK**: `pip install shipstation-api-sdk` *(Coming Soon)* - **JavaScript SDK**: `npm install shipstation-api-sdk` *(Coming Soon)* - **PHP SDK**: `composer require shipstation/api-sdk` *(Coming Soon)* ### Community Libraries - Submit your library to be listed here! --- ## Support ### API Status Monitor API status and uptime: [Status Page] *(Configure your status page)* ### Rate Limit Guidelines - **Implement exponential backoff** for rate limit errors - **Cache responses** when possible to reduce API calls - **Use webhooks** for real-time updates (when available) ### Best Practices 1. **Always validate input** before sending to API 2. **Handle errors gracefully** with proper retry logic 3. **Store API keys securely** (never in client-side code) 4. **Use HTTPS** for all requests 5. **Monitor your API usage** to avoid rate limits ### Contact Support - **Email**: api-support@your-domain.com - **Documentation Issues**: Create an issue in the GitHub repository - **Feature Requests**: Submit via support email ### Changelog - **v1.0.0** (2024-01-15): Initial API release - Order management endpoints - API key authentication - Rate limiting - ShipStation integration --- *Last updated: September 03, 2025* *API Version: v1.0.0*