ConsolAIAPI DOCS
Back to app

Getting Started

The ConsolAI API provides programmatic access to your freight consolidation data. You can manage shipments, warehouse receipts, consolidations, customers, documents, and exceptions through a consistent RESTful interface.

All API endpoints are served from:

https://app.consolai.com/api/v1

Requests and responses use JSON. All timestamps are in ISO 8601 format (UTC). IDs are UUIDs.

To get started:

  1. Generate an API key in Settings → API tab
  2. Include the key in the x-api-key header
  3. Make your first request to GET /api/v1/shipments

Authentication

All API requests must include your API key in the x-api-key header. Keys are scoped to your organization -- any request made with a key will only access data belonging to that organization.

Example request
curl https://app.consolai.com/api/v1/shipments \
  -H "x-api-key: ck_your_key_here" \
  -H "Content-Type: application/json"

Generating a key: Navigate to Settings → API in the ConsolAI dashboard. Click Create API Key, give it a name, and copy the key. The key is only shown once -- store it securely.

Key format: Keys are prefixed with ck_ (client key) for standard access or sk_ (server key) for elevated permissions.

Security: Never expose your API key in client-side code. All requests should be made from your server.

Rate Limits

The API enforces a rate limit of 100 requests per minute per API key. When the limit is exceeded, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait before retrying.

Rate limit headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1712345678
429 response
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please retry after the specified time.",
  "retry_after": 23
}

We recommend implementing exponential backoff in your integration. If you need higher limits, contact us at api@consolai.com.

Shipments

Manage ocean freight shipments. Each shipment represents a cargo movement from origin to destination.

GET/api/v1/shipments

List all shipments with pagination and optional filters.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
statusstringNoFilter by status: draft, booked, in_transit, delivered, cancelled
originstringNoFilter by origin port code (e.g., CNSHA)
destinationstringNoFilter by destination port code (e.g., USLAX)
created_afterISO 8601NoFilter shipments created after this date
Response
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "reference": "SHP-2026-001234",
      "status": "in_transit",
      "origin_port": "CNSHA",
      "destination_port": "USLAX",
      "carrier": "MAERSK",
      "vessel": "MARY MAERSK",
      "voyage": "026E",
      "etd": "2026-04-10T00:00:00Z",
      "eta": "2026-04-28T00:00:00Z",
      "pieces": 42,
      "weight_kg": 12500.0,
      "cbm": 38.5,
      "created_at": "2026-03-15T10:30:00Z",
      "updated_at": "2026-04-01T14:22:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 143,
    "total_pages": 6
  }
}
GET/api/v1/shipments/:id

Retrieve a single shipment by ID, including line items and linked documents.

Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "reference": "SHP-2026-001234",
  "status": "in_transit",
  "origin_port": "CNSHA",
  "destination_port": "USLAX",
  "carrier": "MAERSK",
  "vessel": "MARY MAERSK",
  "voyage": "026E",
  "etd": "2026-04-10T00:00:00Z",
  "eta": "2026-04-28T00:00:00Z",
  "pieces": 42,
  "weight_kg": 12500.0,
  "cbm": 38.5,
  "line_items": [
    { "description": "Electronics", "pieces": 20, "weight_kg": 6000, "cbm": 18.0 },
    { "description": "Textiles", "pieces": 22, "weight_kg": 6500, "cbm": 20.5 }
  ],
  "documents": ["doc_abc123", "doc_def456"],
  "created_at": "2026-03-15T10:30:00Z",
  "updated_at": "2026-04-01T14:22:00Z"
}
POST/api/v1/shipments

Create a new shipment.

Request body
{
  "origin_port": "CNSHA",
  "destination_port": "USLAX",
  "carrier": "MAERSK",
  "etd": "2026-05-01T00:00:00Z",
  "eta": "2026-05-20T00:00:00Z",
  "pieces": 30,
  "weight_kg": 8500.0,
  "cbm": 25.0,
  "notes": "Handle with care — fragile electronics"
}
Response
{
  "id": "f8e7d6c5-b4a3-2190-fedc-ba0987654321",
  "reference": "SHP-2026-001235",
  "status": "draft",
  "origin_port": "CNSHA",
  "destination_port": "USLAX",
  "carrier": "MAERSK",
  "etd": "2026-05-01T00:00:00Z",
  "eta": "2026-05-20T00:00:00Z",
  "pieces": 30,
  "weight_kg": 8500.0,
  "cbm": 25.0,
  "created_at": "2026-04-05T09:15:00Z"
}
PATCH/api/v1/shipments/:id

Update an existing shipment. Only provided fields are changed.

Request body
{
  "status": "booked",
  "vessel": "EMMA MAERSK",
  "voyage": "032W"
}
Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "reference": "SHP-2026-001234",
  "status": "booked",
  "vessel": "EMMA MAERSK",
  "voyage": "032W",
  "updated_at": "2026-04-05T09:20:00Z"
}
DELETE/api/v1/shipments/:id

Delete a shipment. Only draft shipments can be deleted.

Response
{
  "success": true,
  "message": "Shipment SHP-2026-001234 has been deleted."
}

Warehouse Receipts

Warehouse receipts (WRs) represent cargo received at a CFS (Container Freight Station). Each WR tracks inbound cargo from a shipper before it is consolidated.

GET/api/v1/warehouse-receipts

List all warehouse receipts with pagination and filtering.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
statusstringNoFilter by status: pending, received, consolidated, shipped
shipperstringNoFilter by shipper name (partial match)
destinationstringNoFilter by destination port code
Response
{
  "data": [
    {
      "id": "wr_01abc234-def5-6789-0abc-def012345678",
      "wr_number": "WR-2026-00542",
      "status": "received",
      "shipper": "Shenzhen Electronics Co.",
      "consignee": "West Coast Imports LLC",
      "destination_port": "USLAX",
      "pieces": 15,
      "weight_kg": 3200.0,
      "cbm": 9.8,
      "received_at": "2026-04-02T08:45:00Z",
      "consolidation_id": null,
      "created_at": "2026-04-01T16:00:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 87, "total_pages": 4 }
}
POST/api/v1/warehouse-receipts

Create a new warehouse receipt for inbound cargo.

Request body
{
  "shipper": "Guangzhou Textiles Ltd.",
  "consignee": "East Side Fashion Inc.",
  "destination_port": "USNYC",
  "pieces": 8,
  "weight_kg": 1200.0,
  "cbm": 4.2,
  "commodity": "Cotton garments",
  "marks_and_numbers": "GZTX-2026-0042",
  "special_instructions": "Keep dry, no stacking"
}
Response
{
  "id": "wr_99zyx876-wvu5-4321-tsrq-ponm98765432",
  "wr_number": "WR-2026-00543",
  "status": "pending",
  "shipper": "Guangzhou Textiles Ltd.",
  "consignee": "East Side Fashion Inc.",
  "destination_port": "USNYC",
  "pieces": 8,
  "weight_kg": 1200.0,
  "cbm": 4.2,
  "commodity": "Cotton garments",
  "created_at": "2026-04-05T09:30:00Z"
}
PATCH/api/v1/warehouse-receipts/:id

Update a warehouse receipt. Typically used to update status or correct details.

Request body
{
  "status": "received",
  "actual_weight_kg": 1250.0,
  "actual_cbm": 4.5
}
Response
{
  "id": "wr_99zyx876-wvu5-4321-tsrq-ponm98765432",
  "wr_number": "WR-2026-00543",
  "status": "received",
  "actual_weight_kg": 1250.0,
  "actual_cbm": 4.5,
  "updated_at": "2026-04-05T10:00:00Z"
}

Consolidations

Consolidations group multiple warehouse receipts into a single container or shipment. The API allows you to create, manage, and finalize consolidation plans.

GET/api/v1/consolidations

List all consolidation groups with pagination.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
statusstringNoFilter by status: planning, confirmed, shipped, delivered
destinationstringNoFilter by destination port code
Response
{
  "data": [
    {
      "id": "consol_abc12345-6789-0def-abcd-ef0123456789",
      "reference": "CON-2026-LAX-042",
      "status": "confirmed",
      "destination_port": "USLAX",
      "container_type": "40HC",
      "container_number": "MSCU1234567",
      "total_pieces": 68,
      "total_weight_kg": 15200.0,
      "total_cbm": 32.5,
      "utilization_pct": 84.7,
      "wr_count": 5,
      "etd": "2026-04-12T00:00:00Z",
      "created_at": "2026-04-01T12:00:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 23, "total_pages": 1 }
}
POST/api/v1/consolidations

Create a new consolidation group and assign warehouse receipts.

Request body
{
  "destination_port": "USLAX",
  "container_type": "40HC",
  "etd": "2026-04-15T00:00:00Z",
  "warehouse_receipt_ids": [
    "wr_01abc234-def5-6789-0abc-def012345678",
    "wr_99zyx876-wvu5-4321-tsrq-ponm98765432"
  ],
  "notes": "Priority consolidation for Q2 delivery"
}
Response
{
  "id": "consol_new12345-6789-0def-abcd-ef9876543210",
  "reference": "CON-2026-LAX-043",
  "status": "planning",
  "destination_port": "USLAX",
  "container_type": "40HC",
  "wr_count": 2,
  "total_pieces": 23,
  "total_weight_kg": 4400.0,
  "total_cbm": 14.0,
  "utilization_pct": 20.6,
  "created_at": "2026-04-05T09:45:00Z"
}
POST/api/v1/consolidations/:id/add-wrs

Add warehouse receipts to an existing consolidation. Only works when status is planning.

Request body
{
  "warehouse_receipt_ids": [
    "wr_another1-2345-6789-abcd-ef0123456789"
  ]
}
Response
{
  "id": "consol_new12345-6789-0def-abcd-ef9876543210",
  "wr_count": 3,
  "total_pieces": 35,
  "total_weight_kg": 6800.0,
  "total_cbm": 20.2,
  "utilization_pct": 29.7,
  "updated_at": "2026-04-05T10:15:00Z"
}
PATCH/api/v1/consolidations/:id

Update consolidation details or change status.

Request body
{
  "status": "confirmed",
  "container_number": "MSCU7654321",
  "vessel": "EVER GIVEN",
  "voyage": "045E"
}
Response
{
  "id": "consol_new12345-6789-0def-abcd-ef9876543210",
  "status": "confirmed",
  "container_number": "MSCU7654321",
  "updated_at": "2026-04-05T10:30:00Z"
}

Customers

Manage your customer (shipper/consignee) directory. Customers are linked to warehouse receipts and shipments.

GET/api/v1/customers

List all customers with search and pagination.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
searchstringNoSearch by name, email, or reference
typestringNoFilter by type: shipper, consignee, both
Response
{
  "data": [
    {
      "id": "cust_abc12345-6789-0def-1234-567890abcdef",
      "name": "Shenzhen Electronics Co.",
      "type": "shipper",
      "email": "logistics@szelectronics.cn",
      "phone": "+86-755-8888-0001",
      "address": "Building 5, Tech Park, Nanshan District, Shenzhen",
      "country": "CN",
      "shipment_count": 24,
      "created_at": "2025-09-10T08:00:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 156, "total_pages": 7 }
}
POST/api/v1/customers

Create a new customer record.

Request body
{
  "name": "Pacific Imports LLC",
  "type": "consignee",
  "email": "ops@pacificimports.com",
  "phone": "+1-310-555-0199",
  "address": "1200 Harbor Blvd, Long Beach, CA 90802",
  "country": "US",
  "tax_id": "EIN-12-3456789"
}
Response
{
  "id": "cust_new98765-4321-fedc-ba09-876543210fed",
  "name": "Pacific Imports LLC",
  "type": "consignee",
  "email": "ops@pacificimports.com",
  "country": "US",
  "created_at": "2026-04-05T11:00:00Z"
}
PATCH/api/v1/customers/:id

Update customer details.

Request body
{
  "email": "new-ops@pacificimports.com",
  "phone": "+1-310-555-0200"
}
Response
{
  "id": "cust_new98765-4321-fedc-ba09-876543210fed",
  "name": "Pacific Imports LLC",
  "email": "new-ops@pacificimports.com",
  "phone": "+1-310-555-0200",
  "updated_at": "2026-04-05T11:15:00Z"
}

Documents

Upload, retrieve, and manage freight documents such as bills of lading, commercial invoices, packing lists, and customs declarations.

GET/api/v1/documents

List all documents with optional filters.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
typestringNoFilter by type: bill_of_lading, commercial_invoice, packing_list, customs_declaration, other
shipment_iduuidNoFilter by associated shipment
wr_iduuidNoFilter by associated warehouse receipt
Response
{
  "data": [
    {
      "id": "doc_abc12345-6789-0def-abcd-ef0123456789",
      "name": "BOL-MAERSK-2026-001.pdf",
      "type": "bill_of_lading",
      "mime_type": "application/pdf",
      "size_bytes": 245760,
      "shipment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "wr_id": null,
      "url": "https://storage.consolai.com/docs/doc_abc12345.pdf",
      "ai_extracted": {
        "shipper": "Shenzhen Electronics Co.",
        "consignee": "West Coast Imports LLC",
        "bl_number": "MAEU123456789"
      },
      "created_at": "2026-04-01T14:30:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 312, "total_pages": 13 }
}
POST/api/v1/documents

Upload a new document. Send as multipart/form-data with the file and metadata.

Request body
// multipart/form-data fields:
// file: (binary)
// type: "commercial_invoice"
// shipment_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

curl https://app.consolai.com/api/v1/documents \
  -H "x-api-key: ck_your_key_here" \
  -F "file=@invoice.pdf" \
  -F "type=commercial_invoice" \
  -F "shipment_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Response
{
  "id": "doc_new98765-4321-0fed-cba9-876543210def",
  "name": "invoice.pdf",
  "type": "commercial_invoice",
  "mime_type": "application/pdf",
  "size_bytes": 128000,
  "shipment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "ai_extracted": null,
  "processing_status": "queued",
  "created_at": "2026-04-05T11:30:00Z"
}
DELETE/api/v1/documents/:id

Delete a document permanently.

Response
{
  "success": true,
  "message": "Document doc_abc12345 has been deleted."
}

Exceptions

Exceptions represent issues or discrepancies flagged during the freight process -- overweight cargo, documentation mismatches, customs holds, etc.

GET/api/v1/exceptions

List all exceptions with filters.

Query Parameters
NameTypeRequiredDescription
pageintegerNoPage number (default: 1)
per_pageintegerNoResults per page, max 100 (default: 25)
severitystringNoFilter by severity: low, medium, high, critical
statusstringNoFilter by status: open, investigating, resolved, dismissed
shipment_iduuidNoFilter by associated shipment
Response
{
  "data": [
    {
      "id": "exc_abc12345-6789-0def-abcd-ef0123456789",
      "type": "weight_discrepancy",
      "severity": "medium",
      "status": "open",
      "title": "Weight exceeds declared by 15%",
      "description": "WR-2026-00542 declared 3200kg, actual 3680kg",
      "shipment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "wr_id": "wr_01abc234-def5-6789-0abc-def012345678",
      "created_at": "2026-04-03T09:15:00Z",
      "resolved_at": null
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 18, "total_pages": 1 }
}
POST/api/v1/exceptions

Create a new exception manually.

Request body
{
  "type": "documentation_mismatch",
  "severity": "high",
  "title": "Invoice amount does not match PO",
  "description": "Commercial invoice shows $45,000 but PO total is $42,500",
  "shipment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Response
{
  "id": "exc_new98765-4321-0fed-cba9-876543210def",
  "type": "documentation_mismatch",
  "severity": "high",
  "status": "open",
  "title": "Invoice amount does not match PO",
  "created_at": "2026-04-05T12:00:00Z"
}
PATCH/api/v1/exceptions/:id

Update exception status or add resolution details.

Request body
{
  "status": "resolved",
  "resolution": "Supplier issued corrected invoice matching PO amount."
}
Response
{
  "id": "exc_new98765-4321-0fed-cba9-876543210def",
  "status": "resolved",
  "resolution": "Supplier issued corrected invoice matching PO amount.",
  "resolved_at": "2026-04-05T14:30:00Z",
  "updated_at": "2026-04-05T14:30:00Z"
}

Webhooks

Webhooks allow your application to receive real-time notifications when events occur in ConsolAI. Register a URL and we will send POST requests with event payloads.

Register a webhook

POST/api/v1/webhooks

Register a new webhook endpoint.

Request body
{
  "url": "https://your-app.com/api/consolai-webhook",
  "events": [
    "shipment.created",
    "shipment.status_changed",
    "wr.received",
    "consolidation.confirmed",
    "exception.created"
  ],
  "secret": "whsec_your_signing_secret"
}
Response
{
  "id": "wh_abc12345-6789-0def-abcd-ef0123456789",
  "url": "https://your-app.com/api/consolai-webhook",
  "events": [
    "shipment.created",
    "shipment.status_changed",
    "wr.received",
    "consolidation.confirmed",
    "exception.created"
  ],
  "active": true,
  "created_at": "2026-04-05T12:30:00Z"
}
GET/api/v1/webhooks

List all registered webhooks.

Response
{
  "data": [
    {
      "id": "wh_abc12345-6789-0def-abcd-ef0123456789",
      "url": "https://your-app.com/api/consolai-webhook",
      "events": ["shipment.created", "shipment.status_changed"],
      "active": true,
      "last_triggered_at": "2026-04-05T10:00:00Z",
      "created_at": "2026-04-01T08:00:00Z"
    }
  ]
}
DELETE/api/v1/webhooks/:id

Delete a registered webhook.

Response
{
  "success": true,
  "message": "Webhook wh_abc12345 has been deleted."
}

Event types

EventDescription
shipment.createdA new shipment has been created
shipment.status_changedShipment status changed (e.g., booked, in_transit, delivered)
shipment.deletedA shipment has been deleted
wr.createdA new warehouse receipt has been created
wr.receivedCargo for a warehouse receipt has been received at the CFS
wr.consolidatedA warehouse receipt has been assigned to a consolidation
consolidation.createdA new consolidation group has been created
consolidation.confirmedA consolidation has been confirmed and is ready to ship
consolidation.shippedA consolidation container has departed
document.uploadedA new document has been uploaded
document.processedAI extraction completed for a document
exception.createdA new exception has been flagged
exception.resolvedAn exception has been resolved
customer.createdA new customer record has been created

Payload format

Each webhook delivery sends a POST request with a JSON body containing the event type, a timestamp, and the relevant data object.

Webhook payload
{
  "event": "shipment.status_changed",
  "timestamp": "2026-04-05T14:30:00Z",
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "reference": "SHP-2026-001234",
    "previous_status": "booked",
    "status": "in_transit",
    "updated_at": "2026-04-05T14:30:00Z"
  }
}

Signature verification

Every webhook request includes a X-ConsolAI-Signature header. The signature is computed as sha256=HMAC(payload, secret) using the signing secret you provided when registering the webhook.

Always verify the signature before processing the payload to ensure the request originated from ConsolAI.

Node.js signature verification
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express middleware example
app.post('/api/consolai-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-consolai-signature'];
  const isValid = verifyWebhookSignature(req.body.toString(), signature, process.env.WEBHOOK_SECRET);

  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(req.body);
  console.log('Received event:', event.event, event.data);

  // Process the event...
  res.status(200).json({ received: true });
});

Code Examples

Complete examples for common operations in curl, JavaScript, and Python.

List shipments

curl
curl -s "https://app.consolai.com/api/v1/shipments?status=in_transit&per_page=10" \
  -H "x-api-key: ck_your_key_here" \
  -H "Content-Type: application/json" | jq .
JavaScript (fetch)
const response = await fetch(
  'https://app.consolai.com/api/v1/shipments?status=in_transit&per_page=10',
  {
    headers: {
      'x-api-key': process.env.CONSOLAI_API_KEY,
      'Content-Type': 'application/json',
    },
  }
);

const { data: shipments, meta } = await response.json();
console.log(`Found ${meta.total} in-transit shipments`);
shipments.forEach(s => {
  console.log(`  ${s.reference} — ${s.origin_port} → ${s.destination_port}, ETA ${s.eta}`);
});
Python (requests)
import requests

API_KEY = "ck_your_key_here"
BASE_URL = "https://app.consolai.com/api/v1"

resp = requests.get(
    f"{BASE_URL}/shipments",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    params={"status": "in_transit", "per_page": 10},
)
resp.raise_for_status()

data = resp.json()
print(f"Found {data['meta']['total']} in-transit shipments")
for s in data["data"]:
    print(f"  {s['reference']} — {s['origin_port']} → {s['destination_port']}, ETA {s['eta']}")

Create a warehouse receipt

curl
curl -X POST "https://app.consolai.com/api/v1/warehouse-receipts" \
  -H "x-api-key: ck_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "shipper": "Guangzhou Textiles Ltd.",
    "consignee": "East Side Fashion Inc.",
    "destination_port": "USNYC",
    "pieces": 8,
    "weight_kg": 1200.0,
    "cbm": 4.2,
    "commodity": "Cotton garments"
  }'
JavaScript (fetch)
const newWR = await fetch('https://app.consolai.com/api/v1/warehouse-receipts', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.CONSOLAI_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    shipper: 'Guangzhou Textiles Ltd.',
    consignee: 'East Side Fashion Inc.',
    destination_port: 'USNYC',
    pieces: 8,
    weight_kg: 1200.0,
    cbm: 4.2,
    commodity: 'Cotton garments',
  }),
});

const wr = await newWR.json();
console.log('Created WR:', wr.wr_number);
Python (requests)
import requests

resp = requests.post(
    f"{BASE_URL}/warehouse-receipts",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={
        "shipper": "Guangzhou Textiles Ltd.",
        "consignee": "East Side Fashion Inc.",
        "destination_port": "USNYC",
        "pieces": 8,
        "weight_kg": 1200.0,
        "cbm": 4.2,
        "commodity": "Cotton garments",
    },
)
resp.raise_for_status()

wr = resp.json()
print(f"Created WR: {wr['wr_number']}")

Register a webhook

curl
curl -X POST "https://app.consolai.com/api/v1/webhooks" \
  -H "x-api-key: ck_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/api/consolai-webhook",
    "events": ["shipment.status_changed", "exception.created"],
    "secret": "whsec_your_signing_secret"
  }'
JavaScript (fetch)
const webhook = await fetch('https://app.consolai.com/api/v1/webhooks', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.CONSOLAI_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://your-app.com/api/consolai-webhook',
    events: ['shipment.status_changed', 'exception.created'],
    secret: process.env.WEBHOOK_SECRET,
  }),
});

const wh = await webhook.json();
console.log('Webhook registered:', wh.id);
Python (requests)
import requests

resp = requests.post(
    f"{BASE_URL}/webhooks",
    headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
    json={
        "url": "https://your-app.com/api/consolai-webhook",
        "events": ["shipment.status_changed", "exception.created"],
        "secret": "whsec_your_signing_secret",
    },
)
resp.raise_for_status()

wh = resp.json()
print(f"Webhook registered: {wh['id']}")

Need help? Contact us at api@consolai.com or visit the ConsolAI website.

ConsolAI API v1.0 · Last updated April 2026