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

Where {tenant} is your organization’s subdomain (e.g., acme.vectisoms.app/api).

Authentication

All API requests require a Bearer token in the Authorization header, obtained via OAuth 2.0 client credentials flow.

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

Include the token in the Authorization header:

curl https://acme.vectisoms.app/api/orders \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Generate client credentials from Settings → API Access in your Vectis dashboard. Contact support@stoalogistics.com if you need assistance.

Common Endpoints

Orders

MethodEndpointDescription
GET/api/ordersList orders with filtering and pagination
POST/api/ordersCreate a new order
POST/api/orders/bulk-importBulk import orders (JSON or CSV body)
GET/api/orders/{id}Get order details
PATCH/api/orders/{id}Update order status
POST/api/orders/{id}/cancelCancel an order

Products

MethodEndpointDescription
GET/api/productsList products
POST/api/productsCreate a product
GET/api/products/{id}Get product details
GET/api/products/sku/{sku}Get product by SKU
PATCH/api/products/{id}Update product
DELETE/api/products/{id}Delete product (soft delete)

Inventory

MethodEndpointDescription
GET/api/inventoryList inventory levels
POST/api/inventoryCreate inventory record
GET/api/inventory/{id}Get inventory item
PATCH/api/inventory/{id}/adjustAdjust inventory quantity

Webhooks

MethodEndpointDescription
GET/api/webhooksList webhook subscriptions
POST/api/webhooksCreate webhook subscription
DELETE/api/webhooks/{id}Delete webhook subscription

Inbound Webhooks (WMS & Carriers)

MethodEndpointDescription
POST/api/wms/webhooks/package-statusReceive package status from WMS
POST/api/webhooks/carriers/{carrier}/trackingReceive tracking updates from carriers

System

MethodEndpointDescription
GET/healthSystem health check

Request Format

Most requests use JSON. Bulk order import also accepts CSV; see POST /api/orders/bulk-import in OpenAPI.

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"
  }
}

Addresses

Shipping and billing address objects accept line1 as today, and also street1 as an alias for the same field. Use whichever your upstream system already emits.

Order line items in responses

When present on an order, line items may include cost fields for operations and integrations: unitCost, costCurrency, and lineCost. Treat them as optional; availability can depend on your catalog and tenant configuration.

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

Paginated list responses include limit, offset, and total inside the pagination object so you know how many records match the query, not just the current page.

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.created
  • order.updated
  • order.cancelled
  • order.shipped
  • package.created
  • package.shipped
  • package.delivered
  • inventory.adjusted
  • inventory.low_stock

Rate Limits

Rate limits vary by subscription tier:

TierRequests/MinuteBurst Limit
Starter60100
Growth100200
Pro200400
Enterprise5001000

Rate limit headers are included in all responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
  • X-RateLimit-Limit: Your tier’s per-minute limit
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when the limit resets

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://{tenant}.vectisoms.app/api/openapi.json

Interactive Swagger UI at:

https://{tenant}.vectisoms.app/api/docs

SDKs

Official SDKs coming soon. For now, use any HTTP client with the REST API.

Support