{
	"info": {
		"_postman_id": "cubeconnect-api-v1",
		"name": "CubeConnect API",
		"description": "Official Postman collection for CubeConnect WhatsApp Business API.\n\nBase URL: https://cubeconnect.io\nDocs: https://docs.cubeconnect.io\n\n## Setup\n1. Set the `api_key` variable in the collection variables\n2. (Optional) Set `tenant_id` for multi-tenant accounts\n3. Update `phone` with a valid WhatsApp number\n\n## Authentication\nAll requests use Bearer token authentication automatically via the `api_key` variable.",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"auth": {
		"type": "bearer",
		"bearer": [
			{
				"key": "token",
				"value": "{{api_key}}",
				"type": "string"
			}
		]
	},
	"variable": [
		{
			"key": "base_url",
			"value": "https://cubeconnect.io",
			"type": "string"
		},
		{
			"key": "api_key",
			"value": "YOUR_API_KEY",
			"type": "string"
		},
		{
			"key": "tenant_id",
			"value": "",
			"type": "string"
		},
		{
			"key": "phone",
			"value": "+966501234567",
			"type": "string"
		}
	],
	"item": [
		{
			"name": "Health Check",
			"item": [
				{
					"name": "Platform Health",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/health",
							"host": ["{{base_url}}"],
							"path": ["api", "health"]
						},
						"description": "Check platform status. No authentication required.\n\nReturns health status of app, database, and cache."
					},
					"response": [
						{
							"name": "Healthy",
							"status": "OK",
							"code": 200,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": true,\n  \"data\": {\n    \"status\": \"healthy\",\n    \"checks\": {\n      \"app\": true,\n      \"database\": true,\n      \"cache\": true\n    },\n    \"timestamp\": \"2026-02-28T12:00:00Z\"\n  }\n}"
						}
					]
				}
			]
		},
		{
			"name": "Messages",
			"item": [
				{
					"name": "Send Text Message",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Accept",
								"value": "application/json"
							},
							{
								"key": "X-TENANT-ID",
								"value": "{{tenant_id}}",
								"disabled": true,
								"description": "Optional — enable for multi-tenant accounts"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"text\",\n  \"data\": {\n    \"text\": \"Hello from Postman! 👋\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Send a text message to a WhatsApp number.\n\n⚠️ Requires the recipient to have messaged you within the last 24 hours.\nFor first-time messages, use Send Template instead."
					},
					"response": [
						{
							"name": "Success",
							"status": "Accepted",
							"code": 202,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": true,\n  \"data\": {\n    \"status\": \"queued\",\n    \"message_log_id\": 4521,\n    \"conversation_category\": \"SERVICE\",\n    \"cost\": 0.0\n  }\n}"
						}
					]
				},
				{
					"name": "Send Template (with params)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Accept",
								"value": "application/json"
							},
							{
								"key": "X-TENANT-ID",
								"value": "{{tenant_id}}",
								"disabled": true,
								"description": "Optional — enable for multi-tenant accounts"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"template\",\n  \"data\": {\n    \"name\": \"order_confirmation\",\n    \"language_code\": \"en_US\",\n    \"components\": [\n      {\n        \"type\": \"body\",\n        \"parameters\": [\n          {\"type\": \"text\", \"text\": \"ORD-1234\"},\n          {\"type\": \"text\", \"text\": \"500 SAR\"}\n        ]\n      }\n    ]\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Send a pre-approved template message with parameters.\n\nParameters map to {{1}}, {{2}}, etc. in the template body.\nTemplates can be sent anytime — no 24-hour window restriction.\n\n📝 Replace `order_confirmation` with your actual template name."
					},
					"response": [
						{
							"name": "Success",
							"status": "Accepted",
							"code": 202,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": true,\n  \"data\": {\n    \"status\": \"queued\",\n    \"message_log_id\": 4522,\n    \"conversation_category\": \"MARKETING\",\n    \"cost\": 0.0\n  }\n}"
						}
					]
				},
				{
					"name": "Send Template (no params)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"template\",\n  \"data\": {\n    \"name\": \"welcome_message\",\n    \"language_code\": \"en_US\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Send a template message without parameters.\n\nUse this for templates that have no variable placeholders (e.g., welcome messages)."
					},
					"response": [
						{
							"name": "Success",
							"status": "Accepted",
							"code": 202,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": true,\n  \"data\": {\n    \"status\": \"queued\",\n    \"message_log_id\": 4523,\n    \"conversation_category\": \"UTILITY\",\n    \"cost\": 0.0\n  }\n}"
						}
					]
				},
				{
					"name": "Send Template (Arabic)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"template\",\n  \"data\": {\n    \"name\": \"order_confirmation\",\n    \"language_code\": \"ar\",\n    \"components\": [\n      {\n        \"type\": \"body\",\n        \"parameters\": [\n          {\"type\": \"text\", \"text\": \"ORD-1234\"},\n          {\"type\": \"text\", \"text\": \"500 ريال\"}\n        ]\n      }\n    ]\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Send a template message in Arabic.\n\nSet `language_code` to `ar` to use the Arabic version of the template."
					},
					"response": []
				}
			]
		},
		{
			"name": "Conversations",
			"item": [
				{
					"name": "List Conversations",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/conversations?page=1&per_page=20",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "conversations"],
							"query": [
								{
									"key": "page",
									"value": "1",
									"description": "Page number"
								},
								{
									"key": "per_page",
									"value": "20",
									"description": "Items per page (max 100)"
								},
								{
									"key": "status",
									"value": "open",
									"description": "Filter: open, closed",
									"disabled": true
								}
							]
						},
						"description": "List all conversations with pagination."
					},
					"response": []
				},
				{
					"name": "Get Conversation",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/conversations/:id",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "conversations", ":id"],
							"variable": [
								{
									"key": "id",
									"value": "1",
									"description": "Conversation ID"
								}
							]
						},
						"description": "Get a single conversation by ID with its messages."
					},
					"response": []
				}
			]
		},
		{
			"name": "Customers",
			"item": [
				{
					"name": "List Customers",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/customers?page=1&per_page=20",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "customers"],
							"query": [
								{
									"key": "page",
									"value": "1"
								},
								{
									"key": "per_page",
									"value": "20"
								},
								{
									"key": "search",
									"value": "",
									"description": "Search by name or phone",
									"disabled": true
								}
							]
						},
						"description": "List all customers with pagination and optional search."
					},
					"response": []
				},
				{
					"name": "Get Customer",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/customers/:id",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "customers", ":id"],
							"variable": [
								{
									"key": "id",
									"value": "1",
									"description": "Customer ID"
								}
							]
						},
						"description": "Get a single customer by ID."
					},
					"response": []
				}
			]
		},
		{
			"name": "Templates",
			"item": [
				{
					"name": "List Templates",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/templates?page=1&per_page=20",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "templates"],
							"query": [
								{
									"key": "page",
									"value": "1"
								},
								{
									"key": "per_page",
									"value": "20"
								},
								{
									"key": "status",
									"value": "APPROVED",
									"description": "Filter: APPROVED, PENDING, REJECTED",
									"disabled": true
								},
								{
									"key": "category",
									"value": "MARKETING",
									"description": "Filter: MARKETING, UTILITY, AUTHENTICATION",
									"disabled": true
								}
							]
						},
						"description": "List all WhatsApp message templates with optional filters."
					},
					"response": []
				},
				{
					"name": "Get Template",
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/templates/:id",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "templates", ":id"],
							"variable": [
								{
									"key": "id",
									"value": "1",
									"description": "Template ID"
								}
							]
						},
						"description": "Get a single template by ID."
					},
					"response": []
				}
			]
		},
		{
			"name": "Error Examples",
			"item": [
				{
					"name": "401 — Invalid API Key",
					"request": {
						"auth": {
							"type": "bearer",
							"bearer": [
								{
									"key": "token",
									"value": "invalid_key_123",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"text\",\n  \"data\": {\n    \"text\": \"This should fail\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Test error handling with an invalid API key.\n\nExpected: 401 with INVALID_API_KEY error code."
					},
					"response": [
						{
							"name": "Authentication Error",
							"status": "Unauthorized",
							"code": 401,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_API_KEY\",\n    \"message\": \"The provided API key is invalid or has been revoked.\"\n  }\n}"
						}
					]
				},
				{
					"name": "401 — No API Key",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"{{phone}}\",\n  \"message_type\": \"text\",\n  \"data\": {\n    \"text\": \"This should fail\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Test error handling without any API key.\n\nExpected: 401 with AUTHENTICATION_REQUIRED error code."
					},
					"response": [
						{
							"name": "Missing Auth",
							"status": "Unauthorized",
							"code": 401,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"AUTHENTICATION_REQUIRED\",\n    \"message\": \"An API key is required. Include it as a Bearer token or X-API-KEY header.\"\n  }\n}"
						}
					]
				},
				{
					"name": "422 — Validation Error",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"phone\": \"\",\n  \"message_type\": \"text\",\n  \"data\": {}\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/messages/send",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "messages", "send"]
						},
						"description": "Test validation error by sending empty required fields.\n\nExpected: 422 with VALIDATION_ERROR and field-level errors."
					},
					"response": [
						{
							"name": "Validation Error",
							"status": "Unprocessable Entity",
							"code": 422,
							"header": [
								{"key": "Content-Type", "value": "application/json"}
							],
							"body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VALIDATION_ERROR\",\n    \"message\": \"The given data was invalid.\",\n    \"details\": {\n      \"phone\": [\"The phone field is required.\"],\n      \"data.text\": [\"The data.text field is required.\"]\n    }\n  }\n}"
						}
					]
				}
			]
		}
	],
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					"// Auto-add X-TENANT-ID header if tenant_id is set",
					"const tenantId = pm.collectionVariables.get('tenant_id');",
					"if (tenantId) {",
					"    pm.request.headers.add({",
					"        key: 'X-TENANT-ID',",
					"        value: tenantId",
					"    });",
					"}"
				]
			}
		}
	]
}
