Skip to main content
Glama

get_campaign_performance

Retrieve performance metrics for a specific Klaviyo marketing campaign by providing its ID to analyze results and optimize strategies.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesID of the campaign to retrieve performance for

Implementation Reference

  • The core handler function that implements the tool logic. It fetches campaign details, attempts to get campaign message details, queries the campaign-values-reports API for metrics with fallback logic, formats a performance object, and returns it as JSON text content.
    async (params) => {
      try {
        logger.info(`Retrieving campaign performance for campaign ID: ${params.id}`);
    
        // First get the campaign details with fallback
        const campaignFallbackFn = async (error) => {
          logger.warn(`Error retrieving campaign details: ${error.message}. Using simplified approach.`);
          return {
            data: {
              attributes: {
                name: `Campaign ${params.id}`,
                send_time: new Date().toISOString()
              }
            }
          };
        };
    
        const campaign = await klaviyoClient.get(`/campaigns/${params.id}/`, {}, campaignFallbackFn);
        logger.debug(`Retrieved campaign details for ID: ${params.id}`);
    
        // Then get the campaign message to access the metrics (if available)
        let messageId;
        if (campaign.data.relationships && campaign.data.relationships['campaign-messages']?.data?.length) {
          messageId = campaign.data.relationships['campaign-messages'].data[0].id;
          try {
            await klaviyoClient.get(`/campaign-messages/${messageId}/`);
            logger.debug(`Retrieved campaign message details for message ID: ${messageId}`);
          } catch (messageError) {
            logger.warn(`Error retrieving message details: ${messageError.message}. Continuing with metrics only.`);
          }
        } else {
          logger.warn(`No campaign messages found for campaign ID: ${params.id}. Continuing with metrics only.`);
        }
    
        // Get campaign metrics using the updated Reporting API with valid statistics
        const payload = {
          data: {
            type: "campaign-values-report",
            attributes: {
              // Use only valid statistics - based on testing and API responses
              statistics: [
                'delivered', 
                'open_rate', 
                'click_rate', 
                'bounce_rate',
                'unsubscribe_rate',
                'revenue_per_recipient'
              ],
              timeframe: {
                key: "last_30_days"  // Use a valid timeframe
              },
              conversion_metric_id: API_CONFIG.defaultConversionMetricId,
              filter: FILTER_TEMPLATES.campaignId(params.id)
            }
          }
        };
    
        logger.debug('Campaign performance request payload', payload);
    
        // Define the metrics fallback function
        const metricsFallbackFn = async (error) => {
          logger.warn(`Error retrieving comprehensive campaign metrics: ${error.message}. Attempting fallback.`);
          
          // Fallback to minimal statistics set
          const fallbackPayload = {
            data: {
              type: "campaign-values-report",
              attributes: {
                statistics: ['delivered'],
                timeframe: {
                  key: "last_30_days"
                },
                conversion_metric_id: API_CONFIG.defaultConversionMetricId,
                filter: FILTER_TEMPLATES.campaignId(params.id)
              }
            }
          };
    
          logger.debug('Campaign performance fallback payload', fallbackPayload);
          
          return await klaviyoClient.post('/campaign-values-reports/', fallbackPayload);
        };
    
        const metrics = await klaviyoClient.post('/campaign-values-reports/', payload, metricsFallbackFn);
    
        // Format the results for easier consumption
        const performance = {
          campaign_name: campaign.data.attributes.name,
          send_time: campaign.data.attributes.send_time,
          metrics: metrics.data.attributes
        };
    
        logger.info(`Successfully retrieved campaign performance for campaign ID: ${params.id}`);
    
        return {
          content: [{ type: "text", text: JSON.stringify(performance, null, 2) }]
        };
      } catch (error) {
        logger.error(`Failed to retrieve campaign performance: ${error.message}`, {
          campaignId: params.id
        });
    
        return {
          content: [{ type: "text", text: `Error retrieving campaign performance: ${error.message}` }],
          isError: true
        };
      }
    },
  • Zod validation schema for the tool input, requiring a campaign ID.
    {
      id: z.string().describe("ID of the campaign to retrieve performance for")
    },
  • The server.tool call within registerReportingTools that defines and registers the get_campaign_performance tool, including schema, handler, and description.
    server.tool(
      "get_campaign_performance",
      {
        id: z.string().describe("ID of the campaign to retrieve performance for")
      },
      async (params) => {
        try {
          logger.info(`Retrieving campaign performance for campaign ID: ${params.id}`);
    
          // First get the campaign details with fallback
          const campaignFallbackFn = async (error) => {
            logger.warn(`Error retrieving campaign details: ${error.message}. Using simplified approach.`);
            return {
              data: {
                attributes: {
                  name: `Campaign ${params.id}`,
                  send_time: new Date().toISOString()
                }
              }
            };
          };
    
          const campaign = await klaviyoClient.get(`/campaigns/${params.id}/`, {}, campaignFallbackFn);
          logger.debug(`Retrieved campaign details for ID: ${params.id}`);
    
          // Then get the campaign message to access the metrics (if available)
          let messageId;
          if (campaign.data.relationships && campaign.data.relationships['campaign-messages']?.data?.length) {
            messageId = campaign.data.relationships['campaign-messages'].data[0].id;
            try {
              await klaviyoClient.get(`/campaign-messages/${messageId}/`);
              logger.debug(`Retrieved campaign message details for message ID: ${messageId}`);
            } catch (messageError) {
              logger.warn(`Error retrieving message details: ${messageError.message}. Continuing with metrics only.`);
            }
          } else {
            logger.warn(`No campaign messages found for campaign ID: ${params.id}. Continuing with metrics only.`);
          }
    
          // Get campaign metrics using the updated Reporting API with valid statistics
          const payload = {
            data: {
              type: "campaign-values-report",
              attributes: {
                // Use only valid statistics - based on testing and API responses
                statistics: [
                  'delivered', 
                  'open_rate', 
                  'click_rate', 
                  'bounce_rate',
                  'unsubscribe_rate',
                  'revenue_per_recipient'
                ],
                timeframe: {
                  key: "last_30_days"  // Use a valid timeframe
                },
                conversion_metric_id: API_CONFIG.defaultConversionMetricId,
                filter: FILTER_TEMPLATES.campaignId(params.id)
              }
            }
          };
    
          logger.debug('Campaign performance request payload', payload);
    
          // Define the metrics fallback function
          const metricsFallbackFn = async (error) => {
            logger.warn(`Error retrieving comprehensive campaign metrics: ${error.message}. Attempting fallback.`);
            
            // Fallback to minimal statistics set
            const fallbackPayload = {
              data: {
                type: "campaign-values-report",
                attributes: {
                  statistics: ['delivered'],
                  timeframe: {
                    key: "last_30_days"
                  },
                  conversion_metric_id: API_CONFIG.defaultConversionMetricId,
                  filter: FILTER_TEMPLATES.campaignId(params.id)
                }
              }
            };
    
            logger.debug('Campaign performance fallback payload', fallbackPayload);
            
            return await klaviyoClient.post('/campaign-values-reports/', fallbackPayload);
          };
    
          const metrics = await klaviyoClient.post('/campaign-values-reports/', payload, metricsFallbackFn);
    
          // Format the results for easier consumption
          const performance = {
            campaign_name: campaign.data.attributes.name,
            send_time: campaign.data.attributes.send_time,
            metrics: metrics.data.attributes
          };
    
          logger.info(`Successfully retrieved campaign performance for campaign ID: ${params.id}`);
    
          return {
            content: [{ type: "text", text: JSON.stringify(performance, null, 2) }]
          };
        } catch (error) {
          logger.error(`Failed to retrieve campaign performance: ${error.message}`, {
            campaignId: params.id
          });
    
          return {
            content: [{ type: "text", text: `Error retrieving campaign performance: ${error.message}` }],
            isError: true
          };
        }
      },
      { description: "Get a comprehensive performance summary for a campaign" }
    );
  • src/server.js:38-38 (registration)
    Invocation of registerReportingTools on the MCP server, which registers the reporting tools including get_campaign_performance.
    registerReportingTools(server);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ivan-rivera-projects/Klaviyo-MCP-Server-Enhanced'

If you have feedback or need assistance with the MCP directory API, please join our Discord server