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:
- Generate an API key in Settings → API tab
- Include the key in the
x-api-keyheader - 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.
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.
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1712345678
{
"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.
/api/v1/shipmentsList all shipments with pagination and optional filters.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| status | string | No | Filter by status: draft, booked, in_transit, delivered, cancelled |
| origin | string | No | Filter by origin port code (e.g., CNSHA) |
| destination | string | No | Filter by destination port code (e.g., USLAX) |
| created_after | ISO 8601 | No | Filter shipments created after this date |
{
"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
}
}/api/v1/shipments/:idRetrieve a single shipment by ID, including line items and linked documents.
{
"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"
}/api/v1/shipmentsCreate a new shipment.
{
"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"
}{
"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"
}/api/v1/shipments/:idUpdate an existing shipment. Only provided fields are changed.
{
"status": "booked",
"vessel": "EMMA MAERSK",
"voyage": "032W"
}{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reference": "SHP-2026-001234",
"status": "booked",
"vessel": "EMMA MAERSK",
"voyage": "032W",
"updated_at": "2026-04-05T09:20:00Z"
}/api/v1/shipments/:idDelete a shipment. Only draft shipments can be deleted.
{
"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.
/api/v1/warehouse-receiptsList all warehouse receipts with pagination and filtering.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| status | string | No | Filter by status: pending, received, consolidated, shipped |
| shipper | string | No | Filter by shipper name (partial match) |
| destination | string | No | Filter by destination port code |
{
"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 }
}/api/v1/warehouse-receiptsCreate a new warehouse receipt for inbound cargo.
{
"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"
}{
"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"
}/api/v1/warehouse-receipts/:idUpdate a warehouse receipt. Typically used to update status or correct details.
{
"status": "received",
"actual_weight_kg": 1250.0,
"actual_cbm": 4.5
}{
"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.
/api/v1/consolidationsList all consolidation groups with pagination.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| status | string | No | Filter by status: planning, confirmed, shipped, delivered |
| destination | string | No | Filter by destination port code |
{
"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 }
}/api/v1/consolidationsCreate a new consolidation group and assign warehouse receipts.
{
"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"
}{
"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"
}/api/v1/consolidations/:id/add-wrsAdd warehouse receipts to an existing consolidation. Only works when status is planning.
{
"warehouse_receipt_ids": [
"wr_another1-2345-6789-abcd-ef0123456789"
]
}{
"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"
}/api/v1/consolidations/:idUpdate consolidation details or change status.
{
"status": "confirmed",
"container_number": "MSCU7654321",
"vessel": "EVER GIVEN",
"voyage": "045E"
}{
"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.
/api/v1/customersList all customers with search and pagination.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| search | string | No | Search by name, email, or reference |
| type | string | No | Filter by type: shipper, consignee, both |
{
"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 }
}/api/v1/customersCreate a new customer record.
{
"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"
}{
"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"
}/api/v1/customers/:idUpdate customer details.
{
"email": "new-ops@pacificimports.com",
"phone": "+1-310-555-0200"
}{
"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.
/api/v1/documentsList all documents with optional filters.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| type | string | No | Filter by type: bill_of_lading, commercial_invoice, packing_list, customs_declaration, other |
| shipment_id | uuid | No | Filter by associated shipment |
| wr_id | uuid | No | Filter by associated warehouse receipt |
{
"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 }
}/api/v1/documentsUpload a new document. Send as multipart/form-data with the file and metadata.
// 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"
{
"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"
}/api/v1/documents/:idDelete a document permanently.
{
"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.
/api/v1/exceptionsList all exceptions with filters.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| per_page | integer | No | Results per page, max 100 (default: 25) |
| severity | string | No | Filter by severity: low, medium, high, critical |
| status | string | No | Filter by status: open, investigating, resolved, dismissed |
| shipment_id | uuid | No | Filter by associated shipment |
{
"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 }
}/api/v1/exceptionsCreate a new exception manually.
{
"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"
}{
"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"
}/api/v1/exceptions/:idUpdate exception status or add resolution details.
{
"status": "resolved",
"resolution": "Supplier issued corrected invoice matching PO amount."
}{
"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
/api/v1/webhooksRegister a new webhook endpoint.
{
"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"
}{
"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"
}/api/v1/webhooksList all registered webhooks.
{
"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"
}
]
}/api/v1/webhooks/:idDelete a registered webhook.
{
"success": true,
"message": "Webhook wh_abc12345 has been deleted."
}Event types
| Event | Description |
|---|---|
| shipment.created | A new shipment has been created |
| shipment.status_changed | Shipment status changed (e.g., booked, in_transit, delivered) |
| shipment.deleted | A shipment has been deleted |
| wr.created | A new warehouse receipt has been created |
| wr.received | Cargo for a warehouse receipt has been received at the CFS |
| wr.consolidated | A warehouse receipt has been assigned to a consolidation |
| consolidation.created | A new consolidation group has been created |
| consolidation.confirmed | A consolidation has been confirmed and is ready to ship |
| consolidation.shipped | A consolidation container has departed |
| document.uploaded | A new document has been uploaded |
| document.processed | AI extraction completed for a document |
| exception.created | A new exception has been flagged |
| exception.resolved | An exception has been resolved |
| customer.created | A 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.
{
"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.
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 -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 .
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}`);
});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 -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"
}'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);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 -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"
}'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);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