diff --git a/src/.vitepress/sidebars/rest-api.js b/src/.vitepress/sidebars/rest-api.js
index d79616f..4b45dcd 100644
--- a/src/.vitepress/sidebars/rest-api.js
+++ b/src/.vitepress/sidebars/rest-api.js
@@ -506,17 +506,19 @@ export default [
]
},
{
- text: 'Pro Settings (11)',
+ text: 'Pro Settings (13)',
collapsed: true,
items: [
{ text: 'Get License Status GET', link: '/rest-api/operations/pro-settings/get-license-status' },
{ text: 'Get SMS Settings GET', link: '/rest-api/operations/pro-settings/get-sms-settings' },
+ { text: 'Get WhatsApp Settings GET', link: '/rest-api/operations/pro-settings/get-whatsapp-settings' },
{ text: 'List Managers GET', link: '/rest-api/operations/pro-settings/get-managers' },
{ text: 'Add Manager POST', link: '/rest-api/operations/pro-settings/add-manager' },
{ text: 'Disable SMS POST', link: '/rest-api/operations/pro-settings/disable-sms' },
{ text: 'Import Funnel POST', link: '/rest-api/operations/pro-settings/import-funnel' },
{ text: 'Save License POST', link: '/rest-api/operations/pro-settings/save-license' },
{ text: 'Save SMS Settings POST', link: '/rest-api/operations/pro-settings/save-sms-settings' },
+ { text: 'Save WhatsApp Settings POST', link: '/rest-api/operations/pro-settings/save-whatsapp-settings' },
{ text: 'Update Manager PUT', link: '/rest-api/operations/pro-settings/update-manager' },
{ text: 'Deactivate License DELETE', link: '/rest-api/operations/pro-settings/deactivate-license' },
{ text: 'Delete Manager DELETE', link: '/rest-api/operations/pro-settings/delete-manager' },
@@ -553,6 +555,21 @@ export default [
{ text: 'Delete SMS Messages DELETE', link: '/rest-api/operations/sms/delete-sms-messages' },
]
},
+ {
+ text: 'WhatsApp (Pro) (9)',
+ collapsed: true,
+ items: [
+ { text: 'Get Subscriber WhatsApp Messages GET', link: '/rest-api/operations/whatsapp/get-subscriber-whatsapp-messages' },
+ { text: 'Get Subscriber WhatsApp Session GET', link: '/rest-api/operations/whatsapp/get-subscriber-whatsapp-session' },
+ { text: 'Get Subscriber WhatsApp Stats GET', link: '/rest-api/operations/whatsapp/get-subscriber-whatsapp-stats' },
+ { text: 'List WhatsApp Templates GET', link: '/rest-api/operations/whatsapp/list-whatsapp-templates' },
+ { text: 'Create WhatsApp Template POST', link: '/rest-api/operations/whatsapp/create-whatsapp-template' },
+ { text: 'Send Subscriber WhatsApp Message POST', link: '/rest-api/operations/whatsapp/send-subscriber-whatsapp-message' },
+ { text: 'Sync WhatsApp Templates POST', link: '/rest-api/operations/whatsapp/sync-whatsapp-templates' },
+ { text: 'Validate WhatsApp Template POST', link: '/rest-api/operations/whatsapp/validate-whatsapp-template' },
+ { text: 'Delete WhatsApp Template DELETE', link: '/rest-api/operations/whatsapp/delete-whatsapp-template' },
+ ]
+ },
{
text: 'Bounce Handler (Public) (2)',
collapsed: true,
diff --git a/src/public/openapi/pro-settings/get-license-status.json b/src/public/openapi/pro-settings/get-license-status.json
index 1c8468c..f40dddb 100644
--- a/src/public/openapi/pro-settings/get-license-status.json
+++ b/src/public/openapi/pro-settings/get-license-status.json
@@ -86,10 +86,6 @@
"activation_hash": {
"type": "string",
"description": "Hash identifying this site's activation."
- },
- "is_expired": {
- "type": "boolean",
- "description": "True when the licence has lapsed."
}
}
},
diff --git a/src/public/openapi/pro-settings/get-whatsapp-settings.json b/src/public/openapi/pro-settings/get-whatsapp-settings.json
new file mode 100644
index 0000000..7231c86
--- /dev/null
+++ b/src/public/openapi/pro-settings/get-whatsapp-settings.json
@@ -0,0 +1,125 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/campaign-pro-settings/whatsapp-settings": {
+ "get": {
+ "operationId": "getWhatsAppSettings",
+ "summary": "GET WhatsApp Settings",
+ "description": "Retrieve WhatsApp module settings, provider options, and webhook information. **PRO** (requires FluentCampaign Pro).\n\n\n\n**Required capability:** `fcrm_manage_settings`\n\n_Enforced by `SettingsPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro. Without it the route does not exist.\n\n",
+ "tags": [
+ "Pro Settings"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "WhatsApp settings and provider options.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "settings": {
+ "type": "object",
+ "description": "Current WhatsApp settings and provider credentials."
+ },
+ "options": {
+ "type": "object",
+ "description": "Available WhatsApp provider options and field definitions."
+ },
+ "whatsapp_webhook": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "description": "Webhook registration information when WhatsApp is enabled."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/pro-settings/save-whatsapp-settings.json b/src/public/openapi/pro-settings/save-whatsapp-settings.json
new file mode 100644
index 0000000..e41a7ca
--- /dev/null
+++ b/src/public/openapi/pro-settings/save-whatsapp-settings.json
@@ -0,0 +1,186 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/campaign-pro-settings/whatsapp-settings": {
+ "post": {
+ "operationId": "saveWhatsAppSettings",
+ "summary": "POST Save WhatsApp Settings",
+ "description": "Save WhatsApp module settings, selected provider, and provider credentials. **PRO** (requires FluentCampaign Pro).\n\n\n\n**Required capability:** `fcrm_manage_settings`\n\n_Enforced by `SettingsPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro. Without it the route does not exist.\n\n",
+ "tags": [
+ "Pro Settings"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "settings": {
+ "type": "object",
+ "description": "WhatsApp module settings. Provider credentials are nested under the provider slug.",
+ "properties": {
+ "enabled": {
+ "type": "string",
+ "enum": [
+ "yes",
+ "no"
+ ],
+ "description": "Whether to enable WhatsApp messaging."
+ },
+ "whatsapp_provider": {
+ "type": "string",
+ "description": "Provider slug, such as twilio_whatsapp or meta_cloud."
+ }
+ },
+ "additionalProperties": true
+ }
+ },
+ "required": [
+ "settings"
+ ]
+ },
+ "example": {
+ "settings": {
+ "enabled": "yes",
+ "whatsapp_provider": "meta_cloud",
+ "meta_cloud": {
+ "waba_id": "1234567890",
+ "phone_number_id": "1234567890",
+ "access_token": "EAAB...",
+ "app_secret": "app_secret",
+ "verify_token": "verify-token"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "WhatsApp settings saved successfully.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Success message."
+ },
+ "settings": {
+ "type": "object",
+ "description": "Saved WhatsApp settings."
+ },
+ "options": {
+ "type": "object",
+ "description": "Available WhatsApp provider options."
+ },
+ "whatsapp_webhook": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "description": "Webhook registration information when enabled."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/settings/get-abandon-cart-settings.json b/src/public/openapi/settings/get-abandon-cart-settings.json
index 8732374..bcac5b6 100644
--- a/src/public/openapi/settings/get-abandon-cart-settings.json
+++ b/src/public/openapi/settings/get-abandon-cart-settings.json
@@ -86,6 +86,23 @@
"fluent_cartOptions": {
"type": "object",
"properties": {}
+ },
+ "wooOptions": {
+ "type": "object",
+ "description": "WooCommerce status options used by abandoned-cart recovery settings.",
+ "properties": {
+ "all_statuses": {
+ "type": "object",
+ "description": "Available WooCommerce order statuses keyed by status slug."
+ },
+ "paid_statuses": {
+ "type": "array",
+ "description": "WooCommerce statuses treated as paid/recovered.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
}
},
"additionalProperties": true
diff --git a/src/public/openapi/sms/delete-sms-messages.json b/src/public/openapi/sms/delete-sms-messages.json
index 07cd982..2c15527 100644
--- a/src/public/openapi/sms/delete-sms-messages.json
+++ b/src/public/openapi/sms/delete-sms-messages.json
@@ -27,7 +27,7 @@
"delete": {
"operationId": "deleteSmsMessages",
"summary": "DELETE Delete SMS Messages",
- "description": "Delete multiple SMS messages by their IDs. **PRO** (requires FluentCampaign Pro SMS module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\nRoute exists only while the SMS module is enabled; the policy returns false otherwise.\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "description": "Delete multiple SMS messages by their IDs. **PRO** (requires FluentCampaign Pro SMS module).\n\n\n\n**Required capability:** `fcrm_manage_email_delete`\n\nRoute exists only while the SMS module is enabled; the policy returns false otherwise.\n\n_Enforced by `SMSPolicy::deleteMessages()`._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
"tags": [
"SMS"
],
diff --git a/src/public/openapi/whatsapp/create-whatsapp-template.json b/src/public/openapi/whatsapp/create-whatsapp-template.json
new file mode 100644
index 0000000..cffe5dc
--- /dev/null
+++ b/src/public/openapi/whatsapp/create-whatsapp-template.json
@@ -0,0 +1,286 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/templates": {
+ "post": {
+ "operationId": "createWhatsAppTemplate",
+ "summary": "POST Create WhatsApp Template",
+ "description": "Submit a WhatsApp template to the configured provider for review. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Template name."
+ },
+ "language": {
+ "type": "string",
+ "description": "Language code.",
+ "default": "en_US"
+ },
+ "category": {
+ "type": "string",
+ "description": "Template category.",
+ "default": "MARKETING"
+ },
+ "header_text": {
+ "type": "string",
+ "description": "Optional header text."
+ },
+ "body_text": {
+ "type": "string",
+ "description": "Template body text."
+ },
+ "footer_text": {
+ "type": "string",
+ "description": "Optional footer text."
+ },
+ "buttons": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ },
+ "description": "Template buttons."
+ },
+ "variables": {
+ "type": "object",
+ "description": "Template variable examples."
+ }
+ },
+ "required": [
+ "name",
+ "body_text"
+ ]
+ },
+ "example": {
+ "name": "order_update",
+ "language": "en_US",
+ "category": "UTILITY",
+ "body_text": "Hi {{1}}, your order {{2}} has shipped.",
+ "variables": {
+ "1": "Jane",
+ "2": "#1001"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Template submitted for provider review.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Success message."
+ },
+ "template": {
+ "$ref": "#/components/schemas/WhatsAppTemplate"
+ },
+ "warnings": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Validation warnings."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ },
+ "WhatsAppTemplate": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "description": "Template row ID."
+ },
+ "channel": {
+ "type": "string",
+ "description": "Template channel.",
+ "enum": [
+ "whatsapp"
+ ]
+ },
+ "provider": {
+ "type": "string",
+ "description": "Provider slug."
+ },
+ "name": {
+ "type": "string",
+ "description": "Provider template name."
+ },
+ "language": {
+ "type": "string",
+ "description": "Template language code."
+ },
+ "category": {
+ "type": "string",
+ "description": "Template category."
+ },
+ "status": {
+ "type": "string",
+ "description": "Provider review status."
+ },
+ "header_text": {
+ "type": "string",
+ "description": "Header text, when present."
+ },
+ "body_text": {
+ "type": "string",
+ "description": "Template body text."
+ },
+ "footer_text": {
+ "type": "string",
+ "description": "Footer text, when present."
+ },
+ "buttons": {
+ "type": "array",
+ "description": "Template buttons.",
+ "items": {
+ "type": "object"
+ }
+ },
+ "variables": {
+ "type": "object",
+ "description": "Template variable examples or defaults."
+ },
+ "provider_template_id": {
+ "type": "string",
+ "description": "Provider-side template ID."
+ },
+ "rejection_reason": {
+ "type": "string",
+ "description": "Provider rejection reason, when present."
+ },
+ "last_synced_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Last provider sync timestamp."
+ },
+ "created_by": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "description": "WordPress user ID that created the row."
+ },
+ "created_at": {
+ "type": "string",
+ "description": "Creation timestamp."
+ },
+ "updated_at": {
+ "type": "string",
+ "description": "Update timestamp."
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/delete-whatsapp-template.json b/src/public/openapi/whatsapp/delete-whatsapp-template.json
new file mode 100644
index 0000000..12cbfbb
--- /dev/null
+++ b/src/public/openapi/whatsapp/delete-whatsapp-template.json
@@ -0,0 +1,145 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/templates/{id}": {
+ "delete": {
+ "operationId": "deleteWhatsAppTemplate",
+ "summary": "DELETE WhatsApp Template",
+ "description": "Delete a WhatsApp template locally and from the provider when possible. Sent-message references are preserved by disabling referenced templates. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_manage_email_delete`\n\n_Enforced by `SMSPolicy::destroy()`._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "Template row ID.",
+ "required": true,
+ "schema": {
+ "type": "integer"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Template deleted or disabled.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Result message."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The requested resource does not exist.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/get-subscriber-whatsapp-messages.json b/src/public/openapi/whatsapp/get-subscriber-whatsapp-messages.json
new file mode 100644
index 0000000..734b2ad
--- /dev/null
+++ b/src/public/openapi/whatsapp/get-subscriber-whatsapp-messages.json
@@ -0,0 +1,311 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/subscribers/{id}/messages": {
+ "get": {
+ "operationId": "getSubscriberWhatsAppMessages",
+ "summary": "GET Subscriber WhatsApp Messages",
+ "description": "Retrieve paginated WhatsApp message history for a specific subscriber/contact. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "Subscriber/contact ID.",
+ "required": true,
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "page",
+ "in": "query",
+ "description": "Page number.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 1
+ }
+ },
+ {
+ "name": "per_page",
+ "in": "query",
+ "description": "Rows per page.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 20
+ }
+ },
+ {
+ "name": "filter_type",
+ "in": "query",
+ "description": "Optional UI filter key for future filtering.",
+ "required": false,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Paginated WhatsApp messages for the subscriber.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "messages": {
+ "type": "object",
+ "description": "Paginated result set.",
+ "properties": {
+ "total": {
+ "type": "integer",
+ "description": "Total number of matching rows."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Rows per page."
+ },
+ "current_page": {
+ "type": "integer",
+ "description": "Current page number."
+ },
+ "last_page": {
+ "type": "integer",
+ "description": "Number of the final page."
+ },
+ "from": {
+ "type": "integer",
+ "description": "Index of the first row on this page."
+ },
+ "to": {
+ "type": "integer",
+ "description": "Index of the last row on this page."
+ },
+ "next_page_url": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "URL of the next page, or null."
+ },
+ "prev_page_url": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "URL of the previous page, or null."
+ },
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WhatsAppMessage"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The requested resource does not exist.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ },
+ "WhatsAppMessage": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "description": "Message row ID."
+ },
+ "subscriber_id": {
+ "type": "integer",
+ "description": "Subscriber/contact ID."
+ },
+ "campaign_id": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "description": "Campaign ID when sent by a campaign."
+ },
+ "sms_type": {
+ "type": "string",
+ "description": "Message type, such as campaign, automation, incoming, or custom-whatsapp."
+ },
+ "channel": {
+ "type": "string",
+ "description": "Message channel.",
+ "enum": [
+ "whatsapp"
+ ]
+ },
+ "direction": {
+ "type": "string",
+ "description": "Direction of the message.",
+ "enum": [
+ "outbound",
+ "inbound"
+ ]
+ },
+ "mobile_number": {
+ "type": "string",
+ "description": "Recipient or sender phone number."
+ },
+ "message_content": {
+ "type": "string",
+ "description": "Stored message text."
+ },
+ "status": {
+ "type": "string",
+ "description": "Message status."
+ },
+ "delivery_status": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Provider delivery status."
+ },
+ "provider_message_id": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Provider message ID."
+ },
+ "template_id": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "description": "Template row ID for template sends."
+ },
+ "sent_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Send timestamp."
+ },
+ "delivered_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Delivery timestamp."
+ },
+ "read_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Read receipt timestamp."
+ },
+ "created_at": {
+ "type": "string",
+ "description": "Creation timestamp."
+ },
+ "updated_at": {
+ "type": "string",
+ "description": "Update timestamp."
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/get-subscriber-whatsapp-session.json b/src/public/openapi/whatsapp/get-subscriber-whatsapp-session.json
new file mode 100644
index 0000000..62a640d
--- /dev/null
+++ b/src/public/openapi/whatsapp/get-subscriber-whatsapp-session.json
@@ -0,0 +1,162 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/subscribers/{id}/session": {
+ "get": {
+ "operationId": "getSubscriberWhatsAppSession",
+ "summary": "GET Subscriber WhatsApp Session",
+ "description": "Return whether the contact currently has an open 24-hour WhatsApp customer-service session. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "Subscriber/contact ID.",
+ "required": true,
+ "schema": {
+ "type": "integer"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "WhatsApp session information for the subscriber.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "session": {
+ "type": "object",
+ "properties": {
+ "has_active_session": {
+ "type": "boolean",
+ "description": "Whether the 24-hour session window is open."
+ },
+ "expires_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Session expiry timestamp."
+ },
+ "session_type": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Session source/type."
+ },
+ "message_count": {
+ "type": "integer",
+ "description": "Messages in the current window."
+ },
+ "total_sessions": {
+ "type": "integer",
+ "description": "Total tracked sessions."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The requested resource does not exist.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/get-subscriber-whatsapp-stats.json b/src/public/openapi/whatsapp/get-subscriber-whatsapp-stats.json
new file mode 100644
index 0000000..d3932f4
--- /dev/null
+++ b/src/public/openapi/whatsapp/get-subscriber-whatsapp-stats.json
@@ -0,0 +1,156 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/subscribers/{id}/stats": {
+ "get": {
+ "operationId": "getSubscriberWhatsAppStats",
+ "summary": "GET Subscriber WhatsApp Stats",
+ "description": "Return WhatsApp message counters for the contact profile stats panel. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "Subscriber/contact ID.",
+ "required": true,
+ "schema": {
+ "type": "integer"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "WhatsApp message counters for the subscriber.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "stats": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "integer",
+ "description": "Total WhatsApp messages."
+ },
+ "sent": {
+ "type": "integer",
+ "description": "Outbound messages with a send timestamp."
+ },
+ "received": {
+ "type": "integer",
+ "description": "Inbound messages received from the contact."
+ },
+ "campaign": {
+ "type": "integer",
+ "description": "WhatsApp campaign messages."
+ },
+ "read": {
+ "type": "integer",
+ "description": "Messages with a read receipt."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The requested resource does not exist.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/list-whatsapp-templates.json b/src/public/openapi/whatsapp/list-whatsapp-templates.json
new file mode 100644
index 0000000..1cb9615
--- /dev/null
+++ b/src/public/openapi/whatsapp/list-whatsapp-templates.json
@@ -0,0 +1,250 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/templates": {
+ "get": {
+ "operationId": "listWhatsAppTemplates",
+ "summary": "GET WhatsApp Templates",
+ "description": "List stored WhatsApp message templates and review-status counts. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "description": "Optional provider review status filter, for example APPROVED or PENDING.",
+ "required": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "approved_only",
+ "in": "query",
+ "description": "Return only approved templates when truthy.",
+ "required": false,
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "WhatsApp templates and status counts.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "templates": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WhatsAppTemplate"
+ }
+ },
+ "supports_sync": {
+ "type": "boolean",
+ "description": "Whether the current provider supports template sync."
+ },
+ "counts": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "integer",
+ "description": "Total template count."
+ },
+ "approved": {
+ "type": "integer",
+ "description": "Approved template count."
+ },
+ "pending": {
+ "type": "integer",
+ "description": "Pending template count."
+ },
+ "rejected": {
+ "type": "integer",
+ "description": "Rejected template count."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ },
+ "WhatsAppTemplate": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "description": "Template row ID."
+ },
+ "channel": {
+ "type": "string",
+ "description": "Template channel.",
+ "enum": [
+ "whatsapp"
+ ]
+ },
+ "provider": {
+ "type": "string",
+ "description": "Provider slug."
+ },
+ "name": {
+ "type": "string",
+ "description": "Provider template name."
+ },
+ "language": {
+ "type": "string",
+ "description": "Template language code."
+ },
+ "category": {
+ "type": "string",
+ "description": "Template category."
+ },
+ "status": {
+ "type": "string",
+ "description": "Provider review status."
+ },
+ "header_text": {
+ "type": "string",
+ "description": "Header text, when present."
+ },
+ "body_text": {
+ "type": "string",
+ "description": "Template body text."
+ },
+ "footer_text": {
+ "type": "string",
+ "description": "Footer text, when present."
+ },
+ "buttons": {
+ "type": "array",
+ "description": "Template buttons.",
+ "items": {
+ "type": "object"
+ }
+ },
+ "variables": {
+ "type": "object",
+ "description": "Template variable examples or defaults."
+ },
+ "provider_template_id": {
+ "type": "string",
+ "description": "Provider-side template ID."
+ },
+ "rejection_reason": {
+ "type": "string",
+ "description": "Provider rejection reason, when present."
+ },
+ "last_synced_at": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Last provider sync timestamp."
+ },
+ "created_by": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "description": "WordPress user ID that created the row."
+ },
+ "created_at": {
+ "type": "string",
+ "description": "Creation timestamp."
+ },
+ "updated_at": {
+ "type": "string",
+ "description": "Update timestamp."
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/send-subscriber-whatsapp-message.json b/src/public/openapi/whatsapp/send-subscriber-whatsapp-message.json
new file mode 100644
index 0000000..81d2ad8
--- /dev/null
+++ b/src/public/openapi/whatsapp/send-subscriber-whatsapp-message.json
@@ -0,0 +1,192 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/subscribers/{id}/send": {
+ "post": {
+ "operationId": "sendSubscriberWhatsAppMessage",
+ "summary": "POST Send Subscriber WhatsApp Message",
+ "description": "Send a one-off WhatsApp session message or approved template to a subscriber/contact. Session messages require an open 24-hour WhatsApp window. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "description": "Subscriber/contact ID.",
+ "required": true,
+ "schema": {
+ "type": "integer"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message_type": {
+ "type": "string",
+ "enum": [
+ "session",
+ "template"
+ ],
+ "description": "Send a free-form session message or an approved template.",
+ "default": "session"
+ },
+ "message": {
+ "type": "string",
+ "description": "Session message body."
+ },
+ "template_name": {
+ "type": "string",
+ "description": "Approved provider template name."
+ },
+ "template_language": {
+ "type": "string",
+ "description": "Template language variant."
+ },
+ "components": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ },
+ "description": "Provider template components/parameters."
+ }
+ },
+ "required": [
+ "message_type"
+ ]
+ },
+ "example": {
+ "message_type": "session",
+ "message": "Thanks for reaching out. How can we help?"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Message sent through the configured WhatsApp provider.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Success message."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The requested resource does not exist.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/sync-whatsapp-templates.json b/src/public/openapi/whatsapp/sync-whatsapp-templates.json
new file mode 100644
index 0000000..a6eb1a8
--- /dev/null
+++ b/src/public/openapi/whatsapp/sync-whatsapp-templates.json
@@ -0,0 +1,128 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/templates/sync": {
+ "post": {
+ "operationId": "syncWhatsAppTemplates",
+ "summary": "POST Sync WhatsApp Templates",
+ "description": "Sync WhatsApp templates from the configured provider into FluentCRM. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Templates synced from the provider.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Success message."
+ },
+ "synced": {
+ "type": "integer",
+ "description": "Number of templates seen in the provider catalogue."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/public/openapi/whatsapp/validate-whatsapp-template.json b/src/public/openapi/whatsapp/validate-whatsapp-template.json
new file mode 100644
index 0000000..2b9f109
--- /dev/null
+++ b/src/public/openapi/whatsapp/validate-whatsapp-template.json
@@ -0,0 +1,177 @@
+{
+ "openapi": "3.0.4",
+ "info": {
+ "title": "FluentCRM API",
+ "description": "Complete REST API documentation for FluentCRM \u2014 a self-hosted email marketing and CRM plugin for WordPress.",
+ "version": "1.0.0"
+ },
+ "servers": [
+ {
+ "url": "https://{website}/wp-json/fluent-crm/v2",
+ "description": "Your WordPress website",
+ "variables": {
+ "website": {
+ "default": "YourWebsite.com",
+ "description": "Your WordPress website domain (without https://)"
+ }
+ }
+ }
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "paths": {
+ "/whatsapp/templates/validate": {
+ "post": {
+ "operationId": "validateWhatsAppTemplate",
+ "summary": "POST Validate WhatsApp Template",
+ "description": "Validate a WhatsApp template payload without submitting it to the provider. **PRO** (requires FluentCampaign Pro WhatsApp module).\n\n\n\n**Required capability:** `fcrm_read_emails`\n\n_Enforced by `SMSPolicy::verifyRequest()`, the policy default for this route group._\n\n**Requires:** FluentCampaign Pro **with the SMS module enabled**. While SMS is switched off the route is not registered at all and returns a 404.\n\n",
+ "tags": [
+ "WhatsApp"
+ ],
+ "security": [
+ {
+ "ApplicationPasswords": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Template name."
+ },
+ "body_text": {
+ "type": "string",
+ "description": "Template body text."
+ },
+ "header_text": {
+ "type": "string",
+ "description": "Optional header text."
+ },
+ "footer_text": {
+ "type": "string",
+ "description": "Optional footer text."
+ },
+ "buttons": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ },
+ "description": "Template buttons."
+ },
+ "variables": {
+ "type": "object",
+ "description": "Template variable examples."
+ }
+ },
+ "required": [
+ "name",
+ "body_text"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Template validation result.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Blocking validation errors."
+ },
+ "warnings": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Non-blocking validation warnings."
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Not authenticated \u2014 missing or invalid credentials.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Authenticated but the user lacks the capability this route requires.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation failed \u2014 the response message names the offending field.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Error": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "description": "Human-readable error message"
+ },
+ "code": {
+ "type": "string",
+ "description": "Error code"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "integer",
+ "description": "HTTP status code"
+ }
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "ApplicationPasswords": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "Authorization",
+ "description": "WordPress Application Passwords \u2014 use Basic auth with your WordPress username and an application password in the format: username:application_password"
+ }
+ }
+ }
+}
diff --git a/src/rest-api/operations/pro-settings/get-whatsapp-settings.md b/src/rest-api/operations/pro-settings/get-whatsapp-settings.md
new file mode 100644
index 0000000..a98c650
--- /dev/null
+++ b/src/rest-api/operations/pro-settings/get-whatsapp-settings.md
@@ -0,0 +1,7 @@
+---
+title: Get WhatsApp Settings
+description: "Retrieve WhatsApp module settings, provider options, and webhook information. **PRO** (requires FluentCampaign Pro)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/pro-settings/save-whatsapp-settings.md b/src/rest-api/operations/pro-settings/save-whatsapp-settings.md
new file mode 100644
index 0000000..e326814
--- /dev/null
+++ b/src/rest-api/operations/pro-settings/save-whatsapp-settings.md
@@ -0,0 +1,7 @@
+---
+title: Save WhatsApp Settings
+description: "Save WhatsApp module settings, selected provider, and provider credentials. **PRO** (requires FluentCampaign Pro)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/create-whatsapp-template.md b/src/rest-api/operations/whatsapp/create-whatsapp-template.md
new file mode 100644
index 0000000..915e67c
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/create-whatsapp-template.md
@@ -0,0 +1,7 @@
+---
+title: Create WhatsApp Template
+description: "Submit a WhatsApp template to the configured provider for review. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/delete-whatsapp-template.md b/src/rest-api/operations/whatsapp/delete-whatsapp-template.md
new file mode 100644
index 0000000..69aa471
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/delete-whatsapp-template.md
@@ -0,0 +1,7 @@
+---
+title: Delete WhatsApp Template
+description: "Delete a WhatsApp template locally and from the provider when possible. Sent-message references are preserved by disabling referenced templates. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-messages.md b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-messages.md
new file mode 100644
index 0000000..a80b6cc
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-messages.md
@@ -0,0 +1,7 @@
+---
+title: Get Subscriber WhatsApp Messages
+description: "Retrieve paginated WhatsApp message history for a specific subscriber/contact. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-session.md b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-session.md
new file mode 100644
index 0000000..0c1623b
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-session.md
@@ -0,0 +1,7 @@
+---
+title: Get Subscriber WhatsApp Session
+description: "Return whether the contact currently has an open 24-hour WhatsApp customer-service session. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-stats.md b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-stats.md
new file mode 100644
index 0000000..0834d47
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/get-subscriber-whatsapp-stats.md
@@ -0,0 +1,7 @@
+---
+title: Get Subscriber WhatsApp Stats
+description: "Return WhatsApp message counters for the contact profile stats panel. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/list-whatsapp-templates.md b/src/rest-api/operations/whatsapp/list-whatsapp-templates.md
new file mode 100644
index 0000000..a0947a9
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/list-whatsapp-templates.md
@@ -0,0 +1,7 @@
+---
+title: List WhatsApp Templates
+description: "List stored WhatsApp message templates and review-status counts. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/send-subscriber-whatsapp-message.md b/src/rest-api/operations/whatsapp/send-subscriber-whatsapp-message.md
new file mode 100644
index 0000000..1c8d10e
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/send-subscriber-whatsapp-message.md
@@ -0,0 +1,7 @@
+---
+title: Send Subscriber WhatsApp Message
+description: "Send a one-off WhatsApp session message or approved template to a subscriber/contact. Session messages require an open 24-hour WhatsApp window. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/sync-whatsapp-templates.md b/src/rest-api/operations/whatsapp/sync-whatsapp-templates.md
new file mode 100644
index 0000000..82072f0
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/sync-whatsapp-templates.md
@@ -0,0 +1,7 @@
+---
+title: Sync WhatsApp Templates
+description: "Sync WhatsApp templates from the configured provider into FluentCRM. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+
diff --git a/src/rest-api/operations/whatsapp/validate-whatsapp-template.md b/src/rest-api/operations/whatsapp/validate-whatsapp-template.md
new file mode 100644
index 0000000..cb5cfed
--- /dev/null
+++ b/src/rest-api/operations/whatsapp/validate-whatsapp-template.md
@@ -0,0 +1,7 @@
+---
+title: Validate WhatsApp Template
+description: "Validate a WhatsApp template payload without submitting it to the provider. **PRO** (requires FluentCampaign Pro WhatsApp module)."
+outline: false
+aside: false
+---
+