application · active

TopoloMessages

Channel-agnostic business messaging: owns conversations, contacts, campaigns, templates, automations, and the outbound job pipeline. External providers (WhatsApp among them) are connectable channels behind it, not the product; provider state is read from the provider, not treated as the source of truth.

Documentation map

  • Topolo Messages — Public overview of Topolo Messages in the Topolo application suite.

Authority and runtime

System ID
topolo-messages
App IDs
app_topolo_messages
Owners
platform-engineering
Repositories
apps/TopoloMessages
Hosts
https://messages.topolo.app, https://messages.stg.topolo.us
Dependencies
topolo-auth, topolo-nexus, applications-packages

Security and data ownership

Risk tier
high
Tenant isolation
organization_scoped
Privacy classification
restricted
Storage
d1, r2, external_provider
Export and deletion
implemented
Enterprise ready
yes

Source-derived capability inventory

Source revisions: apps/TopoloMessages@8ad475d8acff71d013ffa7e496968950a9516a68

Declared actions: 32 · API routes: 2 · UI routes: 41

{
  "id": "topolo-messages",
  "name": "TopoloMessages",
  "slug": "topolo-messages",
  "kind": "application",
  "visibility": "public",
  "repo_paths": [
    "apps/TopoloMessages"
  ],
  "source_revisions": [
    {
      "source_path": "apps/TopoloMessages",
      "repository": "apps/TopoloMessages",
      "revision": "8ad475d8acff71d013ffa7e496968950a9516a68",
      "ref": "origin/staging"
    }
  ],
  "source_counts": {
    "source_files": 87,
    "test_files": 56,
    "test_cases": 0,
    "migration_files": 18,
    "database_tables": 0,
    "manifests": 1,
    "deploy_targets": 3,
    "actions": 32,
    "mobile_contracts": 1,
    "notifications": 8,
    "package_manifests": 1,
    "deployment_configs": 0
  },
  "manifests": [
    {
      "source_path": "apps/TopoloMessages/topolo.app.json",
      "service_slug": "topolo-messages",
      "name": "topolo-messages",
      "app_id": "app_topolo_messages",
      "compatibility_date": "2026-04-16",
      "primary_target": "web",
      "environments": [
        "development",
        "production",
        "staging"
      ],
      "targets": [
        {
          "name": "api",
          "kind": "worker",
          "directory": "apps/api",
          "main": "src/worker.ts",
          "worker_name": "topolo-messages-api",
          "subdomain": null,
          "healthcheck_path": "/api/health",
          "variable_names": [
            "AUTH_API_URL",
            "ENVIRONMENT",
            "MESSAGES_INBOUND_WEBHOOK_URL",
            "MESSAGES_PUBLIC_BASE_URL",
            "NEXUS_GATEWAY_URL",
            "TOPOLO_NOTIFY_URL"
          ],
          "secret_names": [],
          "bindings": [
            {
              "kind": "d1",
              "binding": "MESSAGES_CORE_DB",
              "target": null
            },
            {
              "kind": "d1",
              "binding": "MESSAGES_TRAFFIC_DB",
              "target": null
            },
            {
              "kind": "d1",
              "binding": "MESSAGES_DELIVERY_DB",
              "target": null
            },
            {
              "kind": "r2",
              "binding": "MESSAGES_ARCHIVE",
              "target": null
            },
            {
              "kind": "secretsStore",
              "binding": "PLATFORM_AT_REST_MASTER_ENCRYPTION_KEY_STORE",
              "target": null
            },
            {
              "kind": "secretsStore",
              "binding": "PLATFORM_AT_REST_MASTER_ENCRYPTION_KEY_PREVIOUS_STORE",
              "target": null
            },
            {
              "kind": "vectorize",
              "binding": "MESSAGES_SEMANTIC_INDEX",
              "target": null
            },
            {
              "kind": "ai",
              "binding": "AI",
              "target": null
            }
          ]
        },
        {
          "name": "web",
          "kind": "worker",
          "directory": "apps/web",
          "main": "src/worker.ts",
          "worker_name": "topolo-messages",
          "subdomain": "messages",
          "healthcheck_path": "/api/health",
          "variable_names": [
            "INSIGHTS_SITE_KEY"
          ],
          "secret_names": [],
          "bindings": [
            {
              "kind": "services",
              "binding": "API",
              "target": null
            },
            {
              "kind": "services",
              "binding": "API",
              "target": null
            },
            {
              "kind": "services",
              "binding": "API",
              "target": null
            }
          ]
        },
        {
          "name": "jobs",
          "kind": "worker",
          "directory": "apps/jobs",
          "main": "src/worker.ts",
          "worker_name": "topolo-messages-dispatch",
          "subdomain": null,
          "healthcheck_path": "/health",
          "variable_names": [
            "AUTH_API_URL",
            "ENVIRONMENT",
            "MESSAGES_PUBLIC_BASE_URL",
            "NEXUS_GATEWAY_URL",
            "TOPOLO_NOTIFY_URL",
            "WHATSAPP_GRAPH_API_VERSION",
            "WHATSAPP_TEMPLATE_LANGUAGE_DEFAULT"
          ],
          "secret_names": [],
          "bindings": [
            {
              "kind": "d1",
              "binding": "MESSAGES_CORE_DB",
              "target": null
            },
            {
              "kind": "d1",
              "binding": "MESSAGES_TRAFFIC_DB",
              "target": null
            },
            {
              "kind": "d1",
              "binding": "MESSAGES_DELIVERY_DB",
              "target": null
            },
            {
              "kind": "secretsStore",
              "binding": "PLATFORM_AT_REST_MASTER_ENCRYPTION_KEY_STORE",
              "target": null
            },
            {
              "kind": "secretsStore",
              "binding": "PLATFORM_AT_REST_MASTER_ENCRYPTION_KEY_PREVIOUS_STORE",
              "target": null
            }
          ]
        }
      ],
      "notifications": [
        "messages.campaign.completed",
        "messages.campaign.failed",
        "messages.message.delivery_failed",
        "messages.message.received",
        "messages.number.verification_changed",
        "messages.provider.degraded",
        "messages.template.approved",
        "messages.template.rejected"
      ],
      "notification_contract": {
        "source_path": "topolo.notification-contracts.json",
        "role": "producer",
        "schema_version": 1,
        "owner_app_id": "app_topolo_messages",
        "events": [
          {
            "type": "messages.campaign.completed",
            "version": 1,
            "description": "All recipients in a persisted Messages campaign reached a terminal state with at least one successful delivery.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "campaign_id",
                    "status",
                    "sent_count",
                    "failed_count"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Campaign completed: July launch",
                "body": "All campaign recipients reached a terminal delivery state.",
                "object_id": "campaign_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/campaigns/campaign_123",
                "payload": {
                  "campaign_id": "campaign_123",
                  "status": "completed",
                  "sent_count": 10,
                  "failed_count": 1
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:campaign-completed:"
            }
          },
          {
            "type": "messages.campaign.failed",
            "version": 1,
            "description": "A persisted Messages campaign reached a terminal state without a successful recipient delivery.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "campaign_id",
                    "status",
                    "failed_count"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Campaign failed: July launch",
                "body": "The campaign ended without a successful recipient delivery.",
                "object_id": "campaign_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/campaigns/campaign_123",
                "payload": {
                  "campaign_id": "campaign_123",
                  "status": "failed",
                  "sent_count": 0,
                  "failed_count": 10
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:campaign-failed:"
            }
          },
          {
            "type": "messages.message.delivery_failed",
            "version": 1,
            "description": "An outbound message and its delivery job durably reached the failed state after retry policy was exhausted or dispatch was rejected.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "message_id",
                    "outbound_job_id",
                    "provider",
                    "error"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Message delivery failed",
                "body": "Provider rejected the request.",
                "object_id": "message_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/conversations?message=message_123",
                "payload": {
                  "message_id": "message_123",
                  "outbound_job_id": "job_123",
                  "provider": "whatsapp_cloud_api",
                  "error": "Provider rejected the request."
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:delivery-failed:"
            }
          },
          {
            "type": "messages.message.received",
            "version": 1,
            "description": "Messages persisted a new inbound provider message and updated its conversation unread state.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "message_id",
                    "conversation_id",
                    "contact_id",
                    "number_id",
                    "message_type"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "New message received",
                "body": "A contact sent a new message to your shared inbox.",
                "object_id": "message_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/conversations/conversation_123",
                "payload": {
                  "message_id": "message_123",
                  "conversation_id": "conversation_123",
                  "contact_id": "contact_123",
                  "number_id": "number_123",
                  "message_type": "text"
                }
              }
            ],
            "dataClassification": "confidential",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:message-received:"
            }
          },
          {
            "type": "messages.number.verification_changed",
            "version": 1,
            "description": "Messages durably mirrored an approved or rejected provider display-name verification decision for a connected number.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "number_id",
                    "status",
                    "decision"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Number verification approved",
                "body": "Meta approved the verified display name for this number.",
                "object_id": "number_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/settings/numbers/number_123",
                "payload": {
                  "number_id": "number_123",
                  "status": "verified",
                  "decision": "approved"
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:number-verification:"
            }
          },
          {
            "type": "messages.provider.degraded",
            "version": 1,
            "description": "Messages persisted an open provider incident after a provider/configuration failure made an outbound job terminal.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "incident_id",
                    "provider",
                    "outbound_job_id",
                    "reason",
                    "status"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Messaging provider degraded",
                "body": "Provider is unavailable.",
                "object_id": "incident_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/settings/providers",
                "payload": {
                  "incident_id": "incident_123",
                  "provider": "whatsapp_cloud_api",
                  "outbound_job_id": "job_123",
                  "reason": "Provider is unavailable.",
                  "status": "open"
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:provider-degraded:"
            }
          },
          {
            "type": "messages.template.approved",
            "version": 1,
            "description": "Messages durably mirrored Meta approval of an app-created message template.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "template_id",
                    "status"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Template approved: order_update",
                "body": "Meta approved this message template for sending.",
                "object_id": "template_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/templates/template_123",
                "payload": {
                  "template_id": "template_123",
                  "template_name": "order_update",
                  "status": "approved"
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:template-approved:"
            }
          },
          {
            "type": "messages.template.rejected",
            "version": 1,
            "description": "Messages durably mirrored Meta rejection of an app-created message template.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "cta_url",
                "payload"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "payload": {
                  "type": "object",
                  "required": [
                    "template_id",
                    "status"
                  ]
                }
              },
              "additionalProperties": true
            },
            "examples": [
              {
                "title": "Template rejected: order_update",
                "body": "Meta rejected this message template.",
                "object_id": "template_123",
                "occurred_at": "2026-07-20T12:00:00.000Z",
                "cta_url": "https://messages.topolo.app/templates/template_123",
                "payload": {
                  "template_id": "template_123",
                  "template_name": "order_update",
                  "status": "rejected"
                }
              }
            ],
            "dataClassification": "internal",
            "recipients": {
              "modes": [
                "organization_member"
              ],
              "externalAddress": "forbidden"
            },
            "sensitiveFields": [],
            "idempotency": {
              "required": true,
              "pattern": "^messages:template-rejected:"
            }
          }
        ]
      },
      "actions": [
        {
          "name": "widget.get",
          "title": "Get widget summary",
          "description": "Get the TopoloOne widget summary for this service.",
          "method": "GET",
          "path": "/api/widget",
          "permission": "context:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "type": "object",
            "additionalProperties": true
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/widget",
              "body": null
            },
            "effects": "Reads state through GET /api/widget without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "GET /api/widget",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "bootstrap.get",
          "title": "Get messages bootstrap",
          "description": "Get Messages workspace bootstrap data.",
          "method": "GET",
          "path": "/api/messages/bootstrap",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get messages bootstrap.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/bootstrap",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/bootstrap without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/bootstrap",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "analytics.get",
          "title": "Get messages analytics",
          "description": "Get messaging volume, delivery, contact consent, and campaign health metrics.",
          "method": "GET",
          "path": "/api/messages/analytics",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get messages analytics.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/analytics",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/analytics without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/analytics",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "provider_status.get",
          "title": "Get messages provider status",
          "description": "Get WhatsApp provider queue, webhook, and runtime configuration status for a Messages workspace.",
          "method": "GET",
          "path": "/api/messages/provider-status",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get messages provider status.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/provider-status",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/provider-status without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/provider-status",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "conversations.list",
          "title": "List conversations",
          "description": "List message conversations.",
          "method": "GET",
          "path": "/api/messages/conversations",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List conversations.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/conversations",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/conversations without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/conversations",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "contacts.list",
          "title": "List contacts",
          "description": "List WhatsApp contacts, consent state, and recent conversation activity.",
          "method": "GET",
          "path": "/api/messages/contacts",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "consentStatus": {
                "type": "string",
                "enum": [
                  "unknown",
                  "opted_in",
                  "opted_out"
                ]
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 250
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List contacts.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example",
              "consentStatus": "unknown",
              "limit": 1
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/contacts",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/contacts without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/contacts",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "contacts.update",
          "title": "Update contact",
          "description": "Update a WhatsApp contact consent state.",
          "method": "PATCH",
          "path": "/api/messages/contacts/{contactId}",
          "permission": "messages:send",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "contactId": {
                "type": "string",
                "minLength": 1
              },
              "consentStatus": {
                "type": "string",
                "enum": [
                  "unknown",
                  "opted_in",
                  "opted_out"
                ]
              }
            },
            "required": [
              "contactId",
              "consentStatus"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Update contact.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "contactId": "example",
              "consentStatus": "unknown"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PATCH",
              "path": "/api/messages/contacts/example",
              "body": {
                "contactId": "example",
                "consentStatus": "unknown"
              }
            },
            "effects": "May change state through PATCH /api/messages/contacts/{contactId}. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PATCH /api/messages/contacts/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "conversations.update",
          "title": "Update conversation",
          "description": "Update a messaging conversation state, assignment, follow-up, or contact context.",
          "method": "PATCH",
          "path": "/api/messages/conversations/{conversationId}",
          "permission": "messages:send",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "conversationId": {
                "type": "string",
                "minLength": 1
              },
              "state": {
                "type": "string",
                "enum": [
                  "open",
                  "pending",
                  "resolved",
                  "archived"
                ]
              },
              "assignedToUserId": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "assignToMe": {
                "type": "boolean"
              },
              "clearAssignment": {
                "type": "boolean"
              },
              "markRead": {
                "type": "boolean"
              },
              "contactConsentStatus": {
                "type": "string",
                "enum": [
                  "unknown",
                  "opted_in",
                  "opted_out"
                ]
              },
              "priority": {
                "type": "string",
                "enum": [
                  "normal",
                  "high",
                  "urgent"
                ]
              },
              "internalNote": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 2000
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "followUpAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "conversationId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Update conversation.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "conversationId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PATCH",
              "path": "/api/messages/conversations/example",
              "body": {
                "conversationId": "example"
              }
            },
            "effects": "May change state through PATCH /api/messages/conversations/{conversationId}. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PATCH /api/messages/conversations/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "messages.send",
          "title": "Send message",
          "description": "Send an outbound message.",
          "method": "POST",
          "path": "/api/messages/messages/send",
          "permission": "messages:send",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "numberId": {
                "type": "string",
                "minLength": 1
              },
              "messageType": {
                "type": "string",
                "enum": [
                  "text",
                  "template"
                ]
              },
              "body": {
                "type": "string",
                "minLength": 1
              },
              "templateName": {
                "type": "string",
                "minLength": 1
              },
              "recipientPhone": {
                "type": "string",
                "minLength": 1
              },
              "phoneNumber": {
                "type": "string",
                "minLength": 1
              },
              "waId": {
                "type": "string",
                "minLength": 1
              },
              "recipientName": {
                "type": "string",
                "minLength": 1
              },
              "payload": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              }
            },
            "required": [
              "numberId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Send message.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "numberId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/messages/send",
              "body": {
                "numberId": "example"
              }
            },
            "effects": "May change state through POST /api/messages/messages/send. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/messages/send",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "campaigns.list",
          "title": "List campaigns",
          "description": "List messaging campaigns.",
          "method": "GET",
          "path": "/api/messages/campaigns",
          "permission": "campaigns:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List campaigns.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/campaigns",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/campaigns without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/campaigns",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.list",
          "title": "List templates",
          "description": "List WhatsApp message templates.",
          "method": "GET",
          "path": "/api/messages/templates",
          "permission": "campaigns:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List templates.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/templates",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/templates without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/templates",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.create",
          "title": "Create template",
          "description": "Register a WhatsApp message template.",
          "method": "POST",
          "path": "/api/messages/templates",
          "permission": "campaigns:manage",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1
              },
              "language": {
                "type": "string",
                "minLength": 1
              },
              "category": {
                "type": "string",
                "enum": [
                  "marketing",
                  "utility",
                  "authentication",
                  "service"
                ]
              },
              "sampleBody": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "name",
              "sampleBody"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Create template.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "name": "example",
              "sampleBody": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/templates",
              "body": {
                "name": "example",
                "sampleBody": "example"
              }
            },
            "effects": "May change state through POST /api/messages/templates. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/templates",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "outbound_jobs.list",
          "title": "List outbound jobs",
          "description": "List recent outbound WhatsApp delivery jobs.",
          "method": "GET",
          "path": "/api/messages/outbound-jobs",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "status": {
                "type": "string",
                "minLength": 1
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List outbound jobs.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example",
              "status": "example",
              "limit": 1
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/outbound-jobs",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/outbound-jobs without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/outbound-jobs",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "webhook_events.list",
          "title": "List webhook events",
          "description": "List recent WhatsApp webhook intake events.",
          "method": "GET",
          "path": "/api/messages/webhook-events",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "status": {
                "type": "string",
                "minLength": 1
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List webhook events.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example",
              "status": "example",
              "limit": 1
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/webhook-events",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/webhook-events without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/webhook-events",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "campaigns.create",
          "title": "Create campaign",
          "description": "Create a messaging campaign.",
          "method": "POST",
          "path": "/api/messages/campaigns",
          "permission": "campaigns:manage",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1
              },
              "numberId": {
                "type": "string",
                "minLength": 1
              },
              "templateName": {
                "type": "string",
                "minLength": 1
              },
              "templateLanguage": {
                "type": "string",
                "minLength": 1
              },
              "templateParameters": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "templateParametersText": {
                "type": "string",
                "minLength": 1
              },
              "audienceSource": {
                "type": "string",
                "minLength": 1
              },
              "scheduledAt": {
                "type": "string",
                "minLength": 1
              },
              "recipientsText": {
                "type": "string",
                "minLength": 1
              },
              "recipients": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "phoneNumber": {
                      "type": "string",
                      "minLength": 1
                    },
                    "phone": {
                      "type": "string",
                      "minLength": 1
                    },
                    "recipientPhone": {
                      "type": "string",
                      "minLength": 1
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1
                    },
                    "recipientName": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Create campaign.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "name": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/campaigns",
              "body": {
                "name": "example"
              }
            },
            "effects": "May change state through POST /api/messages/campaigns. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/campaigns",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "campaigns.recipients.list",
          "title": "List campaign recipients",
          "description": "List recipients and delivery state for a messaging campaign.",
          "method": "GET",
          "path": "/api/messages/campaigns/{campaignId}/recipients",
          "permission": "campaigns:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "campaignId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "campaignId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List campaign recipients.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "campaignId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/campaigns/example/recipients",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/campaigns/{campaignId}/recipients without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/campaigns/*/recipients",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "automations.list",
          "title": "List automations",
          "description": "List messaging automations.",
          "method": "GET",
          "path": "/api/messages/automations",
          "permission": "automations:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List automations.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/automations",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/automations without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/automations",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "automations.runs.list",
          "title": "List automation runs",
          "description": "List recent messaging automation execution runs.",
          "method": "GET",
          "path": "/api/messages/automations/runs",
          "permission": "automations:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "automationId": {
                "type": "string",
                "minLength": 1
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List automation runs.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example",
              "automationId": "example",
              "limit": 1
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/automations/runs",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/automations/runs without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/automations/runs",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "campaigns.launch",
          "title": "Launch campaign",
          "description": "Queue a drafted messaging campaign for pending recipients.",
          "method": "POST",
          "path": "/api/messages/campaigns/{campaignId}/launch",
          "permission": "campaigns:manage",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "campaignId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "campaignId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Launch campaign.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "campaignId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/campaigns/example/launch",
              "body": {
                "campaignId": "example"
              }
            },
            "effects": "May change state through POST /api/messages/campaigns/{campaignId}/launch. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/campaigns/*/launch",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "automations.create",
          "title": "Create automation",
          "description": "Create a messaging automation.",
          "method": "POST",
          "path": "/api/messages/automations",
          "permission": "automations:manage",
          "readOnly": false,
          "requiresConfirmation": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1
              },
              "triggerType": {
                "type": "string",
                "minLength": 1
              },
              "status": {
                "type": "string",
                "minLength": 1
              },
              "numberId": {
                "type": "string",
                "minLength": 1
              },
              "definition": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              }
            },
            "required": [
              "name",
              "triggerType"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Create automation.",
            "additionalProperties": true
          },
          "destructive": false,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "name": "example",
              "triggerType": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/automations",
              "body": {
                "name": "example",
                "triggerType": "example"
              }
            },
            "effects": "May change state through POST /api/messages/automations. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/automations",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "numbers.list",
          "title": "List numbers",
          "description": "List messaging phone numbers.",
          "method": "GET",
          "path": "/api/messages/numbers",
          "permission": "numbers:manage",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List numbers.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/numbers",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/numbers without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/numbers",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "workspaces.delete",
          "title": "Delete workspace",
          "description": "Delete an empty, non-default Messages workspace.",
          "method": "DELETE",
          "path": "/api/messages/workspaces/{workspaceId}",
          "permission": "workspace:delete",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "workspaceId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Delete workspace.",
            "additionalProperties": true
          },
          "readOnly": false,
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/messages/workspaces/example",
              "body": null
            },
            "effects": "May change state through DELETE /api/messages/workspaces/{workspaceId}. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/messages/workspaces/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "contacts.get",
          "title": "Get contact",
          "description": "Get one Messages contact.",
          "method": "GET",
          "path": "/api/messages/contacts/{contactId}",
          "permission": "inbox:read",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "contactId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "contactId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get contact.",
            "additionalProperties": true
          },
          "readOnly": true,
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "contactId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/contacts/example",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/contacts/{contactId} without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/contacts/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "conversations.get",
          "title": "Get conversation",
          "description": "Get one Messages conversation.",
          "method": "GET",
          "path": "/api/messages/conversations/{conversationId}",
          "permission": "inbox:read",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "conversationId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "conversationId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get conversation.",
            "additionalProperties": true
          },
          "readOnly": true,
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "conversationId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/conversations/example",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/conversations/{conversationId} without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/conversations/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "conversation_messages.list",
          "title": "List conversation messages",
          "description": "List message history for one conversation.",
          "method": "GET",
          "path": "/api/messages/conversations/{conversationId}/messages",
          "permission": "inbox:read",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "conversationId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "conversationId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by List conversation messages.",
            "additionalProperties": true
          },
          "readOnly": true,
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "conversationId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/conversations/example/messages",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/conversations/{conversationId}/messages without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/conversations/*/messages",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.get",
          "title": "Get template",
          "description": "Get one Messages template.",
          "method": "GET",
          "path": "/api/messages/templates/{templateId}",
          "permission": "inbox:read",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "templateId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "templateId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get template.",
            "additionalProperties": true
          },
          "readOnly": true,
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "templateId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/templates/example",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/templates/{templateId} without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/templates/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "campaigns.get",
          "title": "Get campaign",
          "description": "Get one Messages campaign.",
          "method": "GET",
          "path": "/api/messages/campaigns/{campaignId}",
          "permission": "inbox:read",
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              },
              "campaignId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "campaignId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Get campaign.",
            "additionalProperties": true
          },
          "readOnly": true,
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "campaignId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/campaigns/example",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/campaigns/{campaignId} without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/campaigns/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "channels.connect",
          "title": "Connect channel",
          "description": "Connect a messaging channel to the active Messages workspace by exchanging a provider authorization code. WhatsApp today; the same action serves other channels.",
          "method": "POST",
          "path": "/api/messages/channels/connect",
          "permission": "numbers:manage",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "channel": {
                "type": "string",
                "enum": [
                  "whatsapp"
                ]
              },
              "code": {
                "type": "string",
                "minLength": 1
              },
              "accountId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "code",
              "accountId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Response returned by Connect channel.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {
              "code": "example",
              "accountId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/channels/connect",
              "body": {
                "code": "example",
                "accountId": "example"
              }
            },
            "effects": "May change state through POST /api/messages/channels/connect. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/channels/connect",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "messages.semantic_search",
          "title": "Search messages semantically",
          "description": "Find workspace-scoped message content by meaning without storing plaintext in the semantic index.",
          "method": "POST",
          "path": "/api/messages/semantic-search",
          "permission": "inbox:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "searchText": {
                "type": "string",
                "minLength": 2,
                "maxLength": 1000
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 25
              }
            },
            "required": [
              "searchText"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Workspace-scoped semantic message matches with decrypted content returned only to the authorized caller.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "searchText": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/messages/semantic-search",
              "body": {
                "searchText": "example"
              }
            },
            "effects": "Reads state through POST /api/messages/semantic-search without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/messages/semantic-search",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "privacy.protection.canary",
          "title": "Check Messages data protection",
          "description": "Verify canonical Messages protected fields decrypt under the active D1 application root.",
          "method": "GET",
          "path": "/api/messages/privacy/protection/canary",
          "permission": "workspace:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Messages protection canary result without plaintext or key material.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/privacy/protection/canary",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/privacy/protection/canary without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/privacy/protection/canary",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "privacy.export",
          "title": "Export workspace data",
          "description": "Export all Messages records for one authorized workspace with protected content decrypted for the requester.",
          "method": "GET",
          "path": "/api/messages/privacy/export",
          "permission": "workspace:read",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "workspaceId": {
                "type": "string",
                "minLength": 1
              }
            },
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Workspace-scoped Messages data export.",
            "additionalProperties": true
          },
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "documentation": {
            "example_input": {
              "workspaceId": "example"
            },
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/messages/privacy/export",
              "body": null
            },
            "effects": "Reads state through GET /api/messages/privacy/export without a declared mutation.",
            "verification": [
              "Check the structured action result and pagination or resource identifiers before using it downstream."
            ],
            "recovery": [
              "Correct identity, resource context, permission, or input validation failures, then retry the read."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/messages/privacy/export",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "privacy.delete",
          "title": "Erase workspace data",
          "description": "Permanently erase all Messages content in one authorized workspace while retaining its workspace identity.",
          "method": "DELETE",
          "path": "/api/messages/privacy",
          "permission": "workspace:delete",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "target": "api",
          "outputSchema": {
            "type": "object",
            "description": "Workspace-scoped Messages erasure result.",
            "additionalProperties": true
          },
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-messages --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/messages/privacy",
              "body": null
            },
            "effects": "May change state through DELETE /api/messages/privacy. Inspect the plan and honor the published confirmation policy.",
            "verification": [
              "Check the structured action result.",
              "Read the affected resource back through the corresponding get or list action."
            ],
            "recovery": [
              "Do not retry an ambiguous mutation until a read confirms whether it applied.",
              "Use a published inverse, update, archive, or delete action only after inspecting its contract."
            ],
            "docs_url": null,
            "resource": null,
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/messages/privacy",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        }
      ],
      "action_coverage": {
        "status": "ok",
        "served_routes": 32,
        "matched_actions": 31,
        "declared_unserved_actions": [
          "GET /api/widget"
        ],
        "coverage_excluded_actions": [],
        "uncatalogued_routes": [],
        "ignored_routes": 1,
        "configured_exclusions": 3,
        "configuration_findings": [
          "* /api/auth/*: exclusion matches no served route",
          "* /api/messages/*: exclusion matches no served route",
          "POST /api/messages/whatsapp/webhook: exclusion matches no served route"
        ],
        "notes": []
      },
      "runtime_contract_audit": {
        "status": "verified",
        "actions": 32,
        "contracts": 32,
        "contract_module": "topolo.action-contracts.mjs",
        "validator_sources": [
          "apps/api/src/worker.ts"
        ],
        "authorization_sources": [
          "apps/api/src/worker.ts"
        ],
        "findings": []
      }
    }
  ],
  "mobile_contracts": [
    {
      "source_path": "apps/TopoloMessages/topolo.mobile-experience.json",
      "contract": {
        "version": "2026-06-29",
        "status": "approved",
        "mode": "native_capability",
        "appId": "app_topolo_messages",
        "localizationNamespace": "messages",
        "permissions": [
          "inbox:read",
          "campaigns:manage"
        ],
        "offlinePolicy": "read_through_cache",
        "fallbackPath": "/conversations",
        "auth": {
          "audience": "topolo-messages",
          "scopes": [
            "inbox:read",
            "campaigns:manage"
          ]
        },
        "routes": [
          {
            "path": "/conversations",
            "apiPath": "/api/messages/conversations",
            "title": "Conversations",
            "titleKey": "messages.InboxRoute.conversations",
            "template": "record.list",
            "dataSource": "messages.conversations.list",
            "detailRoute": "/conversations/:id"
          },
          {
            "path": "/conversations/:id",
            "apiPath": "/api/messages/conversations/:id",
            "title": "Conversations",
            "titleKey": "messages.InboxRoute.conversations",
            "template": "record.detail",
            "dataSource": "messages.conversations.detail"
          },
          {
            "path": "/contacts",
            "apiPath": "/api/messages/contacts",
            "title": "Contacts",
            "titleKey": "messages.nav.contacts.label",
            "template": "record.list",
            "dataSource": "messages.contacts.list",
            "detailRoute": "/contacts/:id"
          },
          {
            "path": "/contacts/:id",
            "apiPath": "/api/messages/contacts/:id",
            "title": "Contacts",
            "titleKey": "messages.nav.contacts.label",
            "template": "record.detail",
            "dataSource": "messages.contacts.detail"
          },
          {
            "path": "/campaigns",
            "apiPath": "/api/messages/campaigns",
            "title": "Campaigns",
            "titleKey": "messages.nav.campaigns.label",
            "template": "record.list",
            "dataSource": "messages.campaigns.list",
            "detailRoute": "/campaigns/:id"
          },
          {
            "path": "/campaigns/:id",
            "apiPath": "/api/messages/campaigns/:id",
            "title": "Campaigns",
            "titleKey": "messages.nav.campaigns.label",
            "template": "record.detail",
            "dataSource": "messages.campaigns.detail"
          },
          {
            "path": "/templates",
            "apiPath": "/api/messages/templates",
            "title": "Templates",
            "titleKey": "messages.nav.templates.label",
            "template": "record.list",
            "dataSource": "messages.templates.list",
            "detailRoute": "/templates/:id"
          },
          {
            "path": "/templates/:id",
            "apiPath": "/api/messages/templates/:id",
            "title": "Templates",
            "titleKey": "messages.nav.templates.label",
            "template": "record.detail",
            "dataSource": "messages.templates.detail"
          }
        ]
      }
    }
  ],
  "package_manifests": [],
  "deployment_configs": [],
  "source_signals": {
    "api_routes": [
      {
        "method": "ALL",
        "path": "*",
        "source_path": "apps/TopoloMessages/apps/api/src/worker.ts"
      },
      {
        "method": "GET",
        "path": "/health",
        "source_path": "apps/TopoloMessages/apps/jobs/src/worker.ts"
      }
    ],
    "ui_routes": [
      {
        "path": "/campaigns/${encodeURIComponent(campaignId)}",
        "source_path": "apps/TopoloMessages/apps/api/functions/api/messages/campaigns.ts"
      },
      {
        "path": "/api/widget",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/bootstrap",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/workspaces/{workspaceId}",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/privacy/export",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/privacy",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/privacy/protection/canary",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/semantic-search",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/analytics",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/provider-status",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/conversations",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/contacts",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/contacts/{contactId}",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/conversations/{conversationId}",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/conversations/{conversationId}/messages",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/messages/send",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/campaigns",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/campaigns/{campaignId}",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/templates",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/templates/{templateId}",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/outbound-jobs",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/webhook-events",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/campaigns/{campaignId}/recipients",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/campaigns/{campaignId}/launch",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/automations",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/automations/runs",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/numbers",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/api/messages/channels/connect",
        "source_path": "apps/TopoloMessages/apps/api/src/topolo.action-contracts.mjs"
      },
      {
        "path": "/health",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/inbox",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/contacts",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/analytics",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/numbers",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/templates",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/campaigns",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/deliveries",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/automations",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/webhooks",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/getting-started",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/settings",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      },
      {
        "path": "/settings/:section",
        "source_path": "apps/TopoloMessages/apps/web/src/App.tsx"
      }
    ],
    "test_cases": [],
    "database_tables": []
  },
  "documentation": {
    "declared_paths": [
      "internal/apps/messages",
      "applications/messages"
    ],
    "present_paths": [
      "internal/apps/messages",
      "applications/messages"
    ],
    "missing_paths": [],
    "human_reference": "/systems/topolo-messages",
    "machine_reference": "/machine/systems/topolo-messages.json",
    "action_examples": 32,
    "action_schemas": 32
  },
  "source_findings": [
    {
      "type": "declared_unserved_actions",
      "source_path": "apps/TopoloMessages/topolo.app.json",
      "detail": [
        "GET /api/widget"
      ]
    },
    {
      "type": "action_coverage_configuration",
      "source_path": "apps/TopoloMessages/topolo.app.json",
      "detail": [
        "* /api/auth/*: exclusion matches no served route",
        "* /api/messages/*: exclusion matches no served route",
        "POST /api/messages/whatsapp/webhook: exclusion matches no served route"
      ]
    }
  ]
}