Meta Pixel Spur MCP Tools Reference
Docs / MCP
Tools

Spur MCP tool catalog

Each tool below includes required inputs, operational notes, and JSON-RPC examples.

Meta spec-aligned template guidance

The guidance below aligns with Meta Business Messaging OpenAPI v23.0 template concepts and is adapted for Spur MCP draft payloads.

Reference: business-messaging-api_v23.0.yaml

  • Meta template objects require a name and language. Use deterministic language values such as en or en_US.
  • Meta runtime component types are commonly header, body, and button. Spur draft payloads use uppercase style such as HEADER, BODY, and BUTTONS.
  • For variable placeholders in body text ({{1}}, {{2}}), always include example.body_text sample values.
  • Supported parameter families include text, currency, date/time, and media. For media templates, provide explicit image/video/document structure. PDF is the safe document default.
  • Button text and payload rules are strict. Keep quick replies and URL suffixes short and final before submission.

Recommended MCP workflow for complex templates

  1. Call template_search to find a close existing template by name/category.
  2. Call template_requirements to generate runtime payload requirements and sample contentMessage.
  3. Build a new payload with template_create_draft using reviewed component structure.
  4. Call template_submit_for_review with the returned draft ID.
  5. If submission fails, read providerError fields (error_user_msg, error_subcode, fbtrace_id), adjust payload, and retry.
  6. Call template_refresh to sync latest review state before sending campaigns.

Broadcast lifecycle flow (recommended)

  1. Call segment_filters_catalog to discover valid filter fields/operators.
  2. Create or locate audience segments with segment_create or segment_search.
  3. Call template_requirements before campaign creation, especially for carousel templates.
  4. Create draft campaign using broadcast_create and a template reference.
  5. Update variables and audience operations with broadcast_update ( includeSet, includeAdd, excludeAdd, sendAt, deliveryBoost, splitAcrossDays ).
  6. Launch the campaign with broadcast_launch.
  7. Track performance via broadcast_analytics and broadcast_overview_stats.

template_create_draft

Creates a WhatsApp template draft inside Spur.

Required fields

  • name
  • channelId
  • category
  • format
  • language
  • components

Optional fields

  • subCategory

Behavior notes

  • category: MARKETING | UTILITY | AUTHENTICATION
  • format: SINGLE | CAROUSEL
  • Creates draft only and does not submit to Meta
  • Template name should be lowercase with underscores for reliable Meta acceptance
  • When BODY has variables ({{1}}, {{2}}), include example.body_text values to avoid review failures
  • BUTTON text must exactly match what you intend to submit. Meta is strict about button text mismatches

Example request

{
  "jsonrpc": "2.0",
  "id": 11,
  "method": "tools/call",
  "params": {
    "name": "template_create_draft",
    "arguments": {
      "name": "order_update_template",
      "channelId": 101,
      "category": "UTILITY",
      "format": "SINGLE",
      "language": "en",
      "components": {
        "body": "Your order update text"
      }
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "draftTemplateId": 873,
  "templateSummary": {
    "name": "order_update_template",
    "channelId": 101,
    "category": "UTILITY",
    "language": "en",
    "format": "SINGLE"
  }
}

template_create_draft (complex utility example)

Reference payload pattern for variable-rich utility templates with header and quick reply buttons.

Required fields

  • name
  • channelId
  • category
  • format
  • language
  • components

Optional fields

  • subCategory

Behavior notes

  • Use this shape when you need placeholders, deterministic button options, and production-safe examples
  • Quick replies should be concise and final before submitting for review
  • BODY text can include line breaks, but avoid invalid formatting patterns that Meta rejects

Example request

{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "template_create_draft",
    "arguments": {
      "name": "address_confirmation_v2",
      "channelId": 3,
      "category": "UTILITY",
      "format": "SINGLE",
      "language": "en",
      "subCategory": "CUSTOM",
      "components": [
        {
          "type": "HEADER",
          "format": "TEXT",
          "text": "Confirm Delivery Address"
        },
        {
          "type": "BODY",
          "text": "Thanks for placing your order with {{1}}. We will deliver to:\n\n{{2}}\n{{3}}\n{{4}}\n\nNeed any corrections before shipping?",
          "example": {
            "body_text": [["Spur Store", "221B Baker Street", "London", "NW1 6XE"]]
          }
        },
        {
          "type": "BUTTONS",
          "buttons": [
            { "type": "QUICK_REPLY", "text": "Address Is Correct" },
            { "type": "QUICK_REPLY", "text": "Edit My Address" }
          ]
        }
      ]
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "draftTemplateId": 910,
  "templateSummary": {
    "name": "address_confirmation_v2",
    "channelId": 3,
    "category": "UTILITY",
    "subCategory": "CUSTOM",
    "language": "en",
    "format": "SINGLE"
  }
}

template_submit_for_review

Submits an existing draft template for Meta review.

Required fields

  • templateId

Behavior notes

  • Returns provider-level error context when Meta rejects submission
  • Use this after template_create_draft
  • warnings is reserved for non-fatal advisories
  • On failure, inspect providerError.error_user_msg, providerError.error_subcode, and traceId

Example request

{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "template_submit_for_review",
    "arguments": {
      "templateId": 873
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "submittedTemplate": {
    "id": 873,
    "status": "IN_REVIEW",
    "category": "UTILITY",
    "templateId": "1234567890"
  },
  "status": "IN_REVIEW",
  "category": "UTILITY",
  "warnings": []
	}

template_refresh

Refreshes template status/components from Meta by internal template id or metaTemplateId.

Required fields

  • one of: id | metaTemplateId

Behavior notes

  • Use id for a specific local template record
  • Use metaTemplateId when your flow stores Meta template IDs
  • Returns updated status and metadata after sync

Example request

{
  "jsonrpc": "2.0",
  "id": 14,
  "method": "tools/call",
  "params": {
    "name": "template_refresh",
    "arguments": {
      "metaTemplateId": "1208259160474051"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "refreshedBy": "metaTemplateId",
  "template": {
    "id": 601,
    "name": "order_update_v1",
    "status": "APPROVED",
    "category": "UTILITY",
    "format": "SINGLE",
    "language": "en_US",
    "templateId": "1208259160474051"
  }
}

template_delete

Deletes a template by internal template id. MCP validates workspace ownership first, then attempts Meta deletion when a linked templateId exists.

Required fields

  • id

Behavior notes

  • Use template_search first to pick the correct internal id
  • metaDeletion.attempted=true means the deleted template had a linked Meta template id
  • metaDeletion.success can be null when no Meta deletion was attempted or provider response is unavailable

Example request

{
  "jsonrpc": "2.0",
  "id": 15,
  "method": "tools/call",
  "params": {
    "name": "template_delete",
    "arguments": {
      "id": 89
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "deleted": {
    "id": 89,
    "name": "mcp_marketing_simple_1771153651",
    "templateId": "1475797657492255",
    "status": "APPROVED",
    "category": "MARKETING",
    "subCategory": "CUSTOM",
    "format": "SINGLE",
    "language": "en",
    "channelId": 3
  },
  "metaDeletion": {
    "attempted": true,
    "success": true,
    "providerResponse": {
      "success": true
    }
  }
}

template_requirements

Returns runtime send requirements and a sample contentMessage payload for a template. Use this before carousel sends and variable-heavy templates.

Required fields

  • one of: id | name

Optional fields

  • channelId

Behavior notes

  • Use id whenever possible for deterministic lookups
  • When using name in a multi-channel workspace, pass channelId to avoid ambiguity
  • hasCarousel=true means contentMessage.components.carousel.cards is required for broadcast/message sends
  • sampleContentMessage is a scaffold, not a final production payload

Example request

{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "tools/call",
  "params": {
    "name": "template_requirements",
    "arguments": {
      "id": 44
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "template": {
    "id": 44,
    "name": "test_template_carousel",
    "format": "CAROUSEL",
    "language": "en",
    "channelId": 3
  },
  "requirements": {
    "hasCarousel": true,
    "carouselCardCount": 2,
    "bodyVariableCount": 0,
    "hasDynamicButtons": true,
    "requiresContentMessage": true
  },
  "sampleContentMessage": {
    "name": "test_template_carousel",
    "language": { "code": "en" },
    "components": [
      {
        "type": "carousel",
        "cards": [
          {
            "card_index": 0,
            "components": [
              {
                "type": "header",
                "parameters": [{ "type": "image", "image": { "link": "https://example.com/image.jpg" } }]
              },
              {
                "type": "button",
                "sub_type": "url",
                "index": "0",
                "parameters": [{ "type": "text", "text": "https://example.com" }]
              }
            ]
          }
        ]
      }
    ]
  }
}

channels_list

Lists connected channels in the workspace. Use this to discover valid sender handles before calling message_send.

Required fields

Optional fields

  • channelType

Behavior notes

  • channelType: whatsapp | instagram | facebook | live_chat
  • For WhatsApp, use channels[].from as options.from in message_send
  • Returns id, type, provider, handle, and displayName

Example request

{
  "jsonrpc": "2.0",
  "id": 13,
  "method": "tools/call",
  "params": {
    "name": "channels_list",
    "arguments": {
      "channelType": "whatsapp"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "count": 2,
  "channels": [
    {
      "id": 12,
      "type": "whatsapp",
      "provider": "AISENSY",
      "from": "919876543210",
      "handle": "919876543210",
      "displayName": "Spur Support"
    },
    {
      "id": 21,
      "type": "whatsapp",
      "provider": "AISENSY",
      "from": "918888777666",
      "handle": "918888777666",
      "displayName": "Spur Sales"
    }
  ]
}

message_send

Sends a message to WhatsApp, Instagram, or Facebook contact.

Required fields

  • to
  • channel
  • content

Optional fields

  • options.from

Behavior notes

  • channel: whatsapp | instagram | facebook
  • content follows Spur send-message payload conventions
  • If multiple WhatsApp channels are connected, options.from is required
  • Call channels_list to discover valid options.from values
  • When WhatsApp 24-hour window is expired, Spur may convert text to a configured template payload
  • WhatsApp sends can auto-create contact/inbox context if the number does not exist
  • warning can be returned for non-blocking conditions

Example request

{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "tools/call",
  "params": {
    "name": "message_send",
    "arguments": {
      "channel": "whatsapp",
      "to": "919876543210",
      "content": {
        "type": "text",
        "text": {
          "body": "Hello from Spur MCP"
        }
      },
      "options": {
        "from": "919999999999"
      }
    }
  }
	}

Example success structuredContent

{
  "ok": true,
  "message": {
    "id": 9981,
    "status": "QUEUED"
  }
}

contact_create

Creates a contact in the workspace.

Required fields

  • firstName
  • lastName
  • number

Optional fields

  • email
  • name

Behavior notes

  • Uses strict REST semantics from POST /contacts
  • Returns conflict-style errors for duplicates
  • Phone format should be digits with country code

Example request

{
  "jsonrpc": "2.0",
  "id": 17,
  "method": "tools/call",
  "params": {
    "name": "contact_create",
    "arguments": {
      "firstName": "Aanya",
      "lastName": "Shah",
      "number": "919876543210",
      "email": "aanya@example.com"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "contact": {
    "id": 4321,
    "firstName": "Aanya",
    "lastName": "Shah",
    "email": "aanya@example.com",
  "number": "919876543210"
  }
}

contact_update

Updates selected fields on an existing contact.

Required fields

  • id
  • at least one of firstName, lastName, email

Behavior notes

  • Uses strict REST semantics from PATCH /contacts/:id
  • Supported fields: firstName, lastName, email
  • Returns not-found when contact does not exist in workspace

Example request

{
  "jsonrpc": "2.0",
  "id": 19,
  "method": "tools/call",
  "params": {
    "name": "contact_update",
    "arguments": {
      "id": 4321,
      "email": "aanya.updated@example.com"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "contact": {
    "id": 4321,
    "firstName": "Aanya",
    "lastName": "Shah",
    "email": "aanya.updated@example.com",
  "number": "919876543210"
  }
}

contact_delete

Deletes a contact by explicit contact ID or by WhatsApp number. Use ID when possible for deterministic deletion.

Required fields

  • one of: id | number

Optional fields

  • channel (only whatsapp when deleting by number)

Behavior notes

  • If number is provided, MCP resolves the WhatsApp contact using workspace-scoped number lookup
  • If multiple contacts match a number, MCP returns a conflict with candidate IDs
  • After deletion, sending to the same WhatsApp number can recreate contact context automatically

Example request

{
  "jsonrpc": "2.0",
  "id": 20,
  "method": "tools/call",
  "params": {
    "name": "contact_delete",
    "arguments": {
      "number": "919871739342",
      "channel": "whatsapp"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "deleted": {
    "id": 10,
    "channel": "whatsapp",
    "number": "919871739342",
    "firstName": "Rohan",
    "lastName": "Rajpal",
    "name": "Rohan Rajpal"
  }
}

segment_filters_catalog

Returns segment categories plus filter/operator metadata so AI can produce valid ruleGroup payloads.

Required fields

Optional fields

  • category

Behavior notes

  • Use this as the first step before segment_create or segment_update
  • category: customerInfo | messageActivity | websiteActivity | shoppingEvents
  • Operators include condition/type combinations required by backend SQL generation

Example request

{
  "jsonrpc": "2.0",
  "id": 30,
  "method": "tools/call",
  "params": {
    "name": "segment_filters_catalog",
    "arguments": {
      "category": "customerInfo"
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "count": 1,
  "categories": [
    {
      "type": "customerInfo",
      "name": "Customer Info",
      "filters": [
        {
          "label": "First Name",
          "value": "contact.firstName",
          "operators": [
            { "name": "Contains", "condition": "contains", "type": "STRING" }
          ]
        }
      ]
    }
  ]
}

segment_create

Creates a SPUR segment with nested ruleGroup logic.

Required fields

  • name
  • ruleGroup

Optional fields

  • description

Behavior notes

  • Build ruleGroup using operator metadata from segment_filters_catalog
  • Use ruleType=rule for leaf predicates and ruleType=group for nesting

Example request

{
  "jsonrpc": "2.0",
  "id": 32,
  "method": "tools/call",
  "params": {
    "name": "segment_create",
    "arguments": {
      "name": "Recent WhatsApp Engagers",
      "description": "Opened at least one message in last 30 days",
      "ruleGroup": {
        "operator": "AND",
        "rules": [
          {
            "ruleType": "rule",
            "categorySelected": "messageActivity",
            "filter": { "field": "customSegment.whatsappRead" },
            "operator": { "condition": "gtz", "type": "NONE" },
            "value": "1"
          }
        ]
      }
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "segment": {
    "id": 201,
    "name": "Recent WhatsApp Engagers",
    "type": "SPUR",
    "updatedAt": "2026-02-16T08:40:00.000Z"
  }
}

segment_update

Updates an existing SPUR segment by replacing name/description/ruleGroup.

Required fields

  • id
  • name
  • ruleGroup

Optional fields

  • description

Behavior notes

  • Shopify segments are read-only and will return an explicit error
  • Send full ruleGroup payload for deterministic updates

Example request

{
  "jsonrpc": "2.0",
  "id": 33,
  "method": "tools/call",
  "params": {
    "name": "segment_update",
    "arguments": {
      "id": 201,
      "name": "Recent WA Engagers (30d)",
      "ruleGroup": {
        "operator": "AND",
        "rules": [
          {
            "ruleType": "rule",
            "categorySelected": "messageActivity",
            "filter": { "field": "customSegment.whatsappRead" },
            "operator": { "condition": "gtz", "type": "NONE" },
            "value": "1"
          }
        ]
      }
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "segment": {
    "id": 201,
    "name": "Recent WA Engagers (30d)",
    "type": "SPUR"
  }
}

segment_delete

Deletes a segment when it is not referenced by active broadcasts.

Required fields

  • id

Behavior notes

  • If segment is referenced by DRAFT/SCHEDULED/RUNNING broadcast, deletion fails with structured hints
  • Use broadcast_search + broadcast_update to remove segment references first

Example request

{
  "jsonrpc": "2.0",
  "id": 34,
  "method": "tools/call",
  "params": {
    "name": "segment_delete",
    "arguments": {
      "id": 201
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "deleted": {
    "id": 201,
    "name": "Recent WA Engagers (30d)",
    "type": "SPUR",
    "success": true
  }
}

broadcast_create

Creates a broadcast draft with template reference, optional variable payload, and initial include/exclude segments.

Required fields

  • name
  • one of: templateInternalId | template

Optional fields

  • channelId
  • contentMessage
  • includedSegmentIds
  • excludedSegmentIds

Behavior notes

  • When multiple WhatsApp channels exist, pass channelId explicitly
  • templateInternalId maps to internal Spur template id from template_search
  • contentMessage maps to broadcast content.message for template variables/components
  • For carousel templates, contentMessage is required. Call template_requirements first and copy the scaffold

Example request

{
  "jsonrpc": "2.0",
  "id": 35,
  "method": "tools/call",
  "params": {
    "name": "broadcast_create",
    "arguments": {
      "name": "Weekend Offer Blast",
      "templateInternalId": 873,
      "channelId": 12,
      "includedSegmentIds": [120],
      "excludedSegmentIds": [205]
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "broadcast": {
    "id": 890,
    "name": "Weekend Offer Blast",
    "status": "DRAFT",
    "channelId": 12,
    "includedSegmentIds": [120],
    "excludedSegmentIds": [205]
  }
}

broadcast_update

Updates a DRAFT broadcast with composable include/exclude operations, template/message changes, schedule, and delivery controls.

Required fields

  • id

Optional fields

  • name
  • templateInternalId
  • template
  • contentMessage
  • includeSet
  • includeAdd
  • includeRemove
  • excludeSet
  • excludeAdd
  • excludeRemove
  • sendAt
  • deliveryBoost
  • splitAcrossDays
  • dailyLimit
  • limitAudience
  • limitCount

Behavior notes

  • Only DRAFT broadcasts are editable
  • Delivery Boost and Split Broadcast cannot both be true
  • limitAudience=true requires limitCount
  • excludeAdd entries already present in include list are ignored

Example request

{
  "jsonrpc": "2.0",
  "id": 36,
  "method": "tools/call",
  "params": {
    "name": "broadcast_update",
    "arguments": {
      "id": 890,
      "includeAdd": [121],
      "includeRemove": [120],
      "excludeAdd": [205],
      "contentMessage": {
        "name": "weekend_offer_v1",
        "language": { "code": "en_US" },
        "components": [
          {
            "type": "body",
            "parameters": [{ "type": "text", "text": "20% OFF" }]
          }
        ]
      },
      "sendAt": "2026-02-20T09:00:00.000Z",
      "limitAudience": true,
      "limitCount": 8000
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "broadcast": {
    "id": 890,
    "status": "DRAFT",
    "includedSegmentIds": [121],
    "excludedSegmentIds": [205],
    "sendAt": "2026-02-20T09:00:00.000Z",
    "filterQuery": { "limit": true, "count": 8000 }
  }
}

broadcast_launch

Launches broadcast by calling setReady.

Required fields

  • id

Behavior notes

  • Returns launchedStatus RUNNING for immediate send
  • Returns launchedStatus SCHEDULED when sendAt is in the future

Example request

{
  "jsonrpc": "2.0",
  "id": 37,
  "method": "tools/call",
  "params": {
    "name": "broadcast_launch",
    "arguments": {
      "id": 890
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "launchedStatus": "SCHEDULED",
  "broadcast": {
    "id": 890,
    "name": "Weekend Offer Blast",
    "status": "SCHEDULED"
  }
}

broadcast_analytics

Returns per-broadcast performance metrics and delivery-boost metadata.

Required fields

  • id

Optional fields

  • cached

Behavior notes

  • Includes delivered/opened/clicked/replied counts and percentages
  • Includes revenue, orders, whatsappCost, and template metadata
  • Use cached=true for faster repeated polling

Example request

{
  "jsonrpc": "2.0",
  "id": 39,
  "method": "tools/call",
  "params": {
    "name": "broadcast_analytics",
    "arguments": {
      "id": 890,
      "cached": true
    }
  }
}

Example success structuredContent

{
  "ok": true,
  "analytics": {
    "broadcastId": 890,
    "messages": 10000,
    "delivered": 9300,
    "opened": 6120,
    "clicks": 830,
    "orders": 94,
    "revenue": 274580,
    "whatsappCost": 4810.2,
    "percentDelivered": 93,
    "percentOpened": 65.8,
    "percentClicked": 8.92
  }
}

broadcast_overview_stats

Returns workspace-level aggregate broadcast KPIs.

Required fields

Behavior notes

  • Use alongside broadcast_analytics for campaign-level + workspace-level reporting
  • Totals are currency-normalized to workspace currency

Example request

{
  "jsonrpc": "2.0",
  "id": 40,
  "method": "tools/call",
  "params": {
    "name": "broadcast_overview_stats",
    "arguments": {}
  }
}

Example success structuredContent

{
  "ok": true,
  "overview": {
    "totalCount": 124,
    "totalRevenue": 12495840,
    "totalOrders": 2611
  }
}