API Reference
Vectis provides a REST API for all operations. 20+ public endpoints, OpenAPI 3.1 documented, with HMAC-signed webhooks.
Base URL
API requests use your tenant subdomain:
https://{tenant}.vectisoms.app/api
Authentication
All API requests require a Bearer token in the Authorization header.
Obtaining a Token
Request an access token from the OAuth endpoint:
curl -X POST https://api.vectisoms.app/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
Making Requests
curl https://acme.vectisoms.app/api/orders \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Generate client credentials from Settings → API Access in your Vectis dashboard.
Common Endpoints
Orders
| Method | Endpoint | Description |
|---|---|---|
GET | /orders | List orders with filtering and pagination |
GET | /orders/:id | Get order details |
POST | /orders | Create an order |
PATCH | /orders/:id | Update order |
POST | /orders/:id/cancel | Cancel order |
POST | /orders/:id/allocate | Allocate inventory |
POST | /orders/:id/ship | Mark as shipped |
Inventory
| Method | Endpoint | Description |
|---|---|---|
GET | /inventory | List inventory by warehouse/product |
PATCH | /inventory/:id/adjust | Adjust quantity with reason code |
POST | /inventory/transfer | Transfer between locations |
POST | /inventory/:id/reserve | Reserve for an order |
POST | /inventory/:id/release | Release reservation |
Products
| Method | Endpoint | Description |
|---|---|---|
GET | /products | List products |
GET | /products/:id | Get product details |
POST | /products | Create product |
PATCH | /products/:id | Update product |
DELETE | /products/:id | Delete product |
Packages
| Method | Endpoint | Description |
|---|---|---|
GET | /packages | List packages |
GET | /packages/:id | Get package details |
POST | /packages/:id/ship | Generate label and ship |
GET | /packages/:id/label | Download shipping label |
Warehouses
| Method | Endpoint | Description |
|---|---|---|
GET | /warehouses | List warehouses |
GET | /warehouses/:id | Get warehouse details |
POST | /warehouses | Create warehouse |
PATCH | /warehouses/:id | Update warehouse |
Request Format
All requests use JSON:
POST /api/orders
Content-Type: application/json
Authorization: Bearer <access_token>
{
"externalId": "SHOP-12345",
"customerId": "cust_john123",
"customerEmail": "john@example.com",
"items": [
{ "sku": "WIDGET-BLU", "quantity": 2, "unitPrice": 29.99 },
{ "sku": "GADGET-RED", "quantity": 1, "unitPrice": 49.99 }
],
"shippingAddresses": [{
"name": "John Doe",
"line1": "123 Main St",
"city": "Phoenix",
"region": "AZ",
"postalCode": "85001",
"country": "US"
}],
"billingAddress": {
"name": "John Doe",
"line1": "123 Main St",
"city": "Phoenix",
"region": "AZ",
"postalCode": "85001",
"country": "US"
}
}
Response Format
Successful responses return JSON with the resource:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"total": 109.97,
"itemCount": 3,
"createdAt": "2026-01-15T10:30:00Z"
}
Errors return a consistent format:
{
"error": {
"code": "validation_error",
"message": "Invalid SKU: WIDGET-BLU not found",
"field": "items[0].sku"
}
}
Pagination
List endpoints support pagination:
GET /api/orders?limit=50&offset=0
Response includes pagination metadata:
{
"orders": [...],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1234
}
}
Filtering
Filter by query parameters:
GET /api/orders?status=pending&q=SHOP-12345&fromDate=2026-01-01
Webhooks
Configure webhooks in Settings → Webhooks. All webhooks are signed with HMAC-SHA256.
Verifying Signatures
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Event Types
order.createdorder.updatedorder.cancelledorder.shippedpackage.createdpackage.shippedpackage.deliveredinventory.adjustedinventory.low_stock
Rate Limits
- Standard: 100 requests/minute
- Burst: 200 requests/minute (short bursts allowed)
Rate limit headers included in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
Idempotency
For POST requests, include an idempotency key:
Idempotency-Key: unique-request-id-12345
Duplicate requests with the same key return the original response.
OpenAPI Specification
Full OpenAPI 3.1 spec available at:
https://api.vectisoms.app/v1/openapi.json
Interactive Swagger UI at:
https://api.vectisoms.app/docs
SDKs
Official SDKs coming soon. For now, use any HTTP client with the REST API.
Support
- API questions: support@stoalogistics.com
- Bug reports: support@stoalogistics.com