{
  

    "": {
      "title": "Getting Started with Moesif",
      "content"	 : "Moesif is an API analytics and monetization platform to help you grow your API business and ship better APIs.Choose your use case whether to get started with API Observability/Analytics or API Monetization. You can always start with API Observability and set up API Monetization later.                    Get started with API Observability                    Get started monitoring and understanding API usage                     View Integrations                                Get started with API Monetization                    Get started monetizing your APIs with usage-based billing                    View Integrations             Using MoesifLearn how to use Moesif to help you gain powerful API observability, monetize your APIs, and improve your customer experience.API Observability                              API Analytics                          Analyze API traffic and usage                                                User Analytics                          Understand customer behavior and drop off                                                API Monitoring &amp;amp; Alerts                          Get alerted of issues impacting customers                                                Dashboards                          Share dashboards and reports with teammates                    API Monetization                              Billing Meters                          Create usage-based billing meters                                                Quotas and Governance                          Enforced quotas and contract terms                                                Product Catalog                          Create Plans and Prices for APIs                                                Prepaid Credit Tracking                          Deploy Moesif&#39;s open-source dev portal                    Customer Experience                              Embedded Metrics                          Embed API logs and charts in a customer portal                                                Behavioral Emails                          Guide users at scale                                                Saved Cohorts                          Identify customers with churn risk                                                Developer Portal                          Deploy Moesif&#39;s open-source dev portal                    Moesif entity diagramResources           Guides            Changelog            API Reference            Ebooks            System Status  ",
      "url": " /",
      "author": "Derric",
      "categories": ""
    }
    ,
  

    "getting-started-overview": {
      "title": "Overview of Moesif",
      "content"	 : "What is Moesif?Moesif is an API analytics and monetization platform that helps you grow your API businesses through data.At its core, Moesif is a data platform to track customer API usage. Use it to better understand your API consumption and the value customers get from your APIs. You can also understand cost such as from AI and LLM model usage. Through Moesif’s workflows, you can set up usage-based billing, quotas and governance and behavioral emails in a few clicks.What does Moesif support?Moesif supports any API, REST, GraphQL, XML/SOAP, RPC, etc andcan monitor both incoming API calls hitting your services and outgoing API calls to 3rd party services.For non-API traffic, Moesif also supports custom metrics via our action tracking API.Moesif has integrations with most API gateway vendors such as Kong and Amazon API Gateway as well as server middleware for most API frameworks if you’re not using an off-the-shelf API gateway solution. Both APIs hostedon-premises and in the cloud are supported along with serverless platforms such as AWS Lambda, Heroku, and Cloudflare Workers.How does Moesif work?Moesif is a fully managed SaaS service running on AWS and Azure. Use one of theserver integrations for popular API gateways and frameworks toautomatically monitor your API traffic. You can also leverage a client integrationto track user behavior and website activity outside of your API which provides visibility into your end-to-end customer journey from a customer’s sign-up to making their first API call.Moesif data structureMoesif tracks two types of events (API Calls and Actions) and three type of entities Users, Companies, and Subscriptions. A full diagram is below.API callsMoesif monitors your API calls using one of the server SDKs or API gateways plugins.This enables you to inspect the payloads, understand latency timing, etc.You can append event metadatato API calls such as deployment id or API version.User actionsNot every customers interactions happens over your APIs. Website visitors will view doc pages and sign in to your developer portal.In addition, there might be consumption events that you may want to meter outside of your API traffic such as from backend jobs.This is where custom actions can be used. You can use a client integration such as moesif-browser-js or send custom actions from your backend.Span actionsSpan Actions are a special type of action ingested from an OTel client. An OTel Span Action maps to a Moesif Span Action.UsersA user is an individual person using your API and identified via your application-specificuser_id. Users in Moesif can be associated with various properties likethe user’s email, first and last name, employment title, and other person demographics.You can enrich users in Moesif with any custom metadata via our API libs or use one of ourextensions like Zapier, Salesforce, Hubspot, Clearbit, etc.CompaniesCompanies in Moesif are a group of related users. If your business model includes B2B, you may be interested in trackingAPI usage at the company level in addition to the user level. You can decide to track users only, companies only, or track both usersand companies depending on your business model. Companies in Moesif can track custom company properties such ascompany name, website domain, revenue, and other company demographics.SubscriptionsIf you decided to leverage the monetization features of Moesif, you can leverage this feature. A companies can be associated with one or more subscription. The subscription connects a customer record to product/service/plans.PlansPlans define a set of prices, currency, and billing cycle for a set of products/services. Some billing providers may call this “Products”.PricesPrices define the unit cost, currency, and for a single usage based metric or service. A plan may be associated with multiple prices.(Some billing providers may call prices addons).An example of relationship between Plans and Prices this: For one plan, you may have a price for number API calls and a price for the size of data bandwidth used.Billing ProvidersBilling providers are services like Stripe, Chargebee, Recurly, or Custom Billing solution that process payment and manage the Subscription, Plans, and Prices. The Subscriptions, Plans and Prices objects can be synced with Moesif. As part of the API monetizations features, Moesif can report usage metrics to these billing providers.Smart SearchMoesif’s Smart Search provides fast, AI-powered semantic search capabilities in your Moesif Web Portal.It searches through the following components:  Dashboards  Workspaces  Alert rules  Cohorts  Billing metersSmart Search organizes the search results in several tabs. The Top tab shows you the best matches for your search query. The rest of the tabs show matches for the individual components.You can access and use Smart Search with these steps:  Log into Moesif.  Select Search with AI or press Control+K.  Enter your search query.  Press Enter.",
      "url": " /getting-started/overview/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-api-observability": {
      "title": "Getting started with API Observability and Analytics",
      "content"	 : "                    1.                    Install Server Integration                    Install a server SDK or API gateway plugin to automatically log API traffic.                    View Integrations                                        2.                    Create Users/Companies                    Create users/companies in Moesif using moesif-browser-js or the API                    View Company Profiles                                        3.                    Install a Client Integration                    Install moesif-browser-js or Segment to track customer actions within your apps.                    View Integrations            With API observability and analytics, you can gain business metrics to better understand your API consumption patterns and ship better API products. You can also gain operational metrics to troubleshoot issues with your API.The first step is to install a server integration to log API traffic to Moesif. Moesif has integrations with most API gateways and web frameworks providing. You can mix and match multiple integrations together to gain a unified view of your API usage even if you have different API management tools and technologies. Server integrations are low-code and automatically instrument your application. Moesif is compatible with OpenTelemetry as well.For understanding client consumption patterns, you should ensure your server integration is configured to also identify the user or company. For most API gateway plugins, this is handled automatically. However, the integrations for web frameworks provide an identifyUser and identifyCompany option to define how to extract this from your request context.While not required, it’s strongly recommended to also sync your customer data to Moesif. This can include the user email, company name, subscription info, etc. Moesif has connectors for tools like Segment, Hubspot, and Stripe which can sync this data automatically.You can also send this data directly from your app using [moesif-browser-js] or via an API libLastly, you can also install a client integration like moesif-browser-js to track web activity such as sign up events,viewing doc pages, etc. This ensures you can track the end-to-end customer journey from sign up to first API call.",
      "url": " /getting-started/api-observability/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-api-monetization": {
      "title": "Getting started with API Monetization",
      "content"	 : "                    1.                    Install Server Integration                    Install a server integration to meter API traffic or ingest custom actions directly.                    View Integrations                                        2.                    Setup Billing Provider                    Connect Moesif to your billing provider like Stripe for automatic invoicing.                    View Setup                                        3.                    Create a Plan and Price                    Create a pricing model such as tiered, PAYG, and more.                    View Product Catalog                                        4.                    Create a Billing Meter                    Create a billing meters for usage-based billing or create a quota rule.                    View Billing Meters            With API monetization, you can directly charge for access to your API. Moesif supports usage-based models like Pay-As-You-Go along with quotas and limits.The first step is to get your raw consumption events in Moesif which can be your API logs or custom actions.Log API Calls via Server IntegrationThe first step is to install a server integration to log API traffic to Moesif. Moesif has integrations with most API gateways and platforms providing a unified view of your API usage regardless of your underlying API management stack. You can mix and match multiple integrations together. Moesif is compatible with OpenTelemetry as well.Identifying CompaniesTo ensure API traffic is associated with customer accounts for billing, you must ensure your server integration identifies the company (customer) or link API users to companies. See docs on identifying companies.Ingest Custom ActionsInstead of a server integration, you can directly send custom events to Moesif’s Track Action API. This can be done such as from an event stream like AWS Firehose and Logstash. See Options to Ingest Custom Actions.Connect Billing ProviderOnce you have your raw events in Moesif, you can connect Moesif to a billing provider like Stripe or Zuora. The integration enables Moesif to automatically invoice customers and collect payments.Lastly, you’ll want to create your plan, price, and billing meters in Moesif.  Create plans and prices through Moesif product catalog for your pricing model such as PAYG, tiered, etc.  Then create a billing meter which represents the billable metric like API Calls or Unique Users to charge for.Create Plans and Billing MetersOnce you ingest your events into Moesif, you can start creating plans, prices, and billing meters.  A plan is the item you are selling like “Starter Plan”  A price is how the usage is rated which can contain tiers.  A billing meter represents the metric you want to charge on such as “API Calls” or “Gigabytes”A full diagram on Moesif entities is below.",
      "url": " /getting-started/api-monetization/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-identify-customers": {
      "title": "Identifying Users",
      "content"	 : "Proper analytics and usage metering requires a mechanism to identify customers and ensure web and API usage is correctly attributed to the correct customers. This may be complicated because an API consumer (user) can consist of different states:  An anonymous visitor viewing your doc pages.  Signed into your portal and created an API key.  Created a subscription that is tied to a company.  Making authenticated calls against your API.Overview of user trackingThe challenge of stitching together a customer journeyMost platform-focused companies have a variety of different products. For example, some products are API-based applications that are accessed by customers programmatically, whereas other products are web-based applications that customers log into with their browsers and use interactively. So it’s critical to stitch together a holistic customer journey so you can understand funnel metrics like initial sign up to first API call across both your API and web apps.Yet, each of these products may have different ways to identify and authenticate users, creating multiple challenges. For example, an API may require adding a bearer token whereas a website may require a user to log in via an OAuth flow and store a session cookie.In addition, not all users have identifying information. For example, you may have anonymous visitors who browsed your website before they signed up. These visitors don’t even have a user id generated yet. What if the same anonymous visitor browses your website from multiple devices? A naive user tracking implementation would double-count that person twice, reducing the integrity of your metrics.How Moesif solves thisThe recommended way to set up Moesif is with two integration points:  A server integration to monitor API calls.  A client integration to track users and their web activity.By using both integrations together, a complete picture can be drawn showing user interactions with each API (the server integration) and interactions with the frontend UI (the client integration).Note that the server integration can be used without the client integration since both are mutually exclusive implementations.A complete implementation is shown in the below diagram.Behind the scenes, the Moesif platform leverages a variety of tricks to accurately stitch together each customer’s journey. This mechanism includes user aliasing, anonymous ids, and merging users. Most of this is handled automatically by Moesif, but this article details what you need and how it works.User IdMoesif uses a user id (or company id) to associate API and web traffic to the same customer. If you are using both the server and client integrations, you should ensure your user id is consistent across both. You will also want to make sure that the user id is unique and unchanging.If you use a user id that may change in the future, it will likely break your metrics. For instance, using an identifier such as email may be risky if you allow users to change their email in your application. A randomly generated UID that stays with the user regardless of profile changes is recommended.To attach a user id to an event or action, server and client integrations should call the identifyUser method. It is important that when calling this method, every call, whether it be from the client or server integrations, be made with the same id for the target user, so metrics are properly tracked.The id used to track the user should be a permanent and robust identifier that never changes, like a database id. Using fields that can change, like email addresses or API keys, is not recommended. Using different ids for the same user will lead to issues with tracking the end-to-end journey (such as over-counting unique users) since Moesif uses one unique identifier per individual user.Server integrationYou will want to use a Moesif server integration to track API calls by user. We support many different platforms and the ability to create a custom integration for unsupported platforms.Identifying usersThe ability to identify users can only happen with authenticated API calls. For example, anonymous calls to the API will not be tracked by user ID.You’ll need to ensure your server integration correctly identifies users so that API traffic is associated with each user.User identification is accomplished by implementing the identifyUser hook in the Moesif middleware. The identifyUser hook should be supplied with your custom logic that returns the user id.The identifyUser() (or identifyCompany()) function you supply has access to the request context. For example, if your API authentication middleware sets a variable req.user.id,  you can use that. You can also read from an HTTP header like X-User-Id, extract a field from a JWT, or use any other field available in the request context.Here is an example of a Node.js integration:const moesifMiddleware = moesif({  applicationId: &#39;Your Moesif Application Id&#39;,  // Return the user id set by the auth middleware.  identifyUser: function (req, res) {    return req.user ? req.user.id : undefined;  },});app.use(moesifMiddleware);You can see in the above snippet that identifyUser is passed a function which has the request and response for the API call. In this example, we are grabbing the id from the requests user.id field and if a user is not defined, no user id to the call/event in Moesif.Depending on the framework, language, or gateway you are using, you should review the identify user section for your respective server integration.Many API gateway plugins and SDKs have a default identifyUser function out of the box based on the conventions for that framework.For example, the Kong plugin reads the value set in x-consumer-custom-id, the AWS API gateway reads the value principalId and cognitoIdentityId, and moesif-nodejs uses the value set in req.user.idYou can do more advanced filtering and metrics by attaching a user id to an event in Moesif. Here’s what it looks like in the Live Event Log screen in Moesif.Anonymous IdsUnlike the client integration, the server integration can’t track anonymous user ids.This is because API traffic is usually authenticated traffic by definition. For example, if an ID is not attached to an event, the userID field in Moesif will simply be undefined.Client integrationMoesif’s support for client integrations allows user interactions to be tracked beyond just the API calls tracked in the server integration. Each event (button click, register, login, etc.) can be easily added to your metrics in Moesif so you can see the full user journey.Identifying usersTo identify a user, you must have a unique ID to associate with them. Once you know the user id of a customer, you can call identifyUser() to associate the current web session with your known permanent identifier. For best results, this should be done as soon as possible such as when a user logs into your app. Otherwise, tracking data can be lost if the customer clears their browser’s cookies and local storage before being identified with Moesif.To make sure a seamless picture of the journey is recorded, be sure that the user ID supplied to the client integration matches the one your server integration is also using.Here is an example of how to initialize the Moesif browser-js package in a JavaScript frontend:&amp;lt;script src=&quot;//unpkg.com/moesif-browser-js@v1/moesif.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;  moesif.init({    applicationId: &quot;Your Moesif Application Id&quot;,  });  // Identify the user with Moesif, such as when the user logs in  moesif.identifyUser(&quot;12345&quot;);&amp;lt;/script&amp;gt;You can see above that we include the dependency (moesif.min.js), call init with the Moesif Application ID for our app, and then call moesif.identifyUser(USER_ID). This would likely be done once the user logs into the app and a user id is retrieved. Once this is done, each action the user performs on the front end will be tracked and reported to Moesif.Anonymous usersWhen a new visitor browses your website, which has a client integration like moesif-browser-js installed, Moesif generates an anonymous user id and stores it on the user’s device.By doing this, users who are yet to create an account or login can still be accurately tracked, and their journey reported to Moesif.This anonymous id is persisted both into localStorage and replicated to a cookie for redundancy so that if the user clears local storage or visits a different subdomain (like from docs.acmeinc.com to acmeinc.com), there is still a cookie to fall back to and the user can be accurately attributed.Anonymous users make it possible to track unique users correctly and stitch together the user journey before and after signing into your app. Moesif uses two different ids to accomplish this:            Name      Description                  User Id      The internal User Id assigned by Moesif. This may be either a generated Anonymous Id or can be your Identified User Id or Anonymous Id.              Identified User Id      The Identified User Id is set by you by the identifyUser function. When no Identified User Id is set, the user is anonymous and has not been identified.      You should call moesif.reset() when a user logs out of your application to ensure a new anonymousId is generated. Otherwise, new activity may get associated with an old user session.User mergingMoesif will automatically merge users if they are identified as the same person.This can happen if an existing user (previously tracked in Moesif) starts browsing your app on a new device.A new anonymous profile is created as soon as the user starts browsing anonymously from their new device.Once the user logs in (thus identifyUser() is called), Moesif will merge the newly created anonymous profile with the previously created user profile. You will see only one user in Moesif.The below table describes different scenarios of how Moesif handles user creation and merging:            Example Scenario      How Moesif handles                  No User Id identified      All events will be associated with an anonymous user profile. Identified User Id is null. User Id is set to a generated Anonymous Id.              User Id is identified after anonymous events      Events are associated with an anonymous user profile. Initially, Identified User Id is null. Once the user is identified, both User Id and Identified User Id are set to the actual user id.              Same User Id on multiple devices, with no anonymous events      Events will be initially associated to two different anonymous profiles. Once the user is identified, both profiles will be merged into a single user profile. User Id and Identified User Id are set to the actual user id.              Multiple User Ids on the same device      Two profiles will be created, one for each user id. No merging will occur. Ensure moesif.reset() is called when a user logs out. Otherwise, events may get associated to an old user session.              Multiple User Ids on the same device, with anonymous events      Ensure moesif.reset() is called when a user logs out. Otherwise, events may get associated to an old user session.      Linking users to companiesIn addition to tracking users, you can also track usage at the by Company. This is helpful if your business primarily sells to other businesses (B2B).Company tracking works by assigning a user to a company (i.e., a group of users), similar to tracking users by user ID.Adding a Company identifier to a user can be done in one of three ways:  Implement the identifyCompany() hook in your server integration. See example for Node.jsThis can be the easiest option if you already have company context available in your API.  Call the identifyCompany() function in your client integration, such as after they sign into your application. See this example for browser-jsThis is great if you already have company context in your front end such as when they sign into your application  Define a company_id when saving a user to Moesif directly. See updating user profilesThis is great if you’re already syncing users and companies via a separate processAs long as you link a user to a company, Moesif will also associate any future web or API traffic from a user to that company.Logging outIn your apps logout routine, if you use moesif-browser-js, call moesif.reset() when a user logs out of your app.Doing this ensures a new anonymous id is generated and ensures different sessions are not mixed up, and is super important for testing.Here is a simple example demonstrating the usage of the moesif.reset() function:function logoutUser() {  // example routine for logging out users from app  logoutUserFromApp();  clearSession();  // Reset browser session for Moesif  moesif.reset();}",
      "url": " /getting-started/identify-customers/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-api-events": {
      "title": "Logging API Calls",
      "content"	 : "API Calls are one of the two event types that can be logged to Moesif for analysis (the other being custom actions).API Calls are automatically logged when using one of the server integrations for popular API gateways and web frameworks.Once logged to Moesif, the rest of the data processing is handled automatically.To filter by API Calls in Moesif, select the Event Type filter and then pick API Call. Then, you’ll see your live API logs, as shown below:Default fieldsMoesif will automatically analyze various default fields, such as HTTP Headers, body fields, and query parameters. Any of these fields can be used in Moesif’s powerful filteringand aggregations.Body payloadsMoesif will also provide metrics on payload keys for supported content types. JSON, XML, SOAP, GraphQL, and other text formats are currently supported.Moesif also works with binary formats like ProtoBuf, but you may be missing certain aggregations and metrics related to the body fields.If you have sensitive data such as financial or healthcare, you can leverage client-side encryption or disable body logging.Parsing URL-encoded form dataWhen using URL-encoded form data, pay attention to how you define the key-value pairs.If the URL-encoded form data has multiple keys, Moesif considers them as arrays for the following formats:credits_array=1&amp;amp;credits_array=1&amp;amp;credits_array=1&amp;amp;credits_array=1credit_array[]=1&amp;amp;credit_array[]=1&amp;amp;credit_array[]=1&amp;amp;credit_array[]=1In both cases, Moesif translates them into the array &quot;credit_array&quot;=&amp;gt;[&quot;1&quot;, &quot;1&quot;, &quot;1&quot;, &quot;1&quot;].For all other formats of URL-encoded data with multiple keys, Moesif processes them as strings rather than arrays:credit_array=[1,1,1,1]credit_array=1,1,1,1credit_array=1%2C1%2C1%2C1credit_array[0]=1&amp;amp;credit_array[1]=1&amp;amp;credit_array[2]=1&amp;amp;credit_array[3]=1Event metadataBesides the default API fields Moesif already analyzes, you can append custom event metadata to any API call.For example, you may want to save tracing information, virtual machine identifiers, or other context variables with an API call.{  &quot;some_string&quot;: &quot;I am a string&quot;,  &quot;some_int&quot;: 77,  &quot;some_object&quot;: {      &quot;some_sub_field&quot;: &quot;some_value&quot;    }}Saving event metadataEach SDK has a slightly different way to save event metadata, browse your specific server integration for details.In order to save metadata, override the respective getMetadata() function in your SDK’s options.The SDK’s getMetadata hook will pass in both the request and response object for context, which you can read when setting metadata fields.For example, the below code will parse the version string from the URI, such as in /api/v1/:items, and also read an environment variable called CATEGORY, which contains the location.options.getMetadata = function (req, res) {  let versionRegex = /vd*/;  return {    api_version: versionRegex.match(req.uri)[0],    category: process.env.CATEGORY  };}Using event metadataNow that we are tracking custom event metadata, we can create metrics reports within Moesif.For our example above, we can understand which data-center locations are seeing the most API traffic.To do so, we can select Time Series under the + Create New button on the left-side navigation.You can open the Metadata within any filter/group by/metric dropdowns.In our example, we select metadata.category, now our chart will show the daily API calls broken down by different categories:Best practicesFollow these best practices when defining event metadata.Maintain consistent data typesOnce a specific JSON key is seen by Moesif with a specific JSON data type, you cannotsend a different JSON datatype using the same key.For example, if you previously sent to Moesif the following event metadatafor an API call:{  &quot;some_string&quot;: &quot;I am a string&quot;,  &quot;some_int&quot;: 77,  &quot;some_object&quot;: {      &quot;some_sub_field&quot;: &quot;some_value&quot;    }}Then, Moesif automatically saves some_string as a JSON string in the metadataschema. You cannot later send a JSON Number using the same some_string key.This is true regardless of the number of levels relative to the object root.The below metadata would now be invalid:{  &quot;some_int&quot;: 77,  &quot;some_object&quot;: {      &quot;some_string&quot;: 23,      &quot;some_sub_field&quot;: &quot;some_value&quot;    }}The metadata schema is specific to each application you create in Moesif.For example, your development environment can be different than your prod environment.Avoid dot charactersBe aware that Dot characters in a JSON key for event metadatawill be converted into an underscore by Moesif automatically.However, Dot characters in a JSON value are fine and will not be transformed.For example,{  &quot;so.me_str.ing&quot;: &quot;I am a string&quot;,  &quot;some.int&quot;: 77.23}Will be converted by Moesif to:{  &quot;so_me_str_ing&quot;: &quot;I am a string&quot;,  &quot;some_int&quot;: 77.23}",
      "url": " /getting-started/api-events/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-user-actions": {
      "title": "Logging Custom Actions",
      "content"	 : "Actions are custom events such as those triggered within your UI, such as Clicked Sign Up or Sent a SMS or from your backend. You can also track actions from an event stream like AWS Firehose or Logstash. By tracking custom actions, you’re able to create metrics and bill on arbitrary event data.Tracking custom actions are normally done with a client integration or can be directly sent from an event stream like AWS Firehose and Logstash. See Options to Ingest Custom Actions.This also enables you to see the end-to-end customer journey from initial sign up to first API call.Intro to ActionsActions have an action name (like “Signed Up” or “Finished Data Processing Job”) which represents the name of the consumption event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;company_id&quot;: &quot;12345&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.Tracking actionsYou can directly send actions via API, or you can also track actions from a Moesif client integration such as moesif-browser-js or Segment:var moesif = require(&#39;moesif-browser-js&#39;);moesif.init({  applicationId: &#39;YOUR_COLLECTOR_APPLICATION_ID&#39;});// The first argument (required) contains the action name string.// The second argument (optional) contains event metadata.moesif.track(&#39;Clicked Sign Up&#39;, {  button_label: &#39;Get Started&#39;,  provider: &#39;Google&#39;});Span actions (OTel)Span Actions are a special type of action ingested from an OpenTelemetry client. An OTel Span Action maps to a Moesif Span Action.Event metadataBesides the action name, you can also store event metadata (i.e. attributes), such as the color of the button click or results of a backend job. In the below example, there are also four metrics we are tracking as part of the action such as how many rows of data touched and how many GenAI input tokens consumed.{    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3}Using event metadataNow that we are tracking custom event metadata, we can create metrics reports within Moesif. For our example above, we can understand which social network login providers are used the most when logging into an application or purchasing a plan.To do so, we can go to Time Series after selecting the + Create New button on the left-side navigation. You can open the Metadata within any filter/group by/metric dropdowns.In our example, we select metadata.provider, now our chart will show the daily API calls broken down by login providers as shown below:Best practices1. Maintain consistent data typesMoesif auto detects the data type the first time a new JSON key is seen. For example, if a field is set to 2, Moesif will treat this field as a number. You cannot send a different type using the same key. For example, if you previously sent the following event metadata for an API call to Moesif:{  &quot;some_string&quot;: &quot;I am a string&quot;,  &quot;some_int&quot;: 77,  &quot;some_object&quot;: {      &quot;some_sub_field&quot;: &quot;some_value&quot;    }}Then, Moesif automatically saves some_string as a JSON string in the metadata schema. You cannot later send a JSON Number using the same some_string key. This is true regardless of the number of levels relative to the object root. The below metadata would now be invalid:{  &quot;some_int&quot;: 77,  &quot;some_object&quot;: {      &quot;some_string&quot;: 23,      &quot;some_sub_field&quot;: &quot;some_value&quot;    }}The metadata schema is specific to each application you create in Moesif. For example, your development environment can be different than your production environment.2. Avoid dots charactersBe aware that Dot characters in a JSON key for event metadatawill be converted into an underscore by Moesif automatically.However, Dot characters in a JSON value are fine and will not be transformed.For example,{  &quot;so.me_str.ing&quot;: &quot;I am a string&quot;,  &quot;some.int&quot;: 77.23}Will be converted by Moesif to:{  &quot;so_me_str_ing&quot;: &quot;I am a string&quot;,  &quot;some_int&quot;: 77.23}",
      "url": " /getting-started/user-actions/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-users": {
      "title": "User Profiles",
      "content"	 : "A user in Moesif is an end consumer of your API. If you are an API provider, this may be the individual third-party developer consuming your API or the users that are employees of your customer.What are user properties?Users can track various properties such as email, first_name, last_name, etc. For a complete list of properties, check out the User API ReferenceYou  can customize a user profile and the fields shown. To see exactly how to do this, check out the docs on Profile View.Identification of usersUsers in Moesif are identified by a single user_id and potentially associated with many session_token.’s.      A user_id is a permanent and unique identifier to track a user across platforms and services. Setting the Moesif user_id field with the id used in your own databases and services is recommended.        A session_token is a temporary or semi-permanent token that is associated with the user’s session. Examples include JSON Web Tokens (JWT), API keys, Access Tokens, and session ids.  How to track users1. Set the identifyUser functionBy defining an identifyUser callback such as setting the moesif-nodejs identifyUser() option, you ensure new API calls are associated with a specific user_id.2. Enrich the user with additional metadataIf you only did Step 1, you’ll see some user analytics in Moesif like first and last seen time, but it’s much more useful if you enrich with your own metadata such as email, first and last name, employment title, social media handles, or any other metadata you want to store in Moesif.To add user metadata to Moesif, just call the SDK’s updateUser() method from your code, such as the moesif-nodejs updateUser() method with the user_id and JSON metadata you want to store. You only need to call this when your own user data changes, such as when you pull from Clearbit or another data provider.The update user endpointThe update user endpoint will perform an upsert if the user_id doesn’t exist, meaning a new user will be created.You can call the updateUser() directly from the Moesif server integration you already installed. If you’re calling from a separate service and don’t need the full middleware, you can use one of the Moesif base API libs or REST API directly.If you attempt to update a user and the user_id doesn’t exist, a new user will be created (i.e., upsert).The update user API is accessible through the Server SDK or thebase API Libs.  Calling either function are equivalent. For example:    Server SDK such as moesif-nodejs’s updateUser() wrapper function.  Base API Lib such as moesifapi-nodejs to call updateUser()(https://www.moesif.com/docs/api?javascript–nodejs#update-a-user) directly.How to alias a sessionMultiple sessions can be associated to the same user profile. That is, the same user_id will be linked to multiple session_token’s.To create a new link or alias, call the update user API with at least the user_id and session_token set. The new session_token will be appended to the existing user’s alias table.For example, if you authorize a user by a JSON web token that expires after two weeks.User metadataYou can save any custom metadata with a user such as the user’s email or employment title. You can search and filter by users in the Moesif portal via the metadata. The metadata must be a valid JSON object.{  &quot;is_email_verified&quot;: true,  &quot;facebook_id&quot;: &quot;123456789&quot;,  &quot;email&quot;: &quot;amy@gmail.com&quot;,  &quot;phone&quot;: &quot;123-456-7890&quot;,  &quot;first_name&quot;: &quot;Amy&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;custom_int_field&quot;: 55,  &quot;custom_obj_field&quot;: {    &quot;sub_a&quot;: &quot;value_a&quot;,    &quot;sub_b&quot;: &quot;value_b&quot;  }}The user metadata can be views in Moesif under a user’s profile. The metadata can be viewed by going to a user profile, clicking the More Actions button, and selecting Show JSON Data.The data will then be displayed in a modal to view.The same rules that apply to API Call metadata also apply to user metadata.1. Maintain consistent data typesOnce a JSON key is seen by Moesif with a specific JSON datatype, you cannot send a different JSON datatype using the same key. For example, if you previously sent to Moesif the following custom metadata for an API call:{  &quot;first_name&quot;: &quot;John Doe&quot;,  &quot;email&quot;: &quot;john@gmail.com&quot;,  &quot;phone&quot;: &quot;123-456-7890&quot;}Then, Moesif automatically saves phone as a JSON string in the metadata schema. You cannot later send a JSON Number using the same phone key. This is true regardless of the number of levels relative to the object root. The below metadata would now be invalid:{  &quot;first_name&quot;: &quot;John Doe&quot;,  &quot;email&quot;: &quot;john@gmail.com&quot;,  &quot;additional_info&quot;: {    &quot;phone&quot;: 1234567890  }}The metadata schema is shared across your organization and applications.2. Avoid dots charactersBe aware that Dot characters in a JSON key for custom metadata will be converted into an underscore by Moesif automatically. However, Dot characters in a JSON value are fine and will not be transformed.For example,{  &quot;fi.rst.na.me&quot;: &quot;John Doe&quot;,  &quot;email&quot;: &quot;john@gmail.com&quot;,}Will be converted by Moesif to:{  &quot;fi_rst_na_me&quot;: &quot;John Doe&quot;,  &quot;email&quot;: &quot;john@gmail.com&quot;,}",
      "url": " /getting-started/users/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-companies": {
      "title": "Company Profiles",
      "content"	 : "Moesif can track companies, not just individual users. If your customers are other businesses, you may want to track the individual users calling using your API separately from the organizations they are a part of.For example, suppose you’re an API provider. In that case, users may be the individual employees’ name, email, and employment title, creating API tokens and calling your API. At the same time, companies can track the organization’s name and monthly revenue. If partners use your API, then you can use the partner company as the company in Moesif.A company profile and the fields shown can be customized. To see exactly how to do this, check out the docs on Profile View.You can associate API calls to both user and a company, or just one of the two. For example, maybe you don’t have user information, so you can only associate API Calls with companies, or you’re B2C, so it makes sense to track only users.You can enrich companies with company data in your CRM or other tools.What are company properties?Companies can track arbitrary properties such as company name, industry sector, revenue or plan information, or domain name.How to track companies1. Set the identifyCompany functionBy defining an identifyCompany callback such as setting the moesif-nodejs identifyCompany() option, you ensure new API calls are associated with a specific company_id.2. Enrich the company with additional metadataIf you only did Step 1, you’ll see some company analytics in Moesif like first and last seen time. Still, it’s much more useful if you enrich your own metadata such as company name, subscription or plan revenue, number of employees, or any other metadata you want to store in Moesif.To add company metadata to Moesif, call the SDK’s updateCompany() method, such as the moesif-nodejs updateCompany() method from your code with the company_id and JSON metadata you want to store. You only need to call this when your own company data changes, such as when the customer changes their subscription.How to alias a sessionMultiple sessions tokens can be associated with the same company. For example, the same company_id can be linked to many session_token’s. This can aid you in seeing how many API tokens a specific company uses or how often.To create a new link or alias, call the update company API with at least the company_id and session_token set. Then, instead of overwriting the session_token, Moesif will append it with the existing company’s alias table.Companies metadataYou can save any custom metadata with a company, such as the company’s name, total revenue, or the number of employees. You can search and filter by companies in the Moesif portal via the metadata. The metadata must be a valid JSON object.{  &quot;company_name&quot;: &quot;Acme, Inc&quot;,  &quot;company_domain&quot;: &quot;www.acmeinc.com&quot;,  &quot;mrr&quot;: 5000,  &quot;is_paid&quot;: true,  &quot;num_employees&quot;: 100000,  &quot;custom_int_field&quot;: 55,  &quot;custom_obj_field&quot;: {    &quot;sub_a&quot;: &quot;value_a&quot;,    &quot;sub_b&quot;: &quot;value_b&quot;  }}The user metadata can be views in Moesif under a user’s profile. Viewing the metadata can be done by going to a user profile, clicking the More Actions button, and selecting Show JSON Data.The data will then be displayed in a modal to view.The same rules that apply to user metadata also apply to company metadata.1. Maintain consistent data-typesOnce a JSON key is seen by Moesif with a specific JSON data type, you cannot send a different JSON datatype using the same key. For example, if you previously sent to Moesif the following custom metadata for an API call:{  &quot;company_name&quot;: &quot;Acme, Inc&quot;,  &quot;company_domain&quot;: &quot;www.acmeinc.com&quot;,  &quot;phone&quot;: &quot;123-456-7890&quot;}Then, Moesif automatically saves phone as a JSON string in the metadata schema. You cannot later send a JSON Number using the same phone key. This is true regardless of the number of levels relative to the object root. The below metadata would now be invalid:{  &quot;company_name&quot;: &quot;Acme, Inc&quot;,  &quot;company_domain&quot;: &quot;www.acmeinc.com&quot;,  &quot;additional_info&quot;: {    &quot;phone&quot;: 1234567890  }}The metadata schema is shared across your organization and applications.2. Avoid dots charactersBe aware that Dot characters in a JSON key for custom metadata will be converted into an underscore by Moesif automatically. However, Dot characters in a JSON value are fine and will not be transformed.For example,{  &quot;comp.any.na.me&quot;: &quot;Acme, Inc&quot;}Will be converted by Moesif to:{  &quot;comp_any_na_me&quot;: &quot;John Doe&quot;}",
      "url": " /getting-started/companies/",
      "author": "Derric",
      "categories": "Getting-Started"
    }
    ,
  

    "getting-started-subscriptions": {
      "title": "Subscriptions",
      "content"	 : "A Subscription in Moesif represents a single plan a customer has subscribed to and paying for. It corresponds to the Subscriptions entity for billing providers such as Stripe. For more information, see Provider Mapping.This document describes how you can look up and analyze existing subscriptions using Moesif.How Subscriptions Relate to CompaniesTo understand how Subscriptions relate to Companies in Moesif, let’s see how Moesifmodels its data structure.Apart from API Callsand Actions event types,Moesif also tracks these entities:  Users  Companies  SubscriptionsThe following diagram illustrates how these components relate to one another:These events and entities constitute Moesif’s data structure for its API analytics, observability, and monetization capabilities.Subscriptions are how Moesif implements various monetization features in itsplatform. A subscription describes how a Company makes recurring payments fora specific product under a plan. A Company can have one or more subscriptions, as you can see in the diagram.With a built-in subscriptions model, Moesif natively integrates with differentbilling providers likeStripe and how theyimplement subscriptions.This allows you to perform various analytics on your customers based on differentsubscription and billing criteria.The following sections demonstrate some of the operations you can perform on subscription data in Moesif Web Portal.Filter on Subscription DataYou can filter on subscription data in Moesif API and customer analytics by selecting from the Subscription filters. In an API analytics workspaces like a Time Series, or a User Lookup, you can access subscription filters in Company.Subscriptions in the Filters pane. In a Company Lookup, they are available in Subscriptions in the Filters pane.For more information about the available subscription filters, see Subscription Filters Reference.The following sections showcase some example filtering scenarios.Filter Active Stripe SubscriptionsHere, in a Company Lookup, we define two filters to to see what companies have active subscriptions in Stripe.  Subscriptions.status.is.active  Subscriptions.provider.is.stripeSegment Customers By Subscription PlansThe following example uses a Segmentation analysis to break down unique users based on various Stripe subscription plans. To do so, it defines the following analysis settings:  Set the Company.Subscriptions.provider filter value to stripe.  Define the Group By filter as Company.Subscriptions.items.plan.name.Access Subscription Details in Company ProfileIn a Company Lookup, you can select a company ID and open a Company Profile view of that company. It contains, among other information, the company’s subscription-related information like subscription ID, the plans and prices they’ve subscribed to, and balances.If a company has multiple subscriptions, you can see the respective details in separate columns in the Company Profile:Company Profile also contains the following real-time visualizations in the Billing Usage and Subscription Balance panes respectively.  Usage and associated cost  Subscription balancesWhat’s Next?  Learn how to meter usage and charge customers  Learn about plans and prices  Analyze User and Company behavior",
      "url": " /getting-started/subscriptions/",
      "author": "Sakib",
      "categories": "Getting-Started"
    }
    ,
  

    "server-integration": {
      "title": "Choose a server integration",
      "content"	 : "Server integration automatically instrument your applications to log API traffic to Moesif including REST, GraphQL, XML/SOAP, RPC, and other APIs.You can mix and match multiple integrations together to gain a unified view of your API usage even if you have different API management tools and technologies. Server integrations are low-code and automatically instrument your application. Server integrations also support enforcing quotas and governance as well.If you already have an off-the-shelf API gateway deployed, we recommend using one of Moesif’s API gateway plugins. There are plugins available for most API gateways including NGINX, Kong, and WSO2. You can also install a server integration for your web/API’s framework.These integrations support logging incoming API calls hitting your own APIs and also log outgoing calls to third party services.Choose a Server IntegrationSelect a language/plugin to get started with integration.                                                                                                                                                                                Alexa Skills                                                       Node.js                                                                                                                                                  Apigee                                                                                                                                                                                                        AWS API Gateway                                                                                                                                                                                                        AWS Lambda                                                       Go                                                                                                                                                  AWS Lambda                                                       Node.js                                                                                                                                                  AWS Lambda                                                       Python                                                                                                                                                  AWS Lambda                                                       Ruby                                                                                                                                                  Azure API Management                                                                                                                                                                                                        Azure Web App Extension                                                                                                                                                                                                        Ballerina                                                                                                                                                                                                        Cloudflare Workers                                                                                                                                                                                                        C#                                                       .NET                                                                                                                                                  Envoy                                                       Lua                                                                                                                                                  Envoy                                                       WASM                                                                                                                                                  Express Gateway                                                                                                                                                                                                        Go                                                       Gin                                                                                                                                                  Go                                                                                                                                                                                                        gravitee.io                                                                                                                                                                                                        OkHttp                                                       Java, Kotlin, etc                                                                                                                                                  Java Servlet                                                       Spring, Jersey                                                                                                                                                  Java Spring Request                                                                                                                                                                                                        Kong API Gateway                                                                                                                                                                                                        Kong Ingress Controller                                                                                                                                                                                                        Kong Konnect                                                                                                                                                                                                        KrakenD                                                                                                                                                                                                        Kubernetes NGINX Ingress Controller                                                                                                                                                                                                        NGINX                                                                                                                                                                                                        NGINX Plus                                                                                                                                                                                                        Node.js                                                       Express                                                                                                                                                  OpenTelemetry                                                                                                                                                                                                        PHP                                                       Laravel                                                                                                                                                  PHP                                                       Slim                                                                                                                                                  PHP                                                       Symfony                                                                                                                                                  Play Framework                                                                                                                                                                                                        Python ASGI                                                       FastAPI                                                                                                                                                  Python                                                       Django                                                                                                                                                  Python Requests                                                                                                                                                                                                        Python Tornado                                                                                                                                                                                                        Python WSGI                                                       Flask, Bottle, Pyramid                                                                                                                                                  Ruby                                                       Rack, Rails                                                                                                                                                  Gloo Gateway                                                                                                                                                                                                        Strapi                                                                                                                                                                                                        Tyk API Gateway                                                                                                                                                                                                        WSO2 API Manager                                                                                                                                                                                                        WSO2 Kubernetes Gateway                                                                                                                                                                                                        WSO2 Bijira                                                                                                                                                                                                        WSO2 Choreo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  OpenTelemetry SupportMoesif is compatible with OpenTelemetry either through Moesif’s native integrations or Moesif’s OTel compliant endpoint. Instead of a native API Gateway or server integration, you can configure your existing OTel client to send OTel trace and log data to Moesif’s OTel compliant endpoint. See how to configure OTel clients to use Moesif.For new Moesif installations, we recommend using a native Moesif server integration for full functionality. Moesif will still capture OTel data regardless if using Moesif’s OTel endpoint or a native server integration.OpenTelemetry Limitations  The OTel integration does not support Moesif API governance rules. If you want to enforce quotas and govern access, use one of Moesif’s native server integrations.  Moesif’s dynamic sampling is not supported. However, you can still leverage OTel sampling which provides a more limited version sampling. See docs on sampling  Currently only traces and logs are captured.Custom ActionsIf you cannot use a server integration, you can directly ingest custom events via the Action API.",
      "url": " /server-integration/",
      "author": "Derric",
      "categories": "Integration"
    }
    ,
  

    "server-integration-alexa-skills-nodejs": {
      "title": "Server Integration Guide - Alexa Skills (Node.js)",
      "content"	 : "Moesif AWS Alexa Skills MiddlewareAlexa Skills Middleware (NodeJS) to automatically log API calls from your AWS Lambda functionsand sends to Moesif for API analytics and log analysis.Designed for AWS Lambda functions that use the Alexa Skills Kit as a trigger.This middleware expects theAlexa skills format.Source Code on GitHubPackage on NPMJSHow to installnpm install --save moesif-alexa-skillsHow to useThe following shows how import Moesif and use:1. Import the module:// Import Modules&#39;use strict&#39;const moesif = require(&#39;moesif-alexa-skills&#39;);const moesifOptions = {    applicationId: &#39;Your Moesif Application Id&#39;,};exports.handler = function (event, context, callback) {    callback(null, {        statusCode: &#39;200&#39;,        body: JSON.stringify({key: &#39;hello world&#39;}),        headers: {            &#39;Content-Type&#39;: &#39;application/json&#39;,        },    });};exports.handler = moesif(moesifOptions, exports.handler);2. Enter Moesif Application IdYour Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu, and then clicking Installation.Repo file structure  lib/index.js the middleware lib  index.js sample AWS Lambda function using the middlewareConfiguration optionsidentifyUserType: (event, context) =&amp;gt; StringidentifyUser is a function that takes AWS lambda event and context objects as argumentsand returns a userId. This helps us attribute requests to unique users.By default, Moesif will use event.session.user.userIdoptions.identifyUser = function (event, context) {  // your code here, must return a string  return event.requestContext.identity.cognitoIdentityId}getSessionTokenType: (event, context) =&amp;gt; StringgetSessionToken a function that takes AWS lambda event and context objects as arguments and returns asession token (i.e. such as an API key). By default, Moesif will use event.session.sessionIdoptions.getSessionToken = function (event, context) {  // your code here, must return a string.  return event.headers[&#39;Authorization&#39;];}getTagsType: (event, context) =&amp;gt; StringgetTags is a function that takes AWS lambda event and context objects as arguments and returns a comma-separated string containing a list of tags.See Moesif documentation for full list of tags.options.getTags = function (event, context) {  // your code here. must return a comma-separated string.  if (event.path.startsWith(&#39;/users&#39;) &amp;amp;&amp;amp; event.httpMethod == &#39;GET&#39;){    return &#39;user&#39;  }  return &#39;random_tag_1, random_tag2&#39;}getApiVersionType: (event, context) =&amp;gt; StringgetApiVersion is a function that takes AWS lambda event and context objects as arguments andreturns a string to tag requests with a specific version of your API.By default, Moesif will use event.versionoptions.getApiVersion = function (event, context) {  // your code here. must return a string.  return &#39;1.0.5&#39;}skipType: (event, context) =&amp;gt; Booleanskip is a function that takes AWS lambda event and context objects as arguments and returns trueif the event should be skipped (i.e. not logged)The default is shown below and skips requests to the root path “/”.options.skip = function (event, context) {  // your code here. must return a boolean.  if (event.path === &#39;/&#39;) {    // Skip probes to home page.    return true;  }  return false}maskContentType: MoesifEventModel =&amp;gt; MoesifEventModelmaskContent is a function that takes the final Moesif event model (rather than the AWS lambda event/context objects) as anargument before being sent to Moesif. With maskContent, you can make modifications to headers or body such asremoving certain header or body fields.options.maskContent = function(moesifEvent) {  // remove any field that you don&#39;t want to be sent to Moesif.  return moesifEvent;}updateUser methodA method is attached to the moesif middleware object to update the users profile or metadata.&#39;use strict&#39;const moesif = require(&#39;moesif-alexa-skills&#39;);const moesifOptions = {    applicationId: &#39;Your Moesif application_id&#39;,};var moesifMiddleware = moesif(options);var user = {  userId: &#39;your user id&#39;,  // required.  metadata: {    email: &#39;user@email.com&#39;,    name: &#39;George&#39;  }}moesifMiddleware.updateUser(user, callback);The metadata field can be any custom data you want to set on the user.The userId field is required.Other integrationsTo view more more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/alexa-skills-nodejs/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-apigee": {
      "title": "Server Integration Guide - Apigee",
      "content"	 : "Moesif Apigee IntegrationThe Moesif integration for Apigee enables you to get powerful API analytics and monetization capabilities for your Apigee environment. It works by logging API traffic to Moesif API Analytics and Monetization platform.With the Moesif plugin for Apigee, you can:  Understand customer API usage  Get alerted on API consumption and issues  Monetize APIs with usage-based billing  Enforce quotas and limits  Guide customers using your APIsThe integration is a javascript policy which installs within the Apigee console in a few clicks.1. Add a Javascript policy  Within the Apigee console, go to your API Proxy and click add a policy.  Select “Javascript” within the drop down  Select a file and upload the file moesif-api-analytics.js.2. Configure policyWithin the XML added, define the properties below to add your Moesif Application Id&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&amp;gt;&amp;lt;Javascript continueOnError=&quot;true&quot; enabled=&quot;true&quot; timeLimit=&quot;200&quot; name=&quot;JS-MOESIF&quot;&amp;gt;  &amp;lt;DisplayName&amp;gt;JS-MOESIF-API-ANALYTICS&amp;lt;/DisplayName&amp;gt;  &amp;lt;Properties&amp;gt;    &amp;lt;Property name=&quot;applicationId&quot;&amp;gt;Your Moesif Application Id&amp;lt;/Property&amp;gt;    &amp;lt;Property name=&quot;logBody&quot;&amp;gt;true&amp;lt;/Property&amp;gt;    &amp;lt;Property name=&quot;debug&quot;&amp;gt;false&amp;lt;/Property&amp;gt;  &amp;lt;/Properties&amp;gt;  &amp;lt;ResourceURL&amp;gt;jsc://moesif-api-analytics.js&amp;lt;/ResourceURL&amp;gt;&amp;lt;/Javascript&amp;gt;Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps or by going to API keys section within Moesif settings.3. Enable the PolicyWithin Proxy Endoints, attach the Moesif policy to the APIs you want monitored by Moesif.High Volume APIsFor high volume APIs, it’s strongly recommended to leverage Moesif’s secure proxy to buffer requests. This ensures optimal performance of your API gateway and infrastructure.LimitationsThis policy has been recently released and still in preview.Moesif dynamic sampling and governance rules are not yet supported but coming soon.",
      "url": " /server-integration/apigee/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-aws-api-gateway": {
      "title": "Server Integration Guide - AWS API Gateway",
      "content"	 : "Moesif AWS API Gateway IntegrationIntegrate Moesif API Monetization and Analytics with your AWS API Gateway without any code changes or redeploy. This integration installs automatically via a CloudFormation template.How it worksThe integration works by Logging API calls to an Amazon Data Firehose which sends API access logs in batches to Moesif. Besides tracking typical API parameters like URI route and status code, the integration also tracks the user identity which makes them perfect for user behavior analytics tools like Moesif.Because you are monitoring at the API gateway itself, you also gain visibility into rejected requests that never reach your underlying service such as those running in AWS Lambda or EC2.This integration only supports AWS Gateway of type REST API and REST API Private. If your gateway is not a REST API Type, you must use one of the SDKs.How to Install1. Create an Amazon Data Firehose  Click the below Launch Stack button to open CloudFormation which will automatically create a new Data Firehose configured with Moesif collection API as the destination.  In the MoesifApplicationId field of the Parameters section, enter yourMoesif Application ID. To get your Application ID, follow these steps:          Log into Moesif Portal.      Select the account icon to bring up the settings menu.      Select Installation or API Keys.      Copy your Moesif Application ID from the Collector Application ID field.        Ensure you checkbox I acknowledge that AWS CloudFormation might create IAM resources. Then click Create Stack.  If you experience errors or want to create the Firehose manually, follow these instructionsAfter the stack is created, search for “Firehose” in the AWS Console search bar and select Amazon Data Firehose.You’ll need the newly created Firehose ARN for the next step.2. Enable API Gateway access loggingWith the Firehose created, you need to configure API Gateway to send access logs to it.  Go to your AWS API Gateway instance within the AWS Console.  Select Stages on the left menu and then select Edit under the “Logs and tracing” section.  Within the Edit logs and tracing panel, toggle on Custom access logging.  Add your Data Firehose ARN created from Step 1 under Access Log Destination ARN.  For Log format, add the below JSON snippet. Ensure the JSON is minified into a single line like below.{&quot;apiId&quot;:&quot;$context.apiId&quot;,&quot;requestId&quot;:&quot;$context.requestId&quot;,&quot;requestTime&quot;:&quot;$context.requestTime&quot;,&quot;protocol&quot;:&quot;$context.protocol&quot;,&quot;httpMethod&quot;:&quot;$context.httpMethod&quot;,&quot;resourcePath&quot;:&quot;$context.path&quot;,&quot;requestHostHeader&quot;:&quot;$context.domainName&quot;,&quot;requestUserAgentHeader&quot;:&quot;$context.identity.userAgent&quot;,&quot;ip&quot;:&quot;$context.identity.sourceIp&quot;,&quot;status&quot;:&quot;$context.status&quot;,&quot;responseLength&quot;:&quot;$context.responseLength&quot;,&quot;durationMs&quot;:&quot;$context.responseLatency&quot;,&quot;caller&quot;:&quot;$context.identity.caller&quot;,&quot;user&quot;:&quot;$context.identity.user&quot;,&quot;principalId&quot;:&quot;$context.authorizer.principalId&quot;,&quot;cognitoIdentityId&quot;:&quot;$context.identity.cognitoIdentityId&quot;,&quot;userArn&quot;:&quot;$context.identity.userArn&quot;,&quot;apiKeyId&quot;:&quot;$context.identity.apiKeyId&quot;,&quot;metadata&quot;:{&quot;apiKey&quot;:&quot;$context.identity.apiKey&quot;,&quot;stage&quot;:&quot;$context.stage&quot;}}The above Log format works by mapping AWS $context variables to Moesif variables. For more info surrounding available $context variables, check out the AWS docsIt’s not possible to log the request and response body with this integration. If you require analytics on body fields, choose a different integration such as a SDK-based integration.Click Save Changes and that’s it! API logs should start showing up after a few minutes.You may need to redeploy your stage if logs are not showing up in Moesif.Overview of User TrackingWith the above Log format, the integration also logs the various identity variables so that Moesif can properly identify the user. For most integrations, no change is needed and the default Log format already includes covers all built in API Gateway access control methods and authorizers used.            Priority      Moesif Variable      AWS Context Variable      Description                  1.      user      $context.identity.user      The principal identifier of the user. Supported for IAM authorization.              2.      apiKeyId      $context.identity.apiKeyId      The API key ID associated with an API request that requires an API key.              3.      principalId      $context.authorizer.principalId      The principal user id associated returned from an API Gateway Lambda authorizer such as a custom one that extracts the subject from a JWT (Json Web Token).              4.      cognitoIdentityId      $context.identity.cognitoIdentityId      The Amazon Cognito identity ID of the caller making the request.              5.      caller      $context.identity.caller      The principal identifier of the caller that signed the request. Supported for IAM authorization.              6.      userArn      $context.identity.userArn      The Amazon Resource Name (ARN) of the effective user identified after authentication.      Priority of Identity VariablesIf multiple identities are available (uncommon), the above table defines the priority to select an identity. For example, if you are using a custom lambda authorizer which extracts the subject from a JWT (Json Web Token), then your lambda function would normally return the principalId which is automatically populated in $context.authorizer.principalId by AWS. Moesif will then use this (assuming $context.identity.user and $context.identity.apiKeyId are not defined as these are higher priority).Customize User IdentificationWhile automatic extraction should be sufficient for most applications, you can override Moesif’s default behavior.To do so, update your Log format to map an AWS $context variable to the Moesif field user. Any AWS context variable can be used as long as it’s a “string” type.For example, if you want to use the source IP address as the user id, modify user in your JSON log format to look like below:{  &quot;user&quot;: &quot;$context.identity.sourceIp&quot;}If the field is not already available as an $context variable, you can add it to the authorizer context in your lambda authorizer. This works only if using a custom lambda authorizer.Enabling Company TrackingThe Moesif AWS API Gateway integration can also enable company tracking as well. This value can be added into Moesif in two distinct ways:  The first option uses the companyId variable within the gateways log format (similar to user tracking). To do so, modify the Moesif field companyId in your JSON log format to refer to the appropriate AWS context variable. For example, you may use $context.identity.apiKeyId or another unique identifier within the available context variables.{  &quot;companyId&quot;: &quot;$context.identity.apiKeyId&quot;}  Secondly, for more flexibility, users can also use the Moesif API to link users to companies via the update users API. Specifics can be found in the docs, here.Event MetadataBesides the above default template variables, you can include additional AWS context variables not already mapped by modifying your Log format. They must be added as part of the queryString, the request.headers, or the metadata field.  For queryString, Moesif will parse this as a query string. Must be in format like a=1&amp;amp;b=2  For request.headers, Moesif wil parse and display these as HTTP headers within Moesif UI.  For metadata, Moesif will parse as the custom event metadata. Use this for any data not part of queryString or request.headers custom to your application.            Field      Format              queryString      The full query string starting with ?. It should be already url encoded such as a=1&amp;amp;b=2              request.headers      Map of key/values of headers like Content-Type and X-Forwarded-For. Values must be primitive types that conform to HTTP header values.              metadata      JSON object of data that’s not already part of query string or headers      Below is an example Log format which maps an additional AWS variable $context.error.message to a new metadata field my_error_message.The rest of Log format fields are omitted for brevity.{  &quot;metadata&quot;: { &quot;my_error_message&quot;: &quot;$context.error.message&quot; }}Any AWS $context variables can be included as part of the metadata.Including event fields not in $contextAWS Log format only supports the $context variables. This works well like in the above example which is already in the $context. However, many event fields like request headers are not part of the $context variables.You can still indirectly include these event fields by returning their key-value pairs as part of the authorizer context from a custom Lambda authorizer function. By doing so, you can then reference the key-values via $context.authorizer.keyName where keyName is your key name.For example, let’s say we want to save the operationName and a request header X-Forwarded-For which are not part of the $context variables.You can read them in a custom lambda authorizer such as in the example Python lambda below. Notice how we set two fields as part of the returned context.import jsondef lambda_handler(event, context):    print(json.dumps(event))    query_string = urlencode(event.get(&#39;queryStringParameters&#39;, {}))    # Construct the policy document    auth_response = {        &quot;principalId&quot;: &quot;user1234&quot;,        &quot;policyDocument&quot;: {            &quot;Version&quot;: &quot;2012-10-17&quot;,            &quot;Statement&quot;: [                {                    &quot;Action&quot;: &quot;execute-api:Invoke&quot;,                    &quot;Effect&quot;: &quot;Allow&quot;,                    &quot;Resource&quot;: event[&#39;methodArn&#39;]                }            ]        },        &quot;context&quot;: {            # The query string            &quot;queryString&quot;: query_string,            # A request header            &quot;x_forwarded_for&quot;: event[&#39;headers&#39;].get(&#39;X-Forwarded-For&#39;, None),            &quot;content_type&quot;: event[&#39;headers&#39;].get(&#39;Content-Type&#39;, None),            # An arbitrary  metadata field            &quot;operation_name&quot;: event[&#39;requestContext&#39;].get(&#39;operationName&#39;, &#39;&#39;)        }    }    # Return the policy document    return auth_responseOnce done, you can now reference the variables like so in your Log format:{    &quot;queryString&quot;: &quot;$context.authorizer.queryString&quot;,    &quot;headers&quot;: {        &quot;X-Forwarded-For&quot;: &quot;$context.authorizer.x_forwarded_for&quot;,        &quot;Content-Type&quot;: &quot;$context.authorizer.content_type&quot;    },    &quot;metadata&quot;: {        &quot;operation_name&quot;: &quot;$context.authorizer.operation_name&quot;    }}With this solution, you can include any fields available in the event context.AWS Restrictions:  AWS Does not support nesting for the authorizer context.authorizer.*  AWS Does not support dashes for field names for context.authorizer.*Supporting Quotas &amp;amp; Governance RulesWith the default integration, API traffic will be logged to Moesif via firehose, but Moesif governance rules will not be enforced. If you require governance rules such as to enforce quotas or block cancelled subscriptions, you can integrate with the Moesif governance rules APIs within your custom lambda authorizer for AWS API Gateway.Moesif has an example lambda authorizer available on GitHub.By enforcing governance rules at the API Gateway layer, you have a central spot to reject requests and you have better protection of your underlying services as the requests will never hit them.Alternatively, if you can’t add a lambda authorizer or prefer a more out-of-the-box integration, you can also install a Moesif server integration for your API/web framework. In your SDK configuration, make sure you skip all logging so you don’t duplicate events that are already logged via the firehose. Because you can mix-and-match multiple Moesif integrations, you can enforce governance through the Moesif server integrations like moesif-nodejs, while still maintaining logging through this API Gateway integration.TroubleshootingManual Firehose CreationIf you cannot use the CloudFormation template or having issues, you can manually create and configure a Kinesis Data Firehose usingthe HTTP destination.Go to Amazon Kinesis within the AWS Console and select Create Delivery Stream.The name of your delivery stream must start with amazon-apigateway-  For the source, select Direct PUT or other sources.  For the destination, select HTTP Endpoint and enter the following:  For HTTP endpoint URL, enter https://api.moesif.net/v1/partners/aws/kinesis  For Access key, enter your Moesif Application Id.  For Buffer interval, enter 60 seconds.  Enable GZIP compression.Finish the creation wizard and make a note of the Firehose ARN.Complete the rest of the guide using your Firehose ARN.This should be in the same region where you created the Firehose.LimitationsThere are certain limitations to be aware of below. You can use an alternative Moesif server integration as a workaround for any of these limitations.  This integration supports REST API and REST API Private. It does not support a Websockets or HTTP Gateway.  Request and Response Body fields are not logged.  Governance rules will not be enforced until you integrate the governance rules API.",
      "url": " /server-integration/aws-api-gateway/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-aws-lambda-go": {
      "title": "Server Integration Guide - AWS Lambda (Go)",
      "content"	 : "Moesif AWS Lambda Middleware for GoGo Middleware for AWS Lambda that automatically logs API calls and sends to Moesif for API analytics and log analysis.Designed for APIs that are hosted on AWS Lambda using Amazon API Gateway or Application Load Balanceras a trigger.How to installRun the following commands:moesif-aws-lambda-go can be installed like any other Go library through go get:go get github.com/moesif/moesif-aws-lambda-goOr, if you are already using Go Modules, specify a version number as well:go get github.com/moesif/moesif-aws-lambda-go@v1.0.3How to use1. Add middleware to your Lambda application.package mainimport (&quot;github.com/aws/aws-lambda-go/lambda&quot;&quot;github.com/aws/aws-lambda-go/events&quot;    &quot;context&quot;    &quot;strings&quot;    &quot;github.com/aws/aws-lambda-go/events&quot;moesifawslambda &quot;github.com/moesif/moesif-aws-lambda-go&quot;)func MoesifOptions() map[string]interface{} {var moesifOptions = map[string]interface{} {&quot;Log_Body&quot;: true,}return moesifOptions}func HandleLambdaEvent(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {return events.APIGatewayProxyResponse{Body:       request.Body,StatusCode: 200,Headers: map[string] string {&quot;Content-Type&quot;:   &quot;application/json&quot;,},   }, nil}func main() {lambda.Start(moesifawslambda.MoesifLogger(HandleLambdaEvent, MoesifOptions()))}2. Set MOESIF_APPLICATION_ID environment variableAdd a new environment variable with the name MOESIF_APPLICATION_ID and the value being your Moesif application id,which can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu, and then clicking Installation.Optional: Capturing outgoing API callsIn addition to your own APIs, you can also start capturing calls out to third party services via the following method:func MoesifOptions() map[string]interface{} {var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,&quot;Log_Body&quot;: true,}return moesifOptions}moesifawslambda.StartCaptureOutgoing(MoesifOptions())moesifOption(required), map[string]interface{}, are the configuration options for your application. Please find the details below on how to configure options.Configuration optionsPlease note that the request and response parameters in the configuration options are as follows:  Payload Format 1.0:          Request: APIGatewayProxyRequest      Response: APIGatewayProxyResponse        Payload Format 2.0:          Request: APIGatewayV2HTTPRequest      Response: APIGatewayV2HTTPResponse      Should_Skip(optional) (request, response) =&amp;gt; boolean, a function that takes a request and a response,and returns true if you want to skip this particular event.Identify_User(optional, but highly recommended) (request, response) =&amp;gt; string, a function that takes a request and response, and returns a string that is the user id used by your system. While Moesif tries to identify users automatically, but different frameworks and your implementation might be very different, it would be helpful and much more accurate to provide this function.Identify_Company(optional) (request, response) =&amp;gt; string, a function that takes a request and response, and returns a string that is the company id for this event.Get_Metadata(optional) (request, response) =&amp;gt; dictionary, a function that takes a request and response, andreturns a dictionary (must be able to be encoded into JSON). This allows youto associate this event with custom metadata. For example, you may want to save a VM instance_id, a trace_id, or a tenant_id with the request.Get_Session_Token(optional) (request, response) =&amp;gt; string, a function that takes a request and response, and returns a string that is the session token for this event. Moesif tries to get the session token automatically, but if this doesn’t work for your service, you should use this to identify sessions.Mask_Event_Model(optional) (EventModel) =&amp;gt; EventModel, a function that takes an EventModel and returns an EventModel with desired data removed. The return value must be a valid EventModel required by Moesif data ingestion API. For details regarding EventModel please see the Moesif Golang API Documentation.Debug(optional) boolean, a flag to see debugging messages.Log_Body(optional) boolean, Default true. Set to false to remove logging request and response body to Moesif.Options for logging outgoing callsThe options below are applied to outgoing API calls. The request and response objects passed in are Request request and Response response objects.Should_Skip_Outgoing(optional) (request, response) =&amp;gt; boolean, a function that takes a request and response, and returns true if you want to skip this particular event.Identify_User_Outgoing(optional, but highly recommended) (request, response) =&amp;gt; string, a function that takes request and response, and returns a string that is the user id used by your system. While Moesif tries to identify users automatically,but different frameworks and your implementation might be very different, it would be helpful and much more accurate to provide this function.Identify_Company_Outgoing(optional) (request, response) =&amp;gt; string, a function that takes request and response, and returns a string that is the company id for this event.Get_Metadata_Outgoing(optional) (request, response) =&amp;gt; dictionary, a function that takes request and response, andreturns a dictionary (must be able to be encoded into JSON). This allowsto associate this event with custom metadata. For example, you may want to save a VM instance_id, a trace_id, or a tenant_id with the request.Get_Session_Token_Outgoing(optional) (request, response) =&amp;gt; string, a function that takes request and response, and returns a string that is the session token for this event. Again, Moesif tries to get the session token automatically, but if you setup is very different from standard, this function will be very help for tying events together, and help you replay the events.Mask_Event_Model_Outgoing(optional) (EventModel) =&amp;gt; EventModel, a function that takes an EventModel and returns an EventModel with desired data removed. The return value must be a valid EventModel required by Moesif data ingestion API. For details regarding EventModel please see the Moesif Golang API Documentation.Log_Body_Outgoing(optional) boolean, Default true. Set to false to remove logging request and response body to Moesif.Update UserUpdateUser methodCreate or update a user profile in Moesif.The metadata field can be any customer demographic or other info you want to store.Only the UserId field is required.This method is a convenient helper that calls the Moesif API lib.For details, visit the Go API Reference.import (moesifawslambda &quot;github.com/moesif/moesif-aws-lambda-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduser := models.UserModel{  UserId:  &quot;12345&quot;,  CompanyId:  literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}// Update Usermoesifawslambda.UpdateUser(&amp;amp;user, moesifOption)UpdateUsersBatch methodSimilar to UpdateUser, but used to update a list of users in one batch. Only the UserId field is required.This method is a convenient helper that calls the Moesif API lib.For details, visit the Go API Reference.import (moesifawslambda &quot;github.com/moesif/moesif-aws-lambda-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// List of Usersvar users []*models.UserModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduserA := models.UserModel{  UserId:  &quot;12345&quot;,  CompanyId:  literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}users = append(users, &amp;amp;userA)// Update Usermoesifawslambda.UpdateUsersBatch(users, moesifOption)Update CompanyUpdateCompany methodCreate or update a company profile in Moesif.The metadata field can be any company demographic or other info you want to store.Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API lib.For details, visit the Go API Reference.import (moesifawslambda &quot;github.com/moesif/moesif-aws-lambda-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompany := models.CompanyModel{CompanyId:  &quot;67890&quot;,// The only required field is your company idCompanyDomain:  literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info Campaign:   &amp;amp;campaign,Metadata:    &amp;amp;metadata,}// Update Companymoesifawslambda.UpdateCompany(&amp;amp;company, moesifOption)UpdateCompaniesBatch methodSimilar to UpdateCompany, but used to update a list of companies in one batch. Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API lib.For details, visit the Go API Reference.import (moesifawslambda &quot;github.com/moesif/moesif-aws-lambda-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// List of Companiesvar companies []*models.CompanyModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompanyA := models.CompanyModel{CompanyId:  &quot;67890&quot;,// The only required field is your company idCompanyDomain:  literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info Campaign:   &amp;amp;campaign,Metadata:    &amp;amp;metadata,}companies = append(companies, &amp;amp;companyA)// Update Companiesmoesifawslambda.UpdateCompaniesBatch(companies, moesifOption)Examples  A complete example is available on GitHub.Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/aws-lambda-go/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-aws-lambda-nodejs": {
      "title": "Server Integration Guide - AWS Lambda (Node.js)",
      "content"	 : "Moesif AWS Lambda Middleware for Node.js documentationby Moesif, the API analytics and API monetization platform.With Moesif Node.js middleware for AWS Lambda, you can automatically log API callsand send them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics andAPI monetization features into your Node.js applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.Who This Middleware is ForWe’ve designed Moesif Node.js middleware for AWS Lambda for APIs that you hoston AWS Lambda using Amazon API Gateway or Application Load Balanceras a trigger. The middleware works with REST APIs, GraphQL APIs(such as with apollo-server-lambda), and more.If you’re running a Node.js framework like Express.js on AWS Lambda and prefer to not have anyAWS-specific dependencies, Moesif also has a Node.js middleware available. The Node.js middleware supports all Node.js frameworks, including Express.js.However, the Node.js middleware doesn’t capture Lambda-specific context like trade ID.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the middlewareIn your project directory, install the middleware as a project dependency:npm install --save moesif-aws-lambdaConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to use1. Import the Module and Initialize// Import Modules&#39;use strict&#39;const moesif = require(&#39;moesif-aws-lambda&#39;);const moesifOptions = {    applicationId: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    identifyUser: function (event, context) {        return event.requestContext.identity.cognitoIdentityId    },    identifyCompany: function (event, context) {        return &#39;5678&#39;    }};exports.handler = function (event, context, callback) {    callback(null, {        statusCode: &#39;200&#39;,        body: JSON.stringify({key: &#39;hello world&#39;}),        headers: {            &#39;Content-Type&#39;: &#39;application/json&#39;,        },    });};exports.handler = moesif(moesifOptions, exports.handler);Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Depends on the version of Node.js, you can also import directly:import moesif from &#39;moesif-aws-lambda&#39;If you are using ECMAScript modules (ES modules) or later version of ES modules, try the following method:const moesifImportWrapper = await import(&#39;moesif-aws-lambda&#39;);const moesif = moesifImportWrapper.default;2. Enter Your Moesif Application IDThe middleware expects your Moesif Application ID in the applicationId key of the Moesif initialization options object.For instructions on how to obtain your Application ID, see Get your Moesif Application ID.You can hardcode your Moesif Application ID value in applicationId. But we highly recommend that you use a more secure option like environment variables to store your Application ID. If you set the environment variable as MOESIF_APPLICATION_ID, Moesif automatically picks it up without you having to explicitly specify it in the applicationId key.3. Call Your APIFinally, grab the URL to your API Gateway or Application Load Balancer and make some HTTP requests using a tool like Postman or cURL.  In order for your events to log to Moesif, you must test using the Amazon API Gateway trigger. Do not invoke your Lambda directly using AWS Console as the payload won’t contain a valid HTTP payload.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── app.js├── images/├── lib/├── LICENSE├── package.json├── package-lock.json├── README.md└── tests/These are the most important files:  lib/index.js: the middleware library  app.js: sample AWS Lambda function using the middlewareConfiguration OptionsThe following sections describe the available configuration options for this middleware. You can set these options in the Moesif initialization options object. See the sample AWS Lambda middleware function code for an example.logBody         Data type          Default              Boolean          true     Whether to log request and response body to Moesif.identifyUser         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as argumentsand returns a user ID. This allows Moesif to attribute API requests to individual unique usersso you can understand who is calling your API. You can use this simultaneously with identifyCompanyto track both individual customers and the companies they are a part of.options.identifyUser = function (event, context) {  // your code here, must return a string  return event.requestContext.identity.cognitoIdentityId}identifyCompany         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as argumentsand returns a company ID. If you have a B2B business, this allows Moesif to attributeAPI requests to specific companies or organizations so you can understand which accounts arecalling your API. You can use this simultaneously with identifyUser to track bothindividual customers and the companies they are a part of.options.identifyCompany = function (event, context) {  // your code here, must return a string  return &#39;5678&#39;}getSessionToken         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as arguments and returns asession token such as an API key.options.getSessionToken = function (event, context) {  // your code here, must return a string.  return event.headers[&#39;Authorization&#39;];}getApiVersion         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as arguments andreturns a string to tag requests with a specific version of your API.options.getApiVersion = function (event, context) {  // your code here. must return a string.  return &#39;1.0.5&#39;}getMetadata         Data type          Parameters          Return type              Function          (event, context)          Object     A function that takes AWS lambda event and context objects as arguments and returns an object.This function allows youto add custom metadata that Moesif can associate with the request. The metadata must be a simple JavaScript object that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.options.getMetadata = function (event, context)  {  // your code here:  return {    foo: &#39;custom data&#39;,    bar: &#39;another custom data&#39;  };}skip         Data type          Parameters          Return type              Function          (event, context)          Boolean     A function that takes AWS lambda event and context objects as arguments and returns trueif you want to skip the event. Skipping an event means Moesif doesn’t log the event.The following example skips requests to the root path /:options.skip = function (event, context) {  // your code here. must return a boolean.  if (event.path === &#39;/&#39;) {    // Skip probes to home page.    return true;  }  return false}maskContent         Data type          Parameters          Return type              Function          (MoesifEventModel)          MoesifEventModel     A function that takes the final Moesif event model, rather than the AWS lambda event or context objects, as anargument before the middleware sends the event model object to Moesif.With maskContent, you can make modifications to headers or body such asremoving certain header or body fields.options.maskContent = function(moesifEvent) {  // remove any field that you don&#39;t want to be sent to Moesif.  return moesifEvent;}Moesif’s event model format looks like this:{  &quot;request&quot;: {    &quot;time&quot;: &quot;2019-08-08T04:45:42.914&quot;,    &quot;uri&quot;: &quot;https://api.acmeinc.com/items/83738/reviews/&quot;,    &quot;verb&quot;: &quot;POST&quot;,    &quot;api_version&quot;: &quot;1.1.0&quot;,    &quot;ip_address&quot;: &quot;61.48.220.123&quot;,    &quot;headers&quot;: {      &quot;Host&quot;: &quot;api.acmeinc.com&quot;,      &quot;Accept&quot;: &quot;*/*&quot;,      &quot;Connection&quot;: &quot;Keep-Alive&quot;,      &quot;Content-Type&quot;: &quot;application/json&quot;,      &quot;Content-Length&quot;: &quot;126&quot;,      &quot;Accept-Encoding&quot;: &quot;gzip&quot;    },    &quot;body&quot;: {      &quot;items&quot;: [        {          &quot;direction_type&quot;: 1,          &quot;item_id&quot;: &quot;fwdsfrf&quot;,          &quot;liked&quot;: false        },        {          &quot;direction_type&quot;: 2,          &quot;item_id&quot;: &quot;d43d3f&quot;,          &quot;liked&quot;: true        }      ]    }  },  &quot;response&quot;: {    &quot;time&quot;: &quot;2019-08-08T04:45:42.924&quot;,    &quot;status&quot;: 500,    &quot;headers&quot;: {      &quot;Vary&quot;: &quot;Accept-Encoding&quot;,      &quot;Pragma&quot;: &quot;no-cache&quot;,      &quot;Expires&quot;: &quot;-1&quot;,      &quot;Content-Type&quot;: &quot;application/json; charset=utf-8&quot;,      &quot;Cache-Control&quot;: &quot;no-cache&quot;    },    &quot;body&quot;: {      &quot;Error&quot;: &quot;InvalidArgumentException&quot;,      &quot;Message&quot;: &quot;Missing field location&quot;    }  },  &quot;user_id&quot;: &quot;my_user_id&quot;,  &quot;company_id&quot;: &quot;my_company_id&quot;,  &quot;session_token&quot;:&quot;end_user_session_token&quot;,  &quot;tags&quot;: &quot;tag1, tag2&quot;}For more information about the different fields of Moesif’s event model,see the following table or the Moesif Node.js API documentation.            Name      Required      Description                  request      Yes      The object that specifies the API request.              request.time      Yes      Timestamp for the request in ISO 8601 format.              request.uri      Yes      Full URI such as https://api.com/?query=string including host, query string, and so on.              request.verb      Yes      The HTTP method—for example, GET and POST.              request.api_version      No      API Version you want to tag this request with such as 1.0.0.              request.ip_address      No      IP address of the client. If not set, Moesif uses the IP address of your logging API calls.              request.headers      Yes      Headers of the  request as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              request.body      No      Body of the request in JSON format or base64 encoded binary data. To specify the transfer encoding, use request.transfer_encoding.              request.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the request body assumed to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           response      No      The object that specifies the response message. If not set, it implies a null response such as a timeout.              response.time      Yes      Timestamp for the response in ISO 8601 format.              response.status      Yes      HTTP response status code number such as 200 OK or 500 Internal Server Error.              response.ip_address      No      IP address of the responding server.              response.headers      Yes      Headers of the response as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              response.body      No      Body of the response in JSON format or base64 encoded binary data. To specify the transfer encoding, use response.transfer_encoding              response.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the body to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           session_token      Recommended      The end user session token such as a JWT or API key, which may or may not be temporary. Moesif automatically detects the session token if not set.              user_id      Recommended      Identifies this API call to a permanent user ID.              metadata      No      A JSON Object consisting of any custom metadata to be stored with this event.      debug         Data type          Default              Boolean          undefined     Set to true to print debug logs if you’re having integration issues.Capture Outgoing API CallsIf you want to capture all outgoing API calls from your Node.js app to third parties likeStripe or to your own dependencies, call startCaptureOutgoing() to start capturing.const moesif = require(&#39;moesif-aws-lambda&#39;);var moesifMiddleware = moesif(options);moesifMiddleware.startCaptureOutgoing();The same set of options also applies to outgoing API calls, with a few key differences:There are several configuration option functions that take request and response object as arguments. The request and response objects passed into those functionsare not Express or Node.js request or response objects when the request is outgoing, but Moesif mockssome of the fields for convenience.Only a subset of the Node.js request or response fields are available, specifically the following:mo_mocked         Data type          Description              Boolean          Set to true if it is a mocked request or response object, for example, outgoing API call.     headers         Data type          Description              Object          A mapping of header names to header values. Case sensitive.     url         Data type          Description              String          The full request URL.     method         Data type          Description              String          The HTTP method such as GET or POST.     statusCode         Data type          Description              Number          The HTTP response status code number.     getHeader         Data type          Parameters          Return type          Description              Function          (String)          String          Reads out a header on the request. Name is case insensitive     get         Data type          Parameters          Return type          Description              Function          (String)          String          Reads out a header on the request. Name is case insensitive     body         Data type          Description              JSON object          The request body as sent to Moesif.     ExamplesSee the example AWS Lambda function that uses this middleware.The following examples demonstrate how to add and update customer information.Update a Single UserTo create or update a user profile in Moesif, use the updateUser() function.var moesifMiddleware = moesif(options);// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema// metadata can be any custom objectvar user = {  userId: &#39;12345&#39;,  companyId: &#39;67890&#39;, // If set, associate user with a company object  campaign: {    utmSource: &#39;google&#39;,    utmMedium: &#39;cpc&#39;,    utmCampaign: &#39;adwords&#39;,    utmTerm: &#39;api+tooling&#39;,    utmContent: &#39;landing&#39;  },  metadata: {    email: &#39;john@acmeinc.com&#39;,    firstName: &#39;John&#39;,    lastName: &#39;Doe&#39;,    title: &#39;Software Engineer&#39;,    salesInfo: {        stage: &#39;Customer&#39;,        lifetimeValue: 24000,        accountOwner: &#39;mary@contoso.com&#39;    }  }};moesifMiddleware.updateUser(user, callback);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update Users in BatchTo update a list of users in one batch, use the updateUsersBatch() function.var moesifMiddleware = moesif(options);// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema//// Define the users.var user = {  userId: &#39;12345&#39;,  companyId: &#39;67890&#39;, // If set, associate user with a company object  campaign: {    utmSource: &#39;google&#39;,    utmMedium: &#39;cpc&#39;,    utmCampaign: &#39;adwords&#39;,    utmTerm: &#39;api+tooling&#39;,    utmContent: &#39;landing&#39;  },  // Metadata can be any custom object  metadata: {    email: &#39;john@acmeinc.com&#39;,    firstName: &#39;John&#39;,    lastName: &#39;Doe&#39;,    title: &#39;Software Engineer&#39;,    salesInfo: {        stage: &#39;Customer&#39;,        lifetimeValue: 24000,        accountOwner: &#39;mary@contoso.com&#39;    }  }};// Put the users you inside an array.var users = [user]// Call the function with the list of users.moesifMiddleware.updateUsersBatch(users, callback);The metadata field can contain any customer demographic or other info you want to store. MOesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update a Single CompanyTo update a single company, use the updateCompany() function.var moesifMiddleware = moesif(options);// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema// metadata can be any custom objectvar company = {  companyId: &#39;67890&#39;,  companyDomain: &#39;acmeinc.com&#39;, // If domain is set, Moesif will enrich your profiles with publicly available info  campaign: {    utmSource: &#39;google&#39;,    utmMedium: &#39;cpc&#39;,    utmCampaign: &#39;adwords&#39;,    utmTerm: &#39;api+tooling&#39;,    utmContent: &#39;landing&#39;  },  metadata: {    orgName: &#39;Acme, Inc&#39;,    planName: &#39;Free Plan&#39;,    dealStage: &#39;Lead&#39;,    mrr: 24000,    demographics: {      alexaRanking: 500000,      employeeCount: 47    }  }};moesifMiddleware.updateCompany(company, callback);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update Companies in BatchTo update a list of companies in one batch, use the updateCompaniesBatch() function.var moesifMiddleware = moesif(options);// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema//// Define your companies.var company = {  companyId: &#39;67890&#39;,  companyDomain: &#39;acmeinc.com&#39;, // If domain is set, Moesif will enrich your profiles with publicly available info  campaign: {    utmSource: &#39;google&#39;,    utmMedium: &#39;cpc&#39;,    utmCampaign: &#39;adwords&#39;,    utmTerm: &#39;api+tooling&#39;,    utmContent: &#39;landing&#39;  },  // Metadata can be any custom object  metadata: {    orgName: &#39;Acme, Inc&#39;,    planName: &#39;Free Plan&#39;,    dealStage: &#39;Lead&#39;,    mrr: 24000,    demographics: {      alexaRanking: 500000,      employeeCount: 47    }  }};// Put the companies inside an array.var companies = [company]// Call the function with the list of companies.moesifMiddleware.updateCompaniesBatch(companies, callback);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Additional DocumentationFor more information and examples, see the following:  REST API Example: an AWS Lambda REST API built with Express.js.  Apollo GraphQL Example: an AWS Lambda GraphQL API built with Apollo.  Moesif, Middy, and Serverless Example: an example showcasing how to use this middleware with Middy and Serverless Framework.Note about AWS Cold Start and Governance RulesThe moesif-aws-lambda-nodejs SDK fetches governance configuration from Moesif (for example, rules on which users or companies to block) and caches it in the Lambda execution environment’s memory.For warm invocations (where the Lambda execution environment is already initialized), this in-memory cache works as expected.On cold starts (when a new execution environment is initialized), there can be a short window before the configuration is fetched and the cache is populated. During this startup window, the SDK loads configuration asynchronously in the background, so governance decisions (like blocking) may not apply immediately.In typical production APIs, regular traffic keeps functions warm, so the likelihood of requests slipping through this initial window is small.In isolated tests or very low-traffic scenarios, the execution environment may be recycled and the cache cleared, recreating the short window until configuration is reloaded. When testing, please send few normal request to keep the system warm first.Cold Start GovernanceYou can enforce that initial requests during a Lambda cold start wait until Moesif Config and Governance Rules are loaded.  waitForGovernanceOnColdStart (Boolean): When true, the middleware blocks the first invocations until governance rules are fetched and the app config is available. Default: false.  governanceLoadTimeoutMs (Number): Maximum time in milliseconds to wait for config before proceeding even if it hasn’t loaded, to avoid indefinite blocking. Default: 5000.Example:const moesif = require(&#39;moesif-aws-lambda&#39;);const options = {  applicationId: process.env.MOESIF_APPLICATION_ID,  waitForGovernanceOnColdStart: true,  governanceLoadTimeoutMs: 8000,};exports.handler = moesif(options, async (event, context) =&amp;gt; {  return {    statusCode: 200,    headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },    body: JSON.stringify({ ok: true })  };});Notes:  Requests during cold start may take longer but ensure governance is applied when rules exist.  If the timeout elapses without config, the request proceeds to avoid indefinite delays.How to Get HelpIf you face any issues using this middleware, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/aws-lambda-nodejs/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-aws-lambda-python": {
      "title": "Server Integration Guide - AWS Lambda (Python)",
      "content"	 : "Moesif AWS Lambda Middleware for Python documentationby Moesif, the API analytics and API monetization platform.With Moesif Python middleware for AWS Lambda, you can automatically log API calls and send them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics and API monetization features into your Python applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.Who This Middleware is ForWe’ve designed Moesif Python middleware for AWS Lambda for APIs that you host on AWS Lambda using Amazon API Gateway or Application Load Balanceras a trigger. This middleware expects theLambda proxy integration type. If you’re using AWS Lambda with API Gateway, you are most likely using the proxy integration type.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall with pip using the following command:pip install moesif_aws_lambdaConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to Use1. Add the Middleware to your Lambda Applicationfrom moesif_aws_lambda.middleware import MoesifLoggerimport jsonmoesif_options = {    &#39;LOG_BODY&#39;: True}@MoesifLogger(moesif_options)def lambda_handler(event, context):    return {        &#39;statusCode&#39;: 200,        &#39;isBase64Encoded&#39;: False,        &#39;body&#39;: json.dumps({            &#39;msg&#39;: &#39;Hello from Lambda!&#39;        }),        &#39;headers&#39;: {            &#39;Content-Type&#39;: &#39;application/json&#39;        }    }  Important: Make sure you set the body field to a JSON-formatted string using json.dumps(). Otherwise,  API Gateway returns a 502 Bad Gateway error response.2. Set the MOESIF_APPLICATION_ID Environment VariableThe middleware expects the MOESIF_APPLICATION_ID environment variable to be able to connect with your Moesif account and send analytics. This variable holds the value of your Moesif Application ID. For instructions on how to set environment variables in Lambda, see Use Lambda environment variables to configure values in code.3. Deploy your Lambda FunctionTo deploy your Lambda function code with Moesif AWS Lambda middleware, you must archive them in a zip file. For archiving instructions, see our example Lambda function repository. Then follow the instructions in AWS Lambda docs to upload and deploy your Lambda function code as a zip file archive.4. Call your APIFinally, grab the URL to your API Gateway or Application Load Balancer and make some HTTP requests using a tool like Postman or cURL.  In order for your events to log to Moesif, you must test using the Amazon API Gateway trigger. Do not invoke your Lambda directly using AWS Console as the payload won’t contain a valid HTTP payload.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── eventV1.json├── eventV2.json├── images/├── lambda_function.py├── LICENSE├── moesif_aws_lambda/├── package.sh├── README.md├── requirements.txt├── setup.cfg└── setup.pyThese are the most important files:  moesif_aws_lambda/middleware.py: the middleware library  lambda_function.py: sample AWS Lambda function using the middlewareConfiguration OptionsThe following sections describe the available configuration options for this middleware. You can set these options in a Python object and then pass that object as argument to the MoesifLogger decorator. See the sample AWS Lambda middleware function code for an example.IDENTIFY_USER         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS Lambda event and context objects as argumentsand returns a user ID. This allows Moesif to attribute API requests to individual unique usersso you can understand who is calling your API. You can use this simultaneously with identify_companyto track both individual customers and the companies they are a part of.def identify_user(event, context):  # your code here, must return a string  return event[&quot;requestContext&quot;][&quot;identity&quot;][&quot;cognitoIdentityId&quot;]IDENTIFY_COMPANY         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS Lambda event and context objects as argumentsand returns a company ID. If you have a B2B business, this allows Moesif to attributeAPI requests to specific companies or organizations so you can understand which accounts arecalling your API. You can use this simultaneously with identify_user to track bothindividual customers and the companies they are a part of.def identify_company(event, context):  # your code here, must return a string  return &#39;7890&#39;}GET_SESSION_TOKEN         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as arguments and returns asession token such as an API key.def get_session_token(event, context):    # your code here, must return a string.    return &#39;XXXXXXXXX&#39;GET_API_VERSION         Data type          Parameters          Return type              Function          (event, context)          String     A function that takes AWS lambda event and context objects as arguments andreturns a string to tag requests with a specific version of your API.def get_api_version(event, context):  # your code here. must return a string.  return &#39;1.0.0&#39;GET_METADATA         Data type          Parameters          Return type              Function          (event, context)          Object     A function that takes AWS lambda event and context objects as arguments and returns an object.This function allows youto add custom metadata that Moesif can associate with the request. The metadata must be a simple Python object that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.def get_metadata(event, context):  # your code here:  return {        &#39;trace_id&#39;: context.aws_request_id,        &#39;function_name&#39;: context.function_name,        &#39;request_context&#39;: event[&#39;requestContext&#39;]    }SKIP         Data type          Parameters          Return type              Function          (event, context)          Boolean     A function that takes AWS lambda event and context objects as arguments and returns Trueif you want to skip the event. Skipping an event means Moesif doesn’t log the event.The following example skips requests to the root path /:def should_skip(event, context):    # your code here. must return a boolean.    return &quot;/&quot; in event[&#39;path&#39;]MASK_EVENT_MODEL         Data type          Parameters          Return type              Function          (MASK_EVENT_MODEL)          MASK_EVENT_MODEL     A function that takes the final Moesif event model, rather than the AWS lambda event or context objects, as anargument before the middleware sends the event model object to Moesif.With MASK_EVENT_MODEL, you can make modifications to headers or body such asremoving certain header or body fields.def mask_event(eventmodel):  # remove any field that you don&#39;t want to be sent to Moesif.  return eventmodelFor an example of how Moesif event model looks like, see the eventV1.json and eventV2.json files.For more information about the different fields of Moesif’s event model,see Moesif Python API documentation.DEBUG         Data type          Default              Boolean          undefined     Set to True to print debug logs if you’re having integration issues.LOG_BODY         Data type          Default              Boolean          True     Whether to log request and response body to Moesif.Optional: Capturing Outgoing API CallsIf you want to capture all outgoing API calls from your Python app to third parties likeStripe or to your own dependencies, call start_capture_outgoing() to start capturing. This mechanism works by patching Requests.from moesif_aws_lambda.middleware import *start_capture_outgoing(moesif_options) # moesif_options are the configuration options.Options for Logging Outgoing CallsThe following options are available for capturing and logging outgoing calls. The request and response objects passed in correspond to the Request and Response objects respectively of the Python Requests library.SKIP_OUTGOING         Data type          Parameters          Return type              Function          (request, response)          Boolean     Optional.This function takes Requests Request and Response objects and returns True if you want to skip this particular event.IDENTIFY_USER_OUTGOING         Data type          Parameters          Return type              Function          (request, response)          String     Optional, but highly recommended.This function takes Requests Request and Response objects and returns a string that represents the user ID used by your system. While Moesif tries to identify users automatically, different frameworks and your implementation might be very different. So we highly recommend that you accurately provide a user ID using this function.IDENTIFY_COMPANY_OUTGOING         Data type          Parameters          Return type              Function          (request, response)          String     Optional.This function takes Requests Request and Response objects and returns a string that represents the company ID for this event.GET_METADATA_OUTGOING         Data type          Parameters          Return type              Function          (request, response)          Dictionary     Optional.This function takes Requests Request and Response objects andreturns a Python dictionary. The dictionary must be such that it can be converted into valid JSON. This allows you to associate this event with custom metadata.For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.GET_SESSION_TOKEN_OUTGOING         Data type          Parameters          Return type              Function          (request, response)          String     Optional.This function takes Requests Request and Response objects and returns a string that represents the session token for this event. Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.LOG_BODY_OUTGOING         Data type          Default              Boolean          True     Optional.Whether to log request and response body to Moesif.ExamplesSee the example AWS Lambda function that uses this middleware.The following examples demonstrate how to add and update customer information.Update A Single UserTo create or update a user profile in Moesif, use the update_user() function.from moesif_aws_lambda.middleware import *moesif_options = {    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: True,}# Only user_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schema# metadata can be any custom objectuser = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_user(user, moesif_options)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif Python API Reference.Update Users in BatchTo update a list of users in one batch, use the update_users_batch() function.from moesif_aws_lambda.middleware import *moesif_options = {    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: True,}userA = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}userB = {  &#39;user_id&#39;: &#39;54321&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;mary@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;Mary&#39;,    &#39;last_name&#39;: &#39;Jane&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 48000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_users_batch([userA, userB], moesif_options)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif Python API Reference.Update A Single CompanyTo update a single company, use the update_company() function.from moesif_aws_lambda.middleware import *moesif_options = {    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: True,}# Only company_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schema# metadata can be any custom objectcompany = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}update_company(company, moesif_options)The metadata field can contain any company demographic or other information you want to store. Moesif only requires the company_id field. For more information, see the function documentation in Moesif Python API Reference.Update Companies in BatchTo update a list of companies in one batch, use the update_companies_batch() function.from moesif_aws_lambda.middleware import *moesif_options = {    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: True,}companyA = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}companyB = {  &#39;company_id&#39;: &#39;09876&#39;,  &#39;company_domain&#39;: &#39;contoso.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Contoso, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 48000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 53    },  }}update_companies_batch([companyA, companyB], moesif_options)The metadata field can contain any company demographic or other information you want to store. Moesif only requires the company_id field. For more information, see the function documentation in Moesif Python API Reference.Additional DocumentationSee Moesif AWS Lambda Example for Python for an example Lambda function using this middleware.How to Get HelpIf you face any issues using this middleware, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other integrationsExplore other integration options from Moesif in the Server Integration Options documentation.",
      "url": " /server-integration/aws-lambda-python/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-aws-lambda-ruby": {
      "title": "Server Integration Guide - AWS Lambda (Ruby)",
      "content"	 : "Moesif AWS Lambda Middleware for Rubyby Moesif, the API analytics and API monetization platform.With Moesif Ruby middleware for AWS Lambda, you can automatically log API calls and send them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics and API monetization features into your Ruby applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.This middleware expects theLambda proxy integration type.If you’re using AWS Lambda with API Gateway, you are most likely using the proxy integration type.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall with Bundler:bundle install moesif_aws_lambdaConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to use1. Wrap your Original Lambda handler with Moesif Middlewaredef your_original_handler(event:, context:)   # your codeendmoesif_options = {  # application_id is required  &quot;application_id&quot; =&amp;gt; &#39;Your Moesif Application Id&#39;,  &quot;debug&quot; =&amp;gt; true,  # see list of other options below.}# create moesif_middleware object.$moesif_middleware = Moesif::MoesifAwsMiddleware.new(method(:your_original_handler), moesif_options)2. Create a Wrapped Handler and Set it to the Function Handler Namedef wrapped_handler(event:, context:)  $moesif_middleware.handle(event: event, context: context);endThen set the AWS Lambda handler name to wrapped_handler instead. For more information, see Define Lambda function handler in Ruby.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailConfiguration OptionsThe following sections describe the available configuration options for this middleware. You must set these options in a Ruby Hash object when you create the middleware instance. See the sample Lambda handler function code in example_handler.rb for better understanding.application_id (Required)         Data type              String     A string that identifies your application in Moesif.api_version         Data type              String     Optional.Use it to tag requests with the version of your API.identify_user         Data type          Return type              Proc          String     Optional, but highly recommended.A Proc that takes the event, context, and Lambda result as arguments.Returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, set this option to ensure user identification properly.In the following code snippet, event and context are original Lambda handler’s input parameters. result is the return result from your own original Lambda handler.moesif_options[&#39;identify_user&#39;] = Proc.new { |event, context, result|  # Add your custom code that returns a string for user id  &#39;12345&#39;}identify_company         Data type          Return type              Proc          String     Optional.A Proc that takes the event, context, and Lambda result as arguments.Returns a string that represents the company ID for this event. This helps Moesif attribute requests to unique company.moesif_options[&#39;identify_company&#39;] = Proc.new { |event, context, result|  # Add your custom code that returns a string for company id  &#39;67890&#39;}identify_session         Data type          Return type              Proc          String     A Proc that takes env, headers, and body as arguments.Returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, use this option to help identify sessions.moesif_options[&#39;identify_session&#39;] = Proc.new { |event, context, result|    # Add your custom code that returns a string for session/API token    &#39;XXXXXXXXX&#39;}get_metadata         Data type          Return type              Proc          Hash     Optional.A Proc that takes env, headers, and body as arguments.Returns a Hash that represents a JSON object. This allows you to attach anymetadata to this event.moesif_options[&#39;get_metadata&#39;] = Proc.new { |event, context, result|  # Add your custom code that returns a dictionary  value = {      &#39;datacenter&#39;  =&amp;gt; &#39;westus&#39;,      &#39;deployment_version&#39;  =&amp;gt; &#39;v1.2.3&#39;  }  value}mask_data         Data type          Return type              Proc          EventModel     Optional.A Proc that takes an EventModel as an argument and returns an EventModel.This option allows you to modify headers or body of an event before sending the event to Moesif.moesif_options[&#39;mask_data&#39;] = Proc.new { |event_model|  # Add your custom code that returns a event_model after modifying any fields  event_model.response.body.password = nil  event_model}For more information and the spec of Moesif’s event model, see the source code of Moesif API library for Ruby or Moesif Ruby API documentationskip         Data type          Return type              Proc          Boolean     Optional.A Proc that takes env, headers, and body as arguments.Returns a boolean. Return true if you want to skip a particular event.moesif_options[&#39;skip&#39;] = Proc.new { |event, context, result|  # Add your custom code that returns true to skip logging the API call  if event.key?(&quot;rawPath&quot;)      # Skip probes to health page    event[&quot;rawPath&quot;].include? &quot;/health&quot;  else      false  end}debug         Data type          Default              Boolean          false     Optional.If true, the middleware prints out debug messages. In debug mode, the processing is not done in backend thread.log_body         Data type          Default              Boolean          true     Optional.If false, doesn’t log request and response body to Moesif.Additional Methods for Updating User and Company ProfilesIf you want to update User or Company profile using this SDK, use the following methods:$moesif_middleware.update_user(user_profile)$moesif_middleware.update_user_batch(user_profiles)$moesif_middleware.update_company(company_profile)$moesif_middleware.update_company_batch(company_profiles)For information about the structure of profiles, see Moesif Ruby API documentationExamplesSee example_handler.rb that contains an example Lambda handler using this middleware.Bundling Your Gem FilesFor AWS Lambda with Ruby, you have to bundle the gem dependencies into a ZIP file archive. For instructions, see Deploy Ruby Lambda functions with .zip file archives.In the file where you define your Lambda handler, you may have to specify the location of the dependencies:load_paths = Dir[  &quot;./vendor/bundle/ruby/2.7.0/gems/**/lib&quot;]$LOAD_PATH.unshift(*load_paths)How to Get HelpIf you face any issues using this middleware, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/aws-lambda-ruby/",
      "author": "Matthew",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-azure-api-management": {
      "title": "Server Integration Guide - Azure API Management",
      "content"	 : "Moesif API Analytics and MonetizationWith Moesif, grow and monetize your API products with a powerful API analytics and billing platform.This template will log API traffic from Azure API Management using Moesif API Analytics &amp;amp; Monetization in a few minutes without any code changes or restarts. The integration also provides visibility into rejected requests that never reach your underlying service.How it worksThis solution is deployed using an Azure Resource Manager Template. An XML Policy configures an APIM logger to send API logs to an Azure EventHub. An Azure WebJob reads from the EventHub and sends to Moesif for data processing.More info on this integration.How to install1. Start Azure Resource DeploymentClick the below button to start a Custom deployment with the Moesif Azure Resource Template.2. Configure ParametersWithin the Azure Template Deployment panel, set the following properties:      Set Resource group to the same resource group that contains your existing Azure APIM instance. This ensures the APIM logger, moesif-log-to-event-hub, is automatically created for you.        Set Moesif Application Id to the one displayed after logging into your Moesif account. You can create a free one on Moesif’s website        Set Existing Api Mgmt Name to the name of your Azure APIM instance. If blank, you will need to manually create the APIM logger.  Once done, click the Review+create button at the bottom and finish the template creation wizard.  Occasionally, Azure reports a failed deployment due to slow propagation of new DNS settings even though everything was deployed successfully. We recommend proceeding with rest of process. If you still have issues after last step, view troubleshooting.3. Add XML PolicyWithin the Azure portal, navigate to your existing Azure API Management instance.Select either a single API you want to add Moesif logging to, or select All APIs to add Moesif globally.  It’s recommended to add the XML policy globally for all APIs to reduce code replication. Then, use Moesif dynamic sampling to control what data is collected based on user behavior or regex rules.Under the Inbound Processing section, click the Add Policy button.Select Other Policies which will open the XML editor.Paste in the XML code you see below.More info on editing APIM policies is available on the Azure docs.This policy applies at the global scope for All APIs in your APIM instance:&amp;lt;policies&amp;gt;    &amp;lt;inbound&amp;gt;        &amp;lt;set-variable name=&quot;moesif-message-id&quot; value=&quot;@(Guid.NewGuid())&quot; /&amp;gt;        &amp;lt;log-to-eventhub logger-id=&quot;moesif-log-to-event-hub&quot; partition-id=&quot;0&quot;&amp;gt;@{var body = context.Request.Body?.As&amp;lt;string&amp;gt;(true);var MAX_BODY_EH = 145000;var origBodyLen = (null != body) ? body.Length : 0;if (MAX_BODY_EH &amp;lt; origBodyLen){ body = body.Remove(MAX_BODY_EH); }var headers = context.Request.Headers    .Where(h =&amp;gt; h.Key != &quot;Ocp-Apim-Subscription-Key&quot;)    .Select(h =&amp;gt; string.Format(&quot;{0}: {1}&quot;, h.Key, String.Join(&quot;, &quot;, h.Value).Replace(&quot;&quot;&quot;, &quot;&quot;&quot;))).ToArray&amp;lt;string&amp;gt;();var jwtToken = context.Request.Headers.GetValueOrDefault(&quot;Authorization&quot;,&quot;&quot;).AsJwt();var userId = (context.User != null &amp;amp;&amp;amp; context.User.Id != null) ? context.User.Id : (jwtToken != null &amp;amp;&amp;amp; jwtToken.Subject != null ? jwtToken.Subject : string.Empty);var companyId = (context.Subscription != null &amp;amp;&amp;amp; context.Subscription.Id != null) ? context.Subscription.Id : string.Empty;var cru = new JObject();if (context.User != null) {  cru.Add(&quot;Email&quot;, context.User.Email);  cru.Add(&quot;Id&quot;, context.User.Id);  cru.Add(&quot;FirstName&quot;, context.User.FirstName);  cru.Add(&quot;LastName&quot;, context.User.LastName);}var crus = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(cru.ToString()));var requestBody = (body != null ? System.Convert.ToBase64String(Encoding.UTF8.GetBytes(body)) : string.Empty);return new JObject(  new JProperty(&quot;event_type&quot;, &quot;request&quot;),  new JProperty(&quot;message-id&quot;, context.Variables[&quot;moesif-message-id&quot;]),  new JProperty(&quot;method&quot;, context.Request.Method),  new JProperty(&quot;ip_address&quot;, context.Request.IpAddress),  new JProperty(&quot;uri&quot;, context.Request.OriginalUrl.ToString()),  new JProperty(&quot;user_id&quot;, userId),  new JProperty(&quot;contextRequestUser&quot;, crus),  new JProperty(&quot;company_id&quot;, companyId),  new JProperty(&quot;request_headers&quot;, string.Join(&quot;;;&quot;, headers)),  new JProperty(&quot;request_body&quot;, requestBody),  new JProperty(&quot;contextTimestamp&quot;, context.Timestamp.ToString(&quot;o&quot;)),  new JProperty(&quot;metadata&quot;, $@&quot;&quot;)  ).ToString();}&amp;lt;/log-to-eventhub&amp;gt;        &amp;lt;set-variable name=&quot;sent-moesif-request&quot; value=&quot;@(true)&quot; /&amp;gt;    &amp;lt;/inbound&amp;gt;    &amp;lt;backend&amp;gt;        &amp;lt;forward-request follow-redirects=&quot;true&quot; /&amp;gt;    &amp;lt;/backend&amp;gt;    &amp;lt;outbound&amp;gt;        &amp;lt;choose&amp;gt;            &amp;lt;when condition=&quot;@(context.Variables.ContainsKey(&quot;sent-moesif-request&quot;) &amp;amp;&amp;amp; !context.Variables.ContainsKey(&quot;sent-moesif-response&quot;))&quot;&amp;gt;                &amp;lt;log-to-eventhub logger-id=&quot;moesif-log-to-event-hub&quot; partition-id=&quot;0&quot;&amp;gt;@{var body = context.Response.Body?.As&amp;lt;string&amp;gt;(true);var MAX_BODY_EH = 145000;var origBodyLen = (null != body) ? body.Length : 0;if (MAX_BODY_EH &amp;lt; origBodyLen){ body = body.Remove(MAX_BODY_EH);}var headers = context.Response.Headers.Select(h =&amp;gt; string.Format(&quot;{0}: {1}&quot;, h.Key, String.Join(&quot;, &quot;, h.Value).Replace(&quot;&quot;&quot;, &quot;&quot;&quot;))).ToArray&amp;lt;string&amp;gt;();var responseBody = (body != null ? System.Convert.ToBase64String(Encoding.UTF8.GetBytes(body)) : string.Empty);return new JObject(  new JProperty(&quot;event_type&quot;, &quot;response&quot;),  new JProperty(&quot;orig_body_len&quot;, origBodyLen),  new JProperty(&quot;message-id&quot;, context.Variables[&quot;moesif-message-id&quot;]),  new JProperty(&quot;status_code&quot;, context.Response.StatusCode),  new JProperty(&quot;response_headers&quot;, string.Join(&quot;;;&quot;, headers)),  new JProperty(&quot;contextTimestamp&quot;, context.Timestamp.Add(context.Elapsed).ToString(&quot;o&quot;)),  new JProperty(&quot;response_body&quot;, responseBody)  ).ToString();}&amp;lt;/log-to-eventhub&amp;gt;                &amp;lt;set-variable name=&quot;sent-moesif-response&quot; value=&quot;@(true)&quot; /&amp;gt;            &amp;lt;/when&amp;gt;        &amp;lt;/choose&amp;gt;    &amp;lt;/outbound&amp;gt;    &amp;lt;on-error&amp;gt;        &amp;lt;choose&amp;gt;            &amp;lt;when condition=&quot;@(context.Variables.ContainsKey(&quot;sent-moesif-request&quot;) &amp;amp;&amp;amp; !context.Variables.ContainsKey(&quot;sent-moesif-response&quot;))&quot;&amp;gt;                &amp;lt;log-to-eventhub logger-id=&quot;moesif-log-to-event-hub&quot; partition-id=&quot;0&quot;&amp;gt;@{var body = context.Response.Body?.As&amp;lt;string&amp;gt;(true);var MAX_BODY_EH = 145000;var origBodyLen = (null != body) ? body.Length : 0;if (MAX_BODY_EH &amp;lt; origBodyLen){ body = body.Remove(MAX_BODY_EH);}var headers = context.Response.Headers.Select(h =&amp;gt; string.Format(&quot;{0}: {1}&quot;, h.Key, String.Join(&quot;, &quot;, h.Value).Replace(&quot;&quot;&quot;, &quot;&quot;&quot;))).ToArray&amp;lt;string&amp;gt;();var responseBody = (body != null ? System.Convert.ToBase64String(Encoding.UTF8.GetBytes(body)) : string.Empty);return new JObject(  new JProperty(&quot;event_type&quot;, &quot;response&quot;),  new JProperty(&quot;orig_body_len&quot;, origBodyLen),  new JProperty(&quot;message-id&quot;, context.Variables[&quot;moesif-message-id&quot;]),  new JProperty(&quot;status_code&quot;, context.Response.StatusCode),  new JProperty(&quot;response_headers&quot;, string.Join(&quot;;;&quot;, headers)),  new JProperty(&quot;contextTimestamp&quot;, context.Timestamp.Add(context.Elapsed).ToString(&quot;o&quot;)),  new JProperty(&quot;response_body&quot;, responseBody)  ).ToString();}&amp;lt;/log-to-eventhub&amp;gt;                &amp;lt;set-variable name=&quot;sent-moesif-response&quot; value=&quot;@(true)&quot; /&amp;gt;            &amp;lt;/when&amp;gt;        &amp;lt;/choose&amp;gt;    &amp;lt;/on-error&amp;gt;&amp;lt;/policies&amp;gt;That’s it. Once the XML is added to your APIs, the logs should start showing up in Moesif.To set policy at the API scope, use the base element within a section to inherit policies from the global scope for that section. In the following API scope policy, the inbound section inherits policies configured in the global inherit section:&amp;lt;policies&amp;gt;    &amp;lt;inbound&amp;gt;        &amp;lt;base /&amp;gt;        &amp;lt;set-variable name=&quot;moesif-message-id&quot; value=&quot;@(Guid.NewGuid())&quot; /&amp;gt;        [...]    [...]&amp;lt;/policies&amp;gt;Configuration OptionsThe below fields in the XML policy can be modified by you to meet your requirements. XML Policies support a number of context variables which you can also leverage.User IdString, The field user_id identifies who the user is making the API and enables Moesif to associate API calls to user profiles. The default XML policy extracts the user id from the context.User.Id or the Subject of the JWT Token. If you are a B2B company, this can be used simultaneously with company id to track API Usage both at the individual user-level and also account-level. See identifying customers in Moesif for more info.User MetadataString, The field contextRequestUser allows you to store additional user metadata as part of the user’s profile in Moesif. By default, the XML policy also saves Email, FirstName, and LastName from Azure’s context.User object. Any fields can be stored. Keep in mind contextRequestUser is expecting a base64 encoded string.Company IdString, The field company_id identifies which company is making the API and enables Moesif to associate API calls to company profiles. The default XML policy does not set this field. See identifying customers in Moesif for more info.Event MetadataString, A JSON string that allows you to add custom metadata that will be associated with the API call. For example, you may want to store the context.Api.Name or context.Api.Version with the API calls by reading from the context variables. The metadata field must be a JSON encoded string.Manual deploymentThe individual components can be deployed directly if needed.WebJobThe WebJob is deployed as part of the overall deployment.To re-deploy the WebJob:  Download the run.bat script to your computer.  Within the Azure Portal, go to your WebApp and select the WebJobs panel. – If there is an existing WebJob, stop it and remove it.  Click the +Add button to create a new job. Give it a name, set type to continuous and upload the run.bat you previously downloaded.Once created, the script will clone the ApimEventProcessor repo ‘v1’ branch, run dotnet build, and starts the worker.APIM LoggerIf the name of an existing Azure API Management is not specified during deployment, you will need to add the log-to-eventhub logger to your Azure API Management service manually. To do so, utilize the nested/microsoft.apimanagement/service/loggers.bicep ARM template or view Microsoft docsMore info on configuring Moesif is available on Microsoft’s documentation.Updating the integrationTo run the latest version of webjob, simply stop, and then restart the WebJob (Within the Azure Portal, go to your WebApp and select the WebJobs panel).Steps performed by the Azure Resource TemplateThis template performs the following tasks  Create Azure Eventhub and policies for Send and Listen.  If the name of an existing Azure API Management instance is provided, the template creates a new log-to-eventhub with the name moesif-log-to-event-hub.  Create an Azure Storage Account to periodically checkpoint the EventHub read location.  Create an Azure WebApp and configures the environment variables required by ApimEventProcessor.  Deploys ApimEventProcessor as a Webjob on the WebApp.Troubleshooting  It is possible that the final step of deployment app-service-webjob-msdeploy reports a failed deployment with error such as conflict or BadRequest or GatewayTimeout. Despite these initial errors reported by deployment, it is possible that the WebJob deployment within Azure App Service may succeed automatically after 5-10 minutes without further custom action. At the end of this template deployment, you may view detailed logs in your App Service/Activity log.  Ensure the log-to-eventhub logger is created  Ensure the policy is set on Api Management Apis  Ensure App Service configuration contains correct environment variables. View your App Service/Settings/Configuration/Application settings  Review the logs of App Service Webjob named azure-api-mgmt-logs-2-moesif and ensure it is running. View your App Service/Settings/WebJobs",
      "url": " /server-integration/azure-api-management/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-azure-webapp": {
      "title": "Server Integration Guide - Azure Web Apps",
      "content"	 : "Moesif Azure Web App ExtensionIntroductionThe Moesif Azure Web App Extensionlogs and monitors API calls hitting your Web App. It can be installed using the Azure Portal UI without code changes and can be used in lieu of the Moesif server integrations.How to Install1. Install Moesif ExtensionInstallation is done entirely within the Azure Portal UI.Within Azure portal, go to your web app, and then select the  Extensions sub panel.Select + Add and scroll down to Moesif API Insights.After selecting Moesif API Insights, you will need to agree to the terms and then select OK.2. Add the MOESIF_APPLICATION_ID settingWithin the Azure portal, go to the Configuration sub panel.Under Application settings, add a new Application setting with the key name MOESIF_APPLICATION_ID and the value to your actual Moesif Application Id which can be found within the Moesif Dashboard -&amp;gt; Bottom Left Menu -&amp;gt; Installation -&amp;gt; Azure WebApp3. Restart the Azure Web AppYou will need to restart the Azure web app, as Azure does not transform applicationHost until after the web app is restarted.If you’re not seeing any data or get an error regarding an incorrect web.config, stop and restart the web app.Configuration optionsThe extension supports the following Application settings            Setting Name      Required      Description      Example                  MOESIF_APPLICATION_ID      true      Your Application Id from your Moesif’s Account to authorize this app with Moesif      XXXXXXXX              MOESIF_DISABLED      false      Disables Moesif Logging      true              MOESIF_SESSION_TOKEN_HEADER      false      The Request Header that contains the session token/API key      Authorization              MOESIF_USER_ID_HEADER      false      The Request or Response Header that contains the user id      X-User-Id              MOESIF_COMPANY_ID_HEADER      false      The Request or Response Header that contains the company id      X-Account-Id              MOESIF_DEBUG      false      Prints debug messages to standard output. (Useful for debugging integration issues)      true      You can also add these settings in your web.config or as an environment variable.Checkout: https://[MY_SITE].scm.azurewebsites.net/MoesifDebuggerfor more info on extension configuration where [MY_SITE] is your Azure App service name found in the Azure Portal.TroubleshootingMy app is returning 500 errors or have errors on missing DLLsFirst, make sure you restarted your web app. It’s possible your Azure permissions or web app configuration is preventing extensions from having write access to D:homesitewwwroot. You can verify this by checking if Moesif.Azure.Web.Logging.dll is missing in the D:homesitewwwrootbin directory.To remedy:  Using the SCM file explorer, copy the DLL from D:homeSiteExtensionsMoesif.Azure.AppsbinMoesif.Azure.Web.Logging.dll to D:homesitewwwrootbinMoesif.Azure.Web.Logging.dll.  Restart your Azure web app.The SCM file explorer is accessible at https://[MY_SITE].scm.azurewebsites.net where [MY_SITE] is your Azure App service name.Nothing is getting logged to MoesifSometimes certain files are locked or in-use by the IIS process while installing the extension preventing a successful installation.To remedy, you can disable all Azure extensions to release the process locks, then re-enable all extensions. This can be done as follows:  With Azure app settings, add a setting WEBSITE_PRIVATE_EXTENSIONS with the value 0 which disables all extensions and click Save.  Re-enable your extensions by setting WEBSITE_PRIVATE_EXTENSIONS back its default of 1 (or delete the setting all together) and click Save.  Restart the web app.Request body is missing from eventsEnsure you have updated your extension to 1.2.0 or later which added support for request body logging.Still having issuesYou can view detailed logs by setting the application setting MOESIF_DEBUG to true. You’ll also need to ensureApplication Logging is enabled under the App Service Logs sub panel.Once done, you will see debug logs printed to the Azure Log Stream..You can download and send your logs to Moesif support if you need help.",
      "url": " /server-integration/azure-webapp/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-ballerina": {
      "title": "Server Integration Guide - Ballerina Programming Language",
      "content"	 : "Moesif Ballerina IntegrationThis document describes how to set up, configure, and use the Moesif observability extension of the Ballerina programming language. The extension provides an implementation for publishing traces, metrics, and logs to a Moesif application.Moesif currently supports OpenTelemetry logs and traces. Metrics are not supported.Get Your Moesif Application ID  Log into Moesif Portal.  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Enable Moesif Extension to Publish TracesTo package the Moesif extension into the JAR file, follow these steps.  Import the package in your program:     import ballerinax/moesif as _;            Add the following configurations in Ballerina.toml when building your program:     [package] org = &quot;my_org&quot; name = &quot;my_package&quot; version = &quot;1.0.0&quot; [build-options] observabilityIncluded=true            To enable the extension and publish traces to Moesif, add the following configurations in Config.toml when running your program, replacing &amp;lt;moesif-application-id&amp;gt; with your Moesif Application ID:     [ballerina.observe] tracingEnabled=true tracingProvider=&quot;moesif&quot; [ballerinax.moesif] applicationId = &quot;&amp;lt;moesif-application-id&amp;gt;&quot;     # Mandatory configuration. reporterBaseUrl = &quot;xxxxx&quot;   # Optional Configuration. Default value is https://api.moesif.net tracingReporterFlushInterval = xxx; # Optional Configuration. Default value is 1000 tracingReporterBufferSize = xxx; # Optional Configuration. Default value is 10000 isTraceLoggingEnabled = xxx; # Optional Configuration. Default value is false isPayloadLoggingEnabled = xxx; # Optional Configuration. Default value is false      Publish Logs to MoesifTo publish logs, the extension leverages Fluent Bit to forward logs to an OTEL Collector, which then sends the logs to Moesif’s OpenTelemetry logs receiver endpoint:Ballerina → Fluent Bit → OTEL Collector → MoesifComponents  docker-compose.yml  Defines the containerized setup for Fluent Bit and OTEL Collector.  fluent-bit.conf  Configures Fluent Bit to read logs from the Ballerina log file and forward them.  otelcol.yaml  Configures the OTEL Collector to process and send logs to Moesif’s logs receiver endpoint.In the following configurations for these components, replace &amp;lt;moesif-application-id&amp;gt; with your Moesif Application ID.docker-compose.ymlservices:  otelcol:    image: otel/opentelemetry-collector-contrib:0.132.0    container_name: otelcol    command: [&quot;--config&quot;, &quot;/etc/otelcol.yaml&quot;]    environment:      MOESIF_APP_ID: &quot;&amp;lt;moesif-application-id&amp;gt;&quot;    ports:      - &quot;4317:4317&quot;      - &quot;4318:4318&quot;    volumes:      - ./otelcol.yaml:/etc/otelcol.yaml:ro    networks:      - otelnet  fluent-bit:    image: fluent/fluent-bit:3.0    container_name: fluent-bit    depends_on:      - otelcol    ports:      - &quot;2020:2020&quot;    volumes:      - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro      # Mount the local log directory into the container      - &amp;lt;ballerina-log-path&amp;gt;:/app/logs:ro    networks:      - otelnetnetworks:  otelnet:    driver: bridgefluent-bit.conf[SERVICE]    Flush         1    Log_Level     debug    Daemon        off    HTTP_Server   On    HTTP_Listen   0.0.0.0    HTTP_Port     2020# Read logs from local Ballerina app[INPUT]    Name              tail    Path              /app/logs/app.log    Tag               ballerina.*    Read_from_Head    true    Skip_Long_Lines   On    Skip_Empty_Lines  On    Refresh_Interval  1# Add metadata[FILTER]    Name         modify    Match        ballerina.*    Add          service.name ballerina-service    Add          deployment.environment prod# Convert to OTEL format and send to collector[OUTPUT]    Name          opentelemetry    Match         ballerina.*    Host          otelcol    Port          4318    Logs_uri      /v1/logs    Log_response_payload True    Tls           Off    Tls.verify    Off# Debug output to see what&#39;s being processed[OUTPUT]    Name          stdout    Match         ballerina.*    Format        json_linesotelcol.ymlreceivers:  otlp:    protocols:      grpc:        endpoint: &quot;0.0.0.0:4317&quot;      http:        endpoint: &quot;0.0.0.0:4318&quot;processors:  resource:    attributes:      - key: service.name        value: ballerina-service        action: upsert      - key: deployment.environment        value: prod        action: upsert  transform/severity_from_message:    log_statements:      - context: log        statements:          # Set default severity to INFO for all logs first          - set(severity_number, 9) where body != nil          - set(severity_text, &quot;INFO&quot;) where body != nil          # Try to parse JSON body, but handle parsing errors gracefully          - set(cache[&quot;is_json&quot;], false)          - set(cache[&quot;is_json&quot;], true) where body != nil and IsMatch(body, &quot;^s*{&quot;)                    # For JSON logs, parse and extract level          - set(cache[&quot;parsed_body&quot;], ParseJSON(body)) where cache[&quot;is_json&quot;] == true                    # Override with specific levels based on JSON level field          - set(severity_number, 1) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;TRACE&quot;          - set(severity_text, &quot;TRACE&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;TRACE&quot;          - set(severity_number, 5) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;DEBUG&quot;          - set(severity_text, &quot;DEBUG&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;DEBUG&quot;          - set(severity_number, 9) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;INFO&quot;          - set(severity_text, &quot;INFO&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;INFO&quot;          - set(severity_number, 13) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;WARN&quot;          - set(severity_text, &quot;WARN&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;WARN&quot;          - set(severity_number, 17) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;ERROR&quot;          - set(severity_text, &quot;ERROR&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;ERROR&quot;          - set(severity_number, 21) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;FATAL&quot;          - set(severity_text, &quot;FATAL&quot;) where cache[&quot;is_json&quot;] == true and cache[&quot;parsed_body&quot;][&quot;level&quot;] == &quot;FATAL&quot;  batch: {}exporters:  # OTLP over HTTP to Moesif  otlphttp:    endpoint: &quot;https://api.moesif.net&quot;    logs_endpoint: &quot;https://api.moesif.net/v1/logs&quot;    headers:      X-Moesif-Application-Id: &quot;&amp;lt;moesif-application-id&amp;gt;&quot;    compression: none    timeout: 10s    sending_queue:      enabled: true      num_consumers: 2      queue_size: 512    retry_on_failure:      enabled: true      initial_interval: 1s      max_interval: 10s      max_elapsed_time: 0sservice:  telemetry:    logs:      level: debug  pipelines:    logs:      receivers:  [otlp]      processors: [resource, transform/severity_from_message, batch]      exporters:  [otlphttp]Setup and Execution      Publish the logs from your Ballerina application to a file in the specified log path:.     bal run 2&amp;gt; &amp;lt;ballerina-log-path&amp;gt;/app.log        Copy the component configurations from the previous section to a directory in your local file system.     . ├── docker-compose.yml ├── fluent-bit.conf └── otelcol.yaml            Run the stack using the following command.     docker compose up      This setup establishes a clear pipeline for the logs:  The Ballerina application writes logs to a specified file  Fluent Bit continuously monitors this file and forwards the logs to the OTEL Collector.  The OTEL Collector processes the logs and dispatches them to Moesif.Visualize Observability DataTraces and logs are published to Moesif as events. You can observe them in real time in the Live Event Log.For example, here we observe trace and span IDs for an API event:Trace and log data is also available in a separate Trace view for Live Event Log workspaces.In the expanded menu for an event, you can go to  Span Events to view Span Event data for the span.You can also use different OpenTelemetry data elements as filters like trace ID and spans.Configuration Optionsmoesif:reporterBaseUrl         Type          Default              String          &quot;https://api.moesif.net&quot;     moesif:applicationId (Required)         Type          Default              String           None     moesif:samplerType         Type          Default              String           &quot;const&quot;     moesif:samplerParam         Type          Default              Decimal           1     moesif:tracingReporterFlushInterval         Type          Default              Integer           1000     moesif:tracingReporterBufferSize         Type          Default              Integer           10000     moesif:metricsReporterFlushInterval         Type          Default              Integer           15000     moesif:metricsReporterClientTimeout         Type          Default              Integer           10000     moesif:additionalAttributes         Type          Default              map&amp;lt;string&amp;gt;           {}     moesif:isTraceLoggingEnabled         Type          Default               Boolean           false     moesif:isPayloadLoggingEnabled         Type          Default               Boolean           false     ",
      "url": " /server-integration/ballerina/",
      "author": "Sakib",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-cloudflare-workers": {
      "title": "Server Integration Guide - Cloudflare Workers",
      "content"	 : "Moesif Cloudflare SDK Documentationby Moesif, the API analytics and API monetization platform.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.OverviewThis SDK allows you to integrate Moesif with Cloudflare Workers using the new ECMAScript modules (ES modules).This NPM package only supports Node.js version 18 and 20.Important Note about Legacy Service Worker ModelIf you are using Cloudflare’s Service Workers API instead of the new ES modules,please follow the legacy instructions.PrerequisitesBefore using this SDK, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the SDKIn the directory of your Worker project created with Wranger, install the SDK:npm install moesif-cloudflareConfigure the SDKSee the available configuration options to learn how to configure the SDK for your use case.How to UseUsing the SDK involves three simple steps:  Import the moesifMiddleware function.  Specify your Moesif Application ID in the Moesif options object.  Wrap your handler with moesifMiddleware.For example:import moesifMiddleware from &#39;moesif-cloudflare&#39;;const options = {  applicationId: &#39;YOUR MOESIF Application ID&#39;,};// your original fetch handler.async function originalFetchHandler(request, _env, context) {  // your code.}// this create a new fetch that is wrapped by moesifMiddlewareconst wrappedFetchHandler = moesifMiddleware(originalFetch, options);// export the fetch handler.export default {  fetch: wrappedFetchHandler};TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── esm/├── example-project/├── images/├── legacy/├── LICENSE└── README.mdConfiguration OptionsThe following sections describe the available configuration options for this SDK. You can set these options in the Moesif initialization options object. See the example Worker project code for an example.You can see the full list of options in the prepareOptions.mjs file.identifyUser         Data type          Parameters          Return type              Function          (req, res, env, ctx)          String     Parameters:  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.The function returns a user ID string. This allows Moesif to attribute API requests to individual unique usersso you can understand who is calling your API. You can use this simultaneously with identifyCompanyto track both individual customers and the companies they are a part of.See the example project’s identifyUser function for an example.identifyCompany         Data type          Parameters          Return type              Function          (req, res, env, ctx)          String     Parameters:  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.This function returns a company ID string. If you have a B2B business, this allows Moesif to attributeAPI requests to specific companies or organizations so you can understand which accounts arecalling your API. You can use this simultaneously with identifyUser to track bothindividual customers and the companies they are a part of.See the example project’s identifyCompany function for an example.getSessionToken         Data type          Parameters          Return type              Function          (req, res, env, ctx)          String     Parameters  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.This function returns a session token such as an API key.For example:var options = {  getSessionToken: function (req, res, env, ctx) {    // your code here must return a string. Example Below    return req.headers.get[&#39;Authorization&#39;];  }}getApiVersion         Data type          Parameters          Return type              Function          (req, res, env, ctx)          String     Parameters  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.This functionreturns a string to tag requests with a specific version of your API.For example:var options = {  getApiVersion: function (req, res, env, ctx) {    // your code here must return a string. Example Below    return req.headers.get[&#39;X-Api-Version&#39;]  }}maskContent         Data type          Parameters          Return type              Function          (MoesifEventModel)          MoesifEventModel     A function that takes the final Moesif event model as anargument before sending the event model object to Moesif.With maskContent, you can make modifications to headers or body such asremoving certain header or body fields.import _ from &#39;lodash&#39;;var options = {  maskContent: function(event) {    // remove any field that you don&#39;t want to be sent to Moesif.    const newEvent = _.omit(event, [&#39;request.headers.Authorization&#39;, &#39;event.response.body.sensitive_field&#39;])    return newEvent;  }};Moesif’s event model format looks like this:{  &quot;request&quot;: {    &quot;time&quot;: &quot;2022-08-08T04:45:42.914&quot;,    &quot;uri&quot;: &quot;https://api.acmeinc.com/items/83738/reviews/&quot;,    &quot;verb&quot;: &quot;POST&quot;,    &quot;api_version&quot;: &quot;1.1.0&quot;,    &quot;ip_address&quot;: &quot;61.48.220.123&quot;,    &quot;headers&quot;: {      &quot;Host&quot;: &quot;api.acmeinc.com&quot;,      &quot;Accept&quot;: &quot;*/*&quot;,      &quot;Connection&quot;: &quot;Keep-Alive&quot;,      &quot;Content-Type&quot;: &quot;application/json&quot;,      &quot;Content-Length&quot;: &quot;126&quot;,      &quot;Accept-Encoding&quot;: &quot;gzip&quot;    },    &quot;body&quot;: {      &quot;items&quot;: [        {          &quot;direction_type&quot;: 1,          &quot;item_id&quot;: &quot;fwdsfrf&quot;,          &quot;liked&quot;: false        },        {          &quot;direction_type&quot;: 2,          &quot;item_id&quot;: &quot;d43d3f&quot;,          &quot;liked&quot;: true        }      ]    }  },  &quot;response&quot;: {    &quot;time&quot;: &quot;2022-08-08T04:45:42.924&quot;,    &quot;status&quot;: 500,    &quot;headers&quot;: {      &quot;Vary&quot;: &quot;Accept-Encoding&quot;,      &quot;Pragma&quot;: &quot;no-cache&quot;,      &quot;Expires&quot;: &quot;-1&quot;,      &quot;Content-Type&quot;: &quot;application/json; charset=utf-8&quot;,      &quot;Cache-Control&quot;: &quot;no-cache&quot;    },    &quot;body&quot;: {      &quot;Error&quot;: &quot;InvalidArgumentException&quot;,      &quot;Message&quot;: &quot;Missing field location&quot;    }  },  &quot;user_id&quot;: &quot;my_user_id&quot;,  &quot;company_id&quot;: &quot;my_company_id&quot;,  &quot;session_token&quot;:&quot;end_user_session_token&quot;,  &quot;tags&quot;: &quot;tag1, tag2&quot;}For more information about the different fields of Moesif’s event model,see the following table or the Moesif Node.js API documentation.            Name      Required      Description                  request      Yes      The object that specifies the API request.              request.time      Yes      Timestamp for the request in ISO 8601 format.              request.uri      Yes      Full URI such as https://api.com/?query=string including host, query string, and so on.              request.verb      Yes      The HTTP method—for example, GET and POST.              request.api_version      No      API Version you want to tag this request with such as 1.0.0.              request.ip_address      No      IP address of the client. If not set, Moesif uses the IP address of your logging API calls.              request.headers      Yes      Headers of the  request as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              request.body      No      Body of the request in JSON format or base64 encoded binary data. To specify the transfer encoding, use request.transfer_encoding.              request.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the request body assumed to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           response      No      The object that specifies the response message. If not set, it implies a null response such as a timeout.              response.time      Yes      Timestamp for the response in ISO 8601 format.              response.status      Yes      HTTP response status code number such as 200 OK or 500 Internal Server Error.              response.ip_address      No      IP address of the responding server.              response.headers      Yes      Headers of the response as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              response.body      No      Body of the response in JSON format or base64 encoded binary data. To specify the transfer encoding, use response.transfer_encoding              response.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the body to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           session_token      Recommended      The end user session token such as a JWT or API key, which may or may not be temporary. Moesif automatically detects the session token if not set.              user_id      Recommended      Identifies this API call to a permanent user ID.              metadata      No      A JSON Object consisting of any custom metadata to be stored with this event.      getMetadata         Data type          Parameters          Return type              Function          (req, res, env, ctx)          Object     Parameters  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.This function returns an object containing custom metadata that Moesif can associate with the request. The metadata must be a simple JavaScript object that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.var options = {  getMetadata: function (req, res, env, ctx) {    // your code here:    return {      foo: &#39;custom data&#39;,      bar: &#39;another custom data&#39;    };  }}skip         Data type          Parameters          Return type              Function          (req, res, env, ctx)          Boolean     Parameters  req: a Request object.  res: a Response object.  env: an env object representing the bindings available to the Worker.  ctx: a Context API object.This function returns trueif you want to skip the event. Skipping an event means Moesif doesn’t log the event.The following example skips requests to the root path / and the /health path:var options = {  skip: function (req, res, env, ctx) {    const url = new URL(req.url)    // your code here must return a boolean. Example Below    if (url.pathname === &#39;/&#39; || url.pathname === &#39;/health&#39;) {      // Skip logging traffic to root path or health probe.      return true;    }    return false  }}logBody         Data type          Default              Boolean          true     Whether to log request and response body to Moesif.hideCreditCards         Data type          Default              Boolean          true     This masks any credit cards using the Luhn algorithm.disableTransactionId         Data type          Default              Boolean          false     X-Moesif-Transaction-Id helps identify transactions in Moesif. Set this option to true to prevent insertion of X-Moesif-Transaction-Id response header.debug         Data type          Default              Boolean          false     Set to true to print debug logs. This may help you troubleshoot if you’re having integration issues.fetchTimeoutMS         Data type          Default              Number          120000 milliseconds     The fetch timeout in milliseconds so that Moesif can log the call even if origin server doesnt respond.requestMaxBodySize         Data type          Default              Number          100000     The maximum request body size in bytes to log when sending the data to Moesif.responseMaxBodySize         Data type          Default              Number          100000     The maximum response body size in bytes to log when sending the data to Moesif.ExampleSee the example-project folder for an example. The example is generated using C3 (create-cloudflare-cli) and follows the Cloudflare get started guide.How to Get HelpIf you face any issues using this SDK, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/cloudflare-workers/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-dotnet": {
      "title": "Server Integration Guide - C# (.NET)",
      "content"	 : "Moesif Middleware for .NETby Moesif, the API analytics and API monetization platform.Moesif .NET middleware SDK automatically logs incoming and outgoing API calls and sends them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics andAPI monetization features into your .NET applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall the Nuget Package for the middleware:Install-Package Moesif.MiddlewareVersions &amp;amp; Target Frameworks            Version      Target Framework                  3.1.0 or above      .NET46 / .NET6 or above              1.5.3 or below      .NET45 / .NET Core 2 or below      Note: We have deprecated support for .NET Core 2 or belowThen jump to usage instructions for your specific framework:  .NET6 installation  .NET Core and .NET 5 installation  .NET Framework installationConfigure the MiddlewareSee the following to learn how to configure the middleware for your use case.  .NET Core configuration options  .NET Framework configuration optionsUse the Middleware in .NET6.0 and higherPlease use Moesif.Middleware version 3.0.9 or higher for .NET6 or higher framework. Rest of instrusctions are same.Use the Middleware in .NET Core and .NET 5.0Follow these instructions to use this middleware in .NET 5 or .NET Core 2.1 and higher:  In Startup.cs file in your project directory, add app.UseMiddleware&amp;lt;MoesifMiddleware&amp;gt;(moesifOptions); to the pipeline.To collect the most context, we recommend that you add the middleware after other middleware such as SessionMiddleware and AuthenticationMiddleware.  Add the middleware in your application:using Moesif.Middleware;public class Startup {    // moesifOptions is an object of type Dictionary&amp;lt;string, object&amp;gt; which holds configuration options for your application.    Dictionary&amp;lt;string, object&amp;gt; moesifOptions = new Dictionary&amp;lt;string, object&amp;gt;    {        {&quot;ApplicationId&quot;, &quot;YOUR_MOESIF_APPLICATION_ID&quot;},        {&quot;LogBody&quot;, true},        ...        # For other options see below.    };    public void ConfigureServices(IServiceCollection services)    {        services.AddMvc();    }    public void Configure(IApplicationBuilder app, IHostingEnvironment env)    {        app.UseMiddleware&amp;lt;MoesifMiddleware&amp;gt;(moesifOptions);        app.UseMvc();    }}Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Use the Middleware in .NET FrameworkFollow these instructiosn to use the middleware in .NET Framework 4.5 and higher.  In Startup.cs file in your project directory, please add app.Use&amp;lt;MoesifMiddleware&amp;gt;(moesifOptions); to the pipeline.To collect the most context, it is recommended to add the middleware after other middleware such as SessionMiddleware and AuthenticationMiddleware.  Add the middleware to your application:using Moesif.Middleware;public class Startup {    // moesifOptions is an object of type Dictionary&amp;lt;string, object&amp;gt; which holds configuration options for your application.    Dictionary&amp;lt;string, object&amp;gt; moesifOptions = new Dictionary&amp;lt;string, object&amp;gt;    {        {&quot;ApplicationId&quot;, &quot;YOUR_MOESIF_APPLICATION_ID&quot;},        {&quot;LogBody&quot;, true},        ...        # For other options see below.    };    public void Configuration(IAppBuilder app)    {        app.Use&amp;lt;MoesifMiddleware&amp;gt;(moesifOptions);    }}Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.  If your app uses Windows Communication Foundation (WCF), set DisableStreamOverride to trueAdd OWIN DependenciesIIS integrated pipelineIf your .NET application runs on IIS or Visual Studio IIS Express using integrated mode, install the OWIN SystemWeb package if not done so already.Install-Package Microsoft.Owin.Host.SystemWebFor more information, see OWIN Middleware in the IIS integrated pipeline.Moesif does not support IIS running in classic mode (backwards compatibility for IIS 6.0). Unless your app predates IIS 6.0 and requires classic mode, we recomend you switch to integrated mode.Self-Host executableWhile uncommon, if your application is a self-hosted executable that does not run on IIS, you may have to install the SelfHost package if not done so already:      For .NET Web API applications:     Install-Package Microsoft.AspNet.WebApi.OwinSelfHost            For all other .NET applications:     Install-Package Microsoft.Owin.SelfHost -Pre      Configuration OptionsThe following sections describe the middleware’s configuration options for .NET Core and .NET Framework..NET Core Configuration OptionsThe next sections describe the available configuration options for .NET Core. Here’s a sample configuration using:public static Func&amp;lt;HttpRequest, HttpResponse, string&amp;gt; IdentifyUser = (HttpRequest req, HttpResponse res) =&amp;gt; {    // Implement your custom logic to return user id    return req.HttpContext?.User?.Identity?.Name;};public static Func&amp;lt;HttpRequest, HttpResponse, string&amp;gt; IdentifyCompany = (HttpRequest req, HttpResponse res) =&amp;gt; {    return req.Headers[&quot;X-Organization-Id&quot;];};public static Func&amp;lt;HttpRequest, HttpResponse, string&amp;gt; GetSessionToken = (HttpRequest req, HttpResponse res) =&amp;gt; {    return req.Headers[&quot;Authorization&quot;];};public static Func&amp;lt;HttpRequest, HttpResponse, Dictionary&amp;lt;string, object&amp;gt;&amp;gt; GetMetadata = (HttpRequest req, HttpResponse res) =&amp;gt; {    Dictionary&amp;lt;string, object&amp;gt; metadata = new Dictionary&amp;lt;string, object&amp;gt;    {        {&quot;string_field&quot;, &quot;value_1&quot;},        {&quot;number_field&quot;, 0},        {&quot;object_field&quot;, new Dictionary&amp;lt;string, string&amp;gt; {            {&quot;field_a&quot;, &quot;value_a&quot;},            {&quot;field_b&quot;, &quot;value_b&quot;}            }        }    };    return metadata;};static public Dictionary&amp;lt;string, object&amp;gt; moesifOptions = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;ApplicationId&quot;, &quot;Your Moesif Application Id&quot;},    {&quot;ApiVersion&quot;, &quot;1.1.0&quot;},    {&quot;IdentifyUser&quot;, IdentifyUser},    {&quot;IdentifyCompany&quot;, IdentifyCompany},    {&quot;GetSessionToken&quot;, GetSessionToken},    {&quot;GetMetadata&quot;, GetMetadata}};ApplicationId (Required)            Data type                  string      A string that identifies your application in Moesif.Skip            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      boolean      Optional.A function that takes a request and a response, and returns true if you want to skip this particular event.IdentifyUser            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. But if your setup differs from the standard implementations, provide this function to ensure user identification properly.IdentifyCompany            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the company ID for this event.GetSessionToken            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if your setup differs from the standard, this function can be helpful for tying events together, and help you replay the events.GetMetadata            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      dictionary      Optional.A function that returns an object that allows you to add custom metadata that will be associated with the event.The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.MaskEventModel            Data type      Parameters      Return type                  Function      (EventModel)      EventModel      A function that takes an a Moesif event model and returns an EventModel with desired data removed.Use this if you prefer to write your own mask function. The return value must be a valid EventModel required by Moesif data ingestion API. For more information, see Moesif C# API documentation.For example:public static Func&amp;lt;EventModel, EventModel&amp;gt; MaskEventModel = (EventModel moesifEvent) =&amp;gt;{    Dictionary&amp;lt;String, String&amp;gt; eventRequestHeaders = moesifEvent.Request.Headers;    bool keyExists = eventRequestHeaders.ContainsKey(&quot;Authorization&quot;);    if (keyExists)    {        eventRequestHeaders.Remove(&quot;Authorization&quot;);    };    return moesifEvent;};ApiVersion            Data type                  string      Optional.The API version associated with this particular event.LocalDebug            Data type                  boolean      Set to true to print internal log messages for debugging SDK integration issues.LogBody            Data type      Default                  boolean      true      Set to false to not log the request and response body to Moesif.RequestMaxBodySize            Data type      Default                  Number      100000      The maximum request body size in bytes to log when sending the data to Moesif. Request body will not be logged if its size exceeds RequestMaxBodySize.ResponseMaxBodySize            Data type      Default                  Number      100000      The maximum response body size in bytes to log when sending the data to Moesif. Response body will not be logged if its size exceeds RequestMaxBodySize.AuthorizationHeaderName            Data type                  string      Optional.Request header containing a bearer or basic token to extract user ID. Also, supports a comma-separated string. Moesif checks headers in order like X-Api-Key,Authorization, and so on.AuthorizationUserIdField            Data type                  string      Optional.Field name in JWT or OpenId token’s payload for identifying users. Only applicable if AuthorizationHeaderName is set and is a bearer token.IsLambda            Data type      Default                  boolean      false      Set to true if integrating with AWS Lambda functions.EnableBatching            Data type      Default                  boolean      true      Moesif logs events in batches. Set to false if you want to send the API events one by one. This option is reset to false if IsLambda true.Capture Outgoing Requests in .NET CoreYou can capture all outgoing API calls from your app to third parties like Stripe or to your own dependencies while using System.Net.Http package.The following snippet shows how to configure your application to start capturing outgoing calls:using System.Net.Http;using Moesif.Middleware.Helpers;// moesifOptions is an object of type Dictionary&amp;lt;string, object&amp;gt; which holds configuration options for your application.MoesifCaptureOutgoingRequestHandler handler = new MoesifCaptureOutgoingRequestHandler(new HttpClientHandler(), moesifOptions);HttpClient client = new HttpClient(handler);The following configuration options are available for outgoing API calls. Several options are functions that take request and response as input arguments. These request and response objects correspond to HttpRequestMessage request and HttpResponseMessage response objects respectively.GetMetadataOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      dictionary      Optional.A function that returns an object that allows youto add custom metadata associated with the event. The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a VM instance ID, a trace ID, or a tenant ID with the request.GetSessionTokenOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns the session token string for this event.Moesif tries to get the session token automatically, but if you setup differs from the standard, this function can be helpful for tying events together and help you replay the events.IdentifyUserOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns a user ID string used by your system.Moesif identifies users automatically. But if your setup differs from the standard implementations, provide this function to ensure user identification properly.IdentifyCompanyOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns company ID string for this event.SkipOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      boolean      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns true if you want to skip this particular event.MaskEventModelOutgoing            Data type      Parameters      Return type                  Function      (EventModel)      EventModel      Optional.A function that takes a Moesif event model and returns an EventModel with desired data removed.Use this if you prefer to write your own mask function. The return value must be a valid EventModel required by Moesif data ingestion API. For more information, see the Moesif C# API documentation.LogBodyOutgoing            Data type      Default                  boolean      true      Set to false to not log the request and response body to Moesif..NET Framework Configuration OptionsThe next sections describe the available configuration options for .NET Framework. Here’s a sample configuration:public static Func&amp;lt;IOwinRequest, IOwinResponse, string&amp;gt; IdentifyUser = (IOwinRequest req, IOwinResponse res) =&amp;gt; {    // Implement your custom logic to return user id    return req?.Context?.Authentication?.User?.Identity?.Name;};public static Func&amp;lt;IOwinRequest, IOwinResponse, string&amp;gt; IdentifyCompany = (IOwinRequest req, IOwinResponse res) =&amp;gt; {    return req.Headers[&quot;X-Organization-Id&quot;];};public static Func&amp;lt;IOwinRequest, IOwinResponse, string&amp;gt; GetSessionToken = (IOwinRequest req, IOwinResponse res) =&amp;gt; {    return req.Headers[&quot;Authorization&quot;];};public static Func&amp;lt;IOwinRequest, IOwinResponse, Dictionary&amp;lt;string, object&amp;gt;&amp;gt; GetMetadata = (IOwinRequest req, IOwinResponse res) =&amp;gt; {    Dictionary&amp;lt;string, object&amp;gt; metadata = new Dictionary&amp;lt;string, object&amp;gt;    {        {&quot;string_field&quot;, &quot;value_1&quot;},        {&quot;number_field&quot;, 0},        {&quot;object_field&quot;, new Dictionary&amp;lt;string, string&amp;gt; {            {&quot;field_a&quot;, &quot;value_a&quot;},            {&quot;field_b&quot;, &quot;value_b&quot;}            }        }    };    return metadata;};static public Dictionary&amp;lt;string, object&amp;gt; moesifOptions = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;ApplicationId&quot;, &quot;Your Moesif Application Id&quot;},    {&quot;LocalDebug&quot;, true},    {&quot;LogBody&quot;, true},    {&quot;LogBodyOutgoing&quot;, true},    {&quot;ApiVersion&quot;, &quot;1.1.0&quot;},    {&quot;IdentifyUser&quot;, IdentifyUser},    {&quot;IdentifyCompany&quot;, IdentifyCompany},    {&quot;GetSessionToken&quot;, GetSessionToken},    {&quot;GetMetadata&quot;, GetMetadata},    {&quot;BatchSize&quot;, 25}};In this configuration options, the request and response objects passed in correspond to IOwinRequest request and IOwinResponse response objects respectively.ApplicationId (Required)            Data type                  string      A string that identifies your application in Moesif.Skip            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      boolean      Optional.A function that takes a request and a response, and returns true if you want to skip this particular event.IdentifyUser            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. But if your setup differs from the standard implementations, provide this function to ensure user identification properly.IdentifyCompany            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the company ID for this event.GetSessionToken            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes a request and a response, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if your setup differs from the standard, this function can be helpful for tying events together, and help you replay the events.GetMetadata            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      dictionary      Optional.A function that returns an object that allows you to add custom metadata that will be associated with the event.The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.MaskEventModel            Data type      Parameters      Return type                  Function      (EventModel)      EventModel      A function that takes an a Moesif event model and returns an EventModel with desired data removed.Use this if you prefer to write your own mask function. The return value must be a valid EventModel required by Moesif data ingestion API. For more information, see Moesif C# API documentation.public static Func&amp;lt;EventModel, EventModel&amp;gt; MaskEventModel = (EventModel moesifEvent) =&amp;gt;{    Dictionary&amp;lt;String, String&amp;gt; eventRequestHeaders = moesifEvent.Request.Headers;    bool keyExists = eventRequestHeaders.ContainsKey(&quot;Authorization&quot;);    if (keyExists)    {        eventRequestHeaders.Remove(&quot;Authorization&quot;);    };    return moesifEvent;};ApiVersion            Data type                  string      Optional.The API version associated with this particular event.LocalDebug            Data type                  boolean      Set to true to print internal log messages for debugging SDK integration issues.LogBody            Data type      Default                  boolean      true      Set to false to not log the request and response body to Moesif.DisableStreamOverride            Data type                  boolean      Set to true to disable overriding the request body stream. This is required if your app is using Windows Communication Foundation (WCF). Otherwise, you may experience issues when your business logic accesses the request body.AuthorizationHeaderName            Data type                  string      Optional.Request header containing a bearer or basic token to extract user ID. Also, supports a comma-separated string. Moesif checks headers in order like X-Api-Key,Authorization, and so on.AuthorizationUserIdField            Data type                  string      Optional.Field name in JWT or OpenId token’s payload for identifying users. Only applicable if AuthorizationHeaderName is set and is a bearer token.Capture Outgoing Requests in .NET CoreYou can capture all outgoing API calls from your app to third parties like Stripe or to your own dependencies while using System.Net.Http package.The following snippet shows how to configure your application to start capturing outgoing calls:using System.Net.Http;using Moesif.Middleware.Helpers;// moesifOptions is an object of type Dictionary&amp;lt;string, object&amp;gt; which holds configuration options for your application.MoesifCaptureOutgoingRequestHandler handler = new MoesifCaptureOutgoingRequestHandler(new HttpClientHandler(), moesifOptions);HttpClient client = new HttpClient(handler);The following configuration options are available for outgoing API calls. Several options are functions that take request and response as input arguments. These request and response objects correspond to HttpRequestMessage request and HttpResponseMessage response objects respectively.GetMetadataOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      dictionary      Optional.A function that returns an object that allows youto add custom metadata associated with the event. The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a VM instance ID, a trace ID, or a tenant ID with the request.GetSessionTokenOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns the session token string for this event.Moesif tries to get the session token automatically, but if you setup differs from the standard, this function can be helpful for tying events together and help you replay the events.IdentifyUserOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns a user ID string used by your system.Moesif identifies users automatically. But if your setup differs from the standard implementations, provide this function to ensure user identification properly.IdentifyCompanyOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      string      A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns company ID string for this event.SkipOutgoing            Data type      Parameters      Return type                  Function      (HttpRequest, HttpResponse)      boolean      Optional.A function that takes an HttpRequestMessage and an HttpResponseMessage, and returns true if you want to skip this particular event.MaskEventModelOutgoing            Data type      Parameters      Return type                  Function      (EventModel)      EventModel      Optional.A function that takes a Moesif event model and returns an EventModel with desired data removed.Use this if you prefer to write your own mask function. The return value must be a valid EventModel required by Moesif data ingestion API. For more information, see the Moesif C# API documentation.LogBodyOutgoing            Data type      Default                  boolean      true      Set to false to not log the request and response body to Moesif.Examples.NET Core ExamplesSee the .NET Core examplesusing .NET Core 2.0 and .NET Core 3.0.NET Framework Examples  .NET Framework Example using .NET Framework 4.6.1 and IIS  .NET Framework SelfHost Example using .NET Framework 4.6.1 (SelfHost is uncommon)The following examples demonstrate how to add and update customer information.Update a Single UserTo create or update a user profile in Moesif, use the UpdateUser method.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemaDictionary&amp;lt;string, object&amp;gt; campaign = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;utm_source&quot;, &quot;google&quot;},    {&quot;utm_medium&quot;, &quot;cpc&quot;},    {&quot;utm_campaign&quot;, &quot;adwords&quot;},    {&quot;utm_term&quot;, &quot;api+tooling&quot;},    {&quot;utm_content&quot;, &quot;landing&quot;}};// metadata can be any custom dictionaryDictionary&amp;lt;string, object&amp;gt; metadata = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;email&quot;, &quot;john@acmeinc.com&quot;},    {&quot;first_name&quot;, &quot;John&quot;},    {&quot;last_name&quot;, &quot;Doe&quot;},    {&quot;title&quot;, &quot;Software Engineer&quot;},    {&quot;sales_info&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;stage&quot;, &quot;Customer&quot;},            {&quot;lifetime_value&quot;, 24000},            {&quot;account_owner&quot;, &quot;mary@contoso.com&quot;}        }    }};// Only user_id is requiredDictionary&amp;lt;string, object&amp;gt; user = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;user_id&quot;, &quot;12345&quot;},    {&quot;company_id&quot;, &quot;67890&quot;}, // If set, associate user with a company object    {&quot;campaign&quot;, campaign},    {&quot;metadata&quot;, metadata},};// .NET CoreMoesifMiddleware moesifMiddleware = new MoesifMiddleware(Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// .NET Framework// MoesifMiddleware moesifMiddleware = new MoesifMiddleware(OwinMiddleware next, Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// Update the user asynchronouslymoesifMiddleware.UpdateUser(user);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif C# API Reference.Update Users in BatchTo update a list of users in one batch, use the UpdateUsersBatch method.Similar to UpdateUser, but used to update a list of users in one batch.Only the user_id field is required.This method is a convenient helper that calls the Moesif API lib.For details, visit the C# API Reference.List&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt; usersBatch = new List&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt;();Dictionary&amp;lt;string, object&amp;gt; metadataA = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;email&quot;, &quot;john@acmeinc.com&quot;},    {&quot;first_name&quot;, &quot;John&quot;},    {&quot;last_name&quot;, &quot;Doe&quot;},    {&quot;title&quot;, &quot;Software Engineer&quot;},    {&quot;sales_info&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;stage&quot;, &quot;Customer&quot;},            {&quot;lifetime_value&quot;, 24000},            {&quot;account_owner&quot;, &quot;mary@contoso.com&quot;}        }    }};// Only user_id is requiredDictionary&amp;lt;string, object&amp;gt; userA = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;user_id&quot;, &quot;12345&quot;},    {&quot;company_id&quot;, &quot;67890&quot;}, // If set, associate user with a company object    {&quot;metadata&quot;, metadataA},};Dictionary&amp;lt;string, object&amp;gt; metadataB = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;email&quot;, &quot;mary@acmeinc.com&quot;},    {&quot;first_name&quot;, &quot;Mary&quot;},    {&quot;last_name&quot;, &quot;Jane&quot;},    {&quot;title&quot;, &quot;Software Engineer&quot;},    {&quot;sales_info&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;stage&quot;, &quot;Customer&quot;},            {&quot;lifetime_value&quot;, 24000},            {&quot;account_owner&quot;, &quot;mary@contoso.com&quot;}        }    }};// Only user_id is requiredDictionary&amp;lt;string, object&amp;gt; userB = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;user_id&quot;, &quot;54321&quot;},    {&quot;company_id&quot;, &quot;67890&quot;}, // If set, associate user with a company object    {&quot;metadata&quot;, metadataB},};usersBatch.Add(userA);usersBatch.Add(userB);// .NET CoreMoesifMiddleware moesifMiddleware = new MoesifMiddleware(Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// .NET Framework// MoesifMiddleware moesifMiddleware = new MoesifMiddleware(OwinMiddleware next, Dictionary&amp;lt;string, object&amp;gt; moesifOptions)moesifMiddleware.UpdateUsersBatch(usersBatch);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif C# API Reference.Update a Single CompanyTo update a single company, use the UpdateCompany method.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemaDictionary&amp;lt;string, object&amp;gt; campaign = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;utm_source&quot;, &quot;google&quot;},    {&quot;utm_medium&quot;, &quot;cpc&quot;},    {&quot;utm_campaign&quot;, &quot;adwords&quot;},    {&quot;utm_term&quot;, &quot;api+tooling&quot;},    {&quot;utm_content&quot;, &quot;landing&quot;}};// metadata can be any custom dictionaryDictionary&amp;lt;string, object&amp;gt; metadata = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;org_name&quot;, &quot;Acme, Inc&quot;},    {&quot;plan_name&quot;, &quot;Free&quot;},    {&quot;deal_stage&quot;, &quot;Lead&quot;},    {&quot;mrr&quot;, 24000},    {&quot;demographics&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;alexa_ranking&quot;, 500000},            {&quot;employee_count&quot;, 47}        }    }};Dictionary&amp;lt;string, object&amp;gt; company = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;company_id&quot;, &quot;67890&quot;}, // The only required field is your company id    {&quot;company_domain&quot;, &quot;acmeinc.com&quot;}, // If domain is set, Moesif will enrich your profiles with publicly available info    {&quot;campaign&quot;, campaign},    {&quot;metadata&quot;, metadata},};// .NET CoreMoesifMiddleware moesifMiddleware = new MoesifMiddleware(Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// .NET Framework// MoesifMiddleware moesifMiddleware = new MoesifMiddleware(OwinMiddleware next, Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// Update the company asynchronouslymoesifMiddleware.UpdateCompany(company);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the company_id field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif C# API Reference.Update Companies in BatchTo update a list of companies in one batch, use the UpdateCompaniesBatch method.List&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt; companiesBatch = new List&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt;();// metadata can be any custom dictionaryDictionary&amp;lt;string, object&amp;gt; metadataA = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;org_name&quot;, &quot;Acme, Inc&quot;},    {&quot;plan_name&quot;, &quot;Free&quot;},    {&quot;deal_stage&quot;, &quot;Lead&quot;},    {&quot;mrr&quot;, 24000},    {&quot;demographics&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;alexa_ranking&quot;, 500000},            {&quot;employee_count&quot;, 47}        }    }};Dictionary&amp;lt;string, object&amp;gt; companyA = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;company_id&quot;, &quot;67890&quot;}, // The only required field is your company id    {&quot;company_domain&quot;, &quot;acmeinc.com&quot;}, // If domain is set, Moesif will enrich your profiles with publicly available info    {&quot;metadata&quot;, metadataA},};// metadata can be any custom dictionaryDictionary&amp;lt;string, object&amp;gt; metadataB = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;org_name&quot;, &quot;Contoso, Inc&quot;},    {&quot;plan_name&quot;, &quot;Starter&quot;},    {&quot;deal_stage&quot;, &quot;Lead&quot;},    {&quot;mrr&quot;, 48000},    {&quot;demographics&quot;, new Dictionary&amp;lt;string, object&amp;gt; {            {&quot;alexa_ranking&quot;, 500000},            {&quot;employee_count&quot;, 59}        }    }};Dictionary&amp;lt;string, object&amp;gt; companyB = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;company_id&quot;, &quot;09876&quot;}, // The only required field is your company id    {&quot;company_domain&quot;, &quot;contoso.com&quot;}, // If domain is set, Moesif will enrich your profiles with publicly available info    {&quot;metadata&quot;, metadataB},};companiesBatch.Add(companyA);companiesBatch.Add(companyB);// .NET CoreMoesifMiddleware moesifMiddleware = new MoesifMiddleware(Dictionary&amp;lt;string, object&amp;gt; moesifOptions)// .NET Framework// MoesifMiddleware moesifMiddleware = new MoesifMiddleware(OwinMiddleware next, Dictionary&amp;lt;string, object&amp;gt; moesifOptions)moesifMiddleware.UpdateCompaniesBatch(companiesBatch);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the company_id field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif C# API Reference.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailThe following sections discuss some specific troubleshooting scenarios.Issue Reading Request Body in WCFCertain serializers for Windows Communication Foundation (WCF) may not correctly bind the request body when using logging middleware like Moesif.If your app uses Windows Communication Foundation (WCF), you may find that your business logic has errors accessing the request body such as for POST and PUT requests.To fix this, set the option DisableStreamOverride to true:Dictionary&amp;lt;string, object&amp;gt; moesifOptions = new Dictionary&amp;lt;string, object&amp;gt;{    {&quot;ApplicationId&quot;, &quot;Your Moesif Application Id&quot;},    {&quot;DisableStreamOverride&quot;, true},};Traditional Monolith Website brokenSome monolith apps which contain both a website and an API in the same app may issues when API logging middleware is enabled.This is usually due to interactions with other custom middleware.Since usually this custom middleware is enabled for the website only, the fix we recommend is to enable Moesif only for your API.To do so, use MapWhen that only activates the middleware if the Path contains /apiapp.MapWhen(context =&amp;gt; context.Request.Path.ToString().Contains(&quot;/api&quot;), appBuilder =&amp;gt;{    appBuilder.Use&amp;lt;MoesifMiddleware&amp;gt;(new System.Collections.Generic.Dictionary&amp;lt;string, object&amp;gt; {        {&quot;ApplicationId&quot;, &quot;Your Moesif Application Id&quot;}    });});The Response Body Is Not Logged or Calls Are Jot Recieved in MoesifEach ASP.NET Core server has an option called AllowSynchronousIO that toggles synchronous IO APIs such as HttpRequest.Body.Read, HttpResponse.Body.Write, and Stream.Flush. These APIs have previously caused thread starvation and app hangs, so starting from ASP.NET Core 3.0 Preview 3, they are disabled by default.You  need to set the following option to ensure the response body is logged and to ensure all events are forwarded to Moesif:      For .NET Core and .NET 5:          .ConfigureKestrel((context, options) =&amp;gt; {          options.AllowSynchronousIO = true;      });            For .NET Core and .NET 6+, when using a WebApplicationBuilder in Program.cs:      builder.WebHost.ConfigureKestrel(serverOptions =&amp;gt;  {      serverOptions.AllowSynchronousIO = true;  });      See the .NET documentation relating to the origins of the AllowSynchronousIO option. For more information about this workaround, see .NET Core 3.0 AllowSynchronousIO Workaround.Ensuring Errors Handled by ExceptionHandler Are LoggedTo capture the API calls handled by ExceptionHandler, make sure that the app.UseMiddleware&amp;lt;MoesifMiddleware&amp;gt;(moesifOptions); precedes the app.UseExceptionHandler() in the pipeline.How to Test  Manually clone the git repository.  From your terminal, navigate to the root directory of the middleware.  Run Install-Package Moesif.Middleware.  Add your Moesif Application ID to Moesif.Middleware.Test/MoesifMiddlewareTest.cs.  The tests live in the Moesif.Middleware.Test project. In order to invoke these test cases, you need NUnit 3.0 Test Adapter Extension for Visual Studio. Once the SDK finishes compiling, the test cases should appear in the Test Explorer window. Here, you can click Run All to execute these test cases.Tested VersionsMoesif has validated this middleware against the following framework versions.            Framework      Framework Version                  .NET      5.0              .NET      6.0              .NET      7.0              .NET Core      2.0-3.0              .NET Framework MVC      4.6-4.7              .NET Framework Web API      4.6-4.7              .NET Framework Web API SelfHost      4.6-4.7      Last Supported Version for .NET 4.5SDK version 1.3.25 supports .NET 4.5, which will be no longer supported. Please upgrade to .NET 4.6.1 or higher.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/dotnet/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-envoy-lua-plugin": {
      "title": "Server Integration Guide - Envoy Lua Plugin",
      "content"	 : "Moesif Envoy PluginThe Moesif Envoy plugin captures API traffic from Envoy Service Proxyand logs it to Moesif API Analytics and Monetization. This plugin leverages an asynchronous design and doesn’t add any latency to your API calls.  Envoy is a L7 proxy and communication bus.  Moesif is an API analytics and monetization platform.Source Code on GitHub  Moesif has both an Envoy plugin built in WASM and one built in Lua. For most projects including Gloo and Istio, Moesif recommends the WASM plugin for full compatibility.How to install1. Download plugin filesDownload the latest release into your current working directory for Envoy. wget -O moesif-envoy-plugin.tar.gz https://github.com/Moesif/moesif-envoy-plugin/archive/0.1.7.tar.gz &amp;amp;&amp;amp;     tar -xf moesif-envoy-plugin.tar.gz -C ./ --strip-components 12. Update Envoy configIn your envoy.yaml, add a http_filters section along with the below code snippet.Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps. http_filters:    - name: envoy.filters.http.lua    typed_config:        &quot;@type&quot;: type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua        inline_code: |        local log = require(&quot;moesif.plugins.log&quot;)        -- Moesif configs        log.set_application_id(&quot;Your Moesif Application Id&quot;)        -- ... For other options see below.        function envoy_on_request(request_handle)            -- Log Event Request to Moesif            log.log_request(request_handle)        end        function envoy_on_response(response_handle)            -- Log Event Response to Moesif            log.log_response(response_handle)        endAdd a clusters config with the below code snippet. clusters:  - name: moesifprod    connect_timeout: 0.25s    type: logical_dns    http2_protocol_options: {}    lb_policy: round_robin    load_assignment:      cluster_name: moesifprod      endpoints:      - lb_endpoints:        - endpoint:            address:              socket_address:                address: api.moesif.net                port_value: 443    transport_socket:      name: envoy.transport_sockets.tls      typed_config:        &quot;@type&quot;: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext        sni: api.moesif.net        common_tls_context:           validation_context:            match_subject_alt_names:            - exact: &quot;*.moesif.net&quot;            trusted_ca:              filename: /etc/ssl/certs/ca-certificates.crtIf you downloaded the files to a different location, replace moesif.plugins.log with the correct path3. Restart EnvoyMake a few API calls to test that they are logged to Moesif.Docker ComposeIf you’re using Docker, Moesif has a working example usign Docker Compose in the example dirTo run the example:Modify the example files Dockerfile-envoy and envoy.yml for use with your live application.  cd into the example dir  Add your Moesif Application Id to envoy.yml  Run the command docker-compose up -dTo run the HTTPS example:Envoy’s Dynamic forward proxy will not normally terminate an SSL connection and will instead tunnel to proxied service. In order for API observability tools like Moesif to capture traffic, you need to configure Envoy to terminate the SSL connection.In order to do so, do the following:  cd into the example dir  Add your Moesif Application Id to envoy-https.yml  Expose port &quot;8443:8443&quot; in docker-compose.yaml  Generate a self-signed certificate pair using: (Please change the common name as required) $ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3650 -nodes -subj &#39;/CN=localhost&#39;  Please update the keys in the transport_socket section in envoy-https.yml. Incase, if you don’t want to copy the keys in the file, you could provide the path where keys are located. Please update the section if passing the path -transport_socket:name: envoy.transport_sockets.tlstyped_config:    &quot;@type&quot;: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext    common_tls_context:    tls_certificates:        certificate_chain: { filename: &quot;/etc/envoy/ssl/cert.pem&quot; }        private_key: { filename: &quot;/etc/envoy/ssl/key.pem&quot; }        password: { inline_string: &quot;XXXXX&quot; }      Update the Docker cmd to use envoy-https.yaml instead of envoy.yml. This can be done by updating last line in Dockerfile-envoy to CMD [&quot;/usr/local/bin/envoy&quot;, &quot;-c&quot;, &quot;/etc/envoy-https.yaml&quot;, &quot;-l&quot;, &quot;debug&quot;, &quot;--service-cluster&quot;, &quot;proxy&quot;]  Run the command docker-compose up -dConfiguration optionsset_application_id()(required), string, is obtained via your Moesif Account, this is required.set_batch_size()(optional) number, default 5. Maximum batch size when sending to Moesif.set_user_id_header()(optional) string, Request header to use to identify the User in Moesif.set_company_id_header()(optional) string, Request header to use to identify the Company (Account) in Moesif.set_metadata()(optional) table, default {}. This allows you to associate the event with custom metadata. For example, you may want to save a VM instance_id, a trace_id, or a tenant_id with the request.set_disable_capture_request_body()(optional) boolean, default false. Set this flag to true, to disable logging of request body.set_disable_capture_response_body()(optional) boolean, default false. Set this flag to true, to disable logging of response body.set_request_header_masks()(optional) table, default {}. An array of request header fields to mask.set_request_body_masks()(optional) table, default {}. An array of request body fields to mask.set_response_header_masks()(optional) table, default {}. An array of response header fields to mask.set_response_body_masks()(optional) table, default {}. An array of response body fields to mask.set_debug()(optional) boolean, default false. Set this flag to true, to see debugging messages.How to test      Clone this repo and edit the example/envoy.yaml file to set your actual Moesif Application Id.    Your Moesif Application Id can be found in the Moesif Portal. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.    You can always find your Moesif Application Id at any time by logging  into the Moesif Portal, click on the top right menu, and then clicking API Keys.        Build docker image and start container     cd example &amp;amp;&amp;amp; docker-compose up -d            By default, The container is listening on port 8000. You should now be able to make a request:     curl --request GET      --url &#39;http://localhost:8000/?x=2&amp;amp;y=4&#39;      --header &#39;Content-Type: application/json&#39;      --header &#39;company_id_header: envoy_company_id&#39;      --header &#39;user_id_header: envoy_user_id&#39;      --data &#39;{         &quot;envoy_event&quot;: true     }&#39;            The data should be captured in the corresponding Moesif account.  Congratulations! If everything was done correctly, Moesif should now be tracking all network requests. If you have any issues with set up, please reach out to support@moesif.com.How to enable Envoy plugin inside Istio’s sidecars  If you’ve istio already installed, and istio-system namespace available, skip this step. If not you could download and install istio.      Download (Linux or macOS):      curl -L https://istio.io/downloadIstio | sh -            Move to the Istio package directory. For example, if the package is istio-1.9.2:      cd istio-1.9.2            Add the istioctl client to your path (Linux or macOS):      export PATH=$PWD/bin:$PATH            For this example, we use the demo configuration profile. It’s selected to have a good set of defaults for testing, but there are other profiles for production or performance testing.      istioctl install --set profile=demo            Clone this repo and edit the istio-example/envoy-filter.yaml file to set your actual Moesif Application Id.    Your Moesif Application Id can be found in the Moesif Portal. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.    You can always find your Moesif Application Id at any time by logging  into the Moesif Portal, click on the top right menu, and then clicking API Keys.        At this point, make sure istio-system namespace is available since we’re going to deploy app and enable envoy-filter in istio-system for this particular example. It could be verified by running this command     kubectl get namespace            Navigate to istio-example directory.        Create a configMap which will be consumed by Pods as configuration file in a volume.     kubectl create -f configMap.yaml -n istio-system            Create a Pod and manually inject the sidecar before deploying the nginx application with the following command:     kubectl apply -n istio-system -f &amp;lt;(istioctl kube-inject -f nginx.yaml)        Verify the nginx pod is running     kubectl get pods -n istio-system        Verify the deployment is ready and available     kubectl get deployment -o wide -n istio-system            Create Envoy filter     kubectl apply -f envoy-filter.yaml -n istio-system            Set the SOURCE_POD environment variable to the name of your source pod:    export SOURCE_POD=$(kubectl get pod -n istio-system -l app=nginx -o jsonpath={.items..metadata.name})echo $SOURCE_POD            Now you could send request to an external service, and data should be captured in the corresponding Moesif account.    kubectl -n istio-system exec &quot;$SOURCE_POD&quot; -c nginx -- curl -XGET -sSL  -H &quot;Content-Type:application/json&quot; -o /dev/null -D - http://httpbin.org/uuid -d &quot;{&quot;test&quot;: &quot;sf&quot;}&quot;        You could tail Logs    kubectl logs --follow -l app=nginx -c istio-proxy -n istio-system        Congratulations! If everything was done correctly, Moesif should now be tracking all network requests. If you have any issues with set up, please reach out to support@moesif.com.  Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/envoy-lua-plugin/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-envoy-wasm-plugin": {
      "title": "Server Integration Guide - Envoy WASM Plugin",
      "content"	 : "Moesif Envoy WASM PluginThe Moesif Envoy WebAssembly plugin captures API traffic from Envoy Service Proxy and logs it to Moesif API Analytics and Monetization platform. Supports projects built on Envoy such as Solo.io Gloo Gateway, Istio, and others. This plugin leverages an asynchronous design and doesn’t add any latency to your API calls.  Envoy is a L7 proxy and communication bus.  Moesif is an API analytics and monetization platform.Source Code on GitHub  Moesif has both an Envoy plugin built in WASM and one built in Lua. For most projects including Gloo and Istio, Moesif recommends the WASM plugin for full compatibility.How to Install1. Download the PluginThe moesif_envoy_wasm_plugin.wasm file can be downloaded directly from the GitHub releases page. To do so:  Navigate to the GitHub release page.  Find the latest release and download the moesif_envoy_wasm_plugin.wasm file from the assets section.2. Load the Plugin into your Envoy Proxy  Transfer the downloaded moesif_envoy_wasm_plugin.wasm file to the Envoy proxy server.  Place the wasm file in an appropriate directory (for example, /etc/envoy/proxy-wasm-plugins/).  Ensure the Envoy proxy has read access to the wasm file.3. Configure EnvoyUpdate your Envoy configuration (envoy.yaml) to use the Moesif Envoy plugin. Add the http_filters and clusters sections as shown in the provided code snippets.Remember to replace &amp;lt;YOUR APPLICATION ID HERE&amp;gt; with your actual Moesif Application Id. Your Moesif Application Id can be found in the Moesif Portal. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.The upstream config defaults to ‘moesif_api’ and is optional, but if you use something else in the clusters.name field, you will need to explicitly include the upstream config value to match.Also, remember to update the filename path in the vm_config section to match the location where you placed the moesif_envoy_wasm_plugin.wasm file.http_filters:# ... other filters ...- name: envoy.filters.http.wasm  typed_config:    &quot;@type&quot;: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm    config:      name: &quot;moesif_api&quot;      root_id: &quot;moesif_api_root_id&quot;      configuration:        &quot;@type&quot;: &quot;type.googleapis.com/google.protobuf.StringValue&quot;        value: |          {            &quot;moesif_application_id&quot;:&quot;&amp;lt;YOUR APPLICATION ID HERE&amp;gt;&quot;,             &quot;user_id_header&quot;:&quot;X-User-Example-Header&quot;,            &quot;company_id_header&quot;:&quot;X-Company-Example-Header&quot;,            &quot;upstream&quot;: &quot;moesif_api&quot;          }      vm_config:        vm_id: &quot;moesif_api_vm&quot;        code:          local:            filename: &quot;/etc/envoy/proxy-wasm-plugins/moesif_envoy_wasm_plugin.wasm&quot;# ... other filters ending with router- name: envoy.filters.http.router  typed_config:    &quot;@type&quot;: type.googleapis.com/envoy.extensions.filters.http.router.v3.Routerclusters:# ... other clusters ...- name: moesif_api  type: strict_dns  load_assignment:    cluster_name: moesif_api    endpoints:    - lb_endpoints:      - endpoint:          address:            socket_address:              address: api.moesif.net              port_value: 443  transport_socket:    name: envoy.transport_sockets.tls    typed_config:      &quot;@type&quot;: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext4. Restart EnvoyAfter saving the updated configuration file, restart Envoy to apply the changes. Check Envoy’s log to ensure that there are no errors during startup.5. TestMake a few API calls that pass through the Envoy proxy. These calls should now be logged to your Moesif account.How to UseCapturing API trafficThe Moesif Envoy plugin captures API traffic from Envoy and logs it to Moesif automatically when Envoy routes traffic through the plugin.  Envoy has detailed and robust configuration options for traffic and plugin routing to apply the Moesif plugin to only some traffic or to all traffic. For more information, please refer to the Envoy Request Lifecycle Guide.Identifying users and companiesThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey. The plugin currently supports reading request headers to identify users and companies automatically from events.  If the user_id_header or company_id_header configuration option is set, the named request header will be read from each request and it’s value will be included in the Moesif event model as the user_id or company_id field respectively.          You can associate API users to companies for tracking account-level usage. This can be done either with the company header above or through the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.      Configuration OptionsThese configuration options are specified as JSON in the configuration section of the http_filters in your envoy.yaml file.            Option      Type      Default      Description                  moesif_application_id      String      None      Required. Your Moesif Application Id. Can be found within the Moesif Portal.              user_id_header      String      None      Optional. The header key for User Id. If provided, the corresponding header value is used as the User Id in Moesif event models.              company_id_header      String      None      Optional. The header key for Company Id. If provided, the corresponding header value is used as the Company Id in Moesif event models.              batch_max_size      Integer      100      Optional. The maximum batch size of events to be sent to Moesif.              batch_max_wait      Integer      2000      Optional. The maximum wait time in milliseconds before a batch is sent to Moesif, regardless of the batch size.              upstream      String      “moesif_api”      Optional. The upstream cluster that points to Moesif’s API.      Exampleconfiguration:  &quot;@type&quot;: &quot;type.googleapis.com/google.protobuf.StringValue&quot;  value: |    {      &quot;moesif_application_id&quot;:&quot;&amp;lt;YOUR APPLICATION ID HERE&amp;gt;&quot;,       &quot;user_id_header&quot;:&quot;X-User-Example-Header&quot;,      &quot;company_id_header&quot;:&quot;X-Company-Example-Header&quot;,      &quot;batch_max_size&quot;: 100,      &quot;batch_max_wait&quot;: 5,      &quot;upstream&quot;: &quot;example_custom_envoy_cluster_naming_scheme_moesif&quot;    }Updating the ConfigurationUpdating the envoy.yaml configuration file in the example above and restarting is sufficient to update your Moesif WASM Plugin configuration. Envoy has a diversity of configuration mechanisms and supports hot reloading of configuration. For more information, please refer to the Envoy Configuration Documentation.ExamplesEnvoy Docker ComposeIf you’re using Docker, you can use the provided docker-compose.yaml to easily set up your environment. The Docker Compose file includes three services:  rust-builder: This service builds the wasm binary from the Rust source code.  envoy: This service runs the Envoy proxy with the Moesif Envoy plugin.  echo: This is a simple echo server for testing purposes.Steps  Ensure Docker and Docker Compose are installed on your system.      Clone the project repository.     git clone https://github.com/Moesif/moesif-envoy-wasm-plugin.git cd moesif-envoy-plugin/examples/envoy            Build and start the services using Docker Compose.     docker-compose up --build            Now, you can send requests to http://localhost:10000. The Envoy proxy listens on this port, forwards the requests to the echo server, and logs the requests and responses to Moesif.        You can view the Envoy logs with the following command:     docker-compose logs envoy      Remember to replace &amp;lt;YOUR APPLICATION ID HERE&amp;gt; in envoy.yaml file with your actual Moesif Application Id. Your Moesif Application Id can be found in the Moesif Portal.Moesif Istio WASM Plugin ExampleThis README describes how to install and configure the Moesif Istio WASM Plugin with Minikube, using the Kubernetes resources provided.PrerequisitesYou’ll need access to a Kubernetes cluster into which to install the Moesif Istio WASM Plugin. This example uses Minikube to provide everything you need, but you can use any Kubernetes cluster:  Istioctl (v1.10.0 or later)  Minikube (v1.27 or later)  kubectl (v1.25 or later)Start Minikube giving it enough resources:minikube start --cpus 4 --memory 8192Istio InstallationWe’re going to use the Istio CLI tool for the installation.  Install the Istio base chart which includes cluster-wide resources used by the Istio operator:istioctl install --set profile=demo -y  Check the status of the Istio system pods:kubectl get pods -n istio-systemDeploy the Moesif Istio WASM Plugin Example      Navigate to the examples/istio directory in this repository:        Apply the resources to your Minikube cluster.  This will create the echo service, Istio inbound configuration to route traffic to the echo service, Istio outbound configuration to allow Istio to contact Moesif’s API, and the Moesif WASM plugin itself:  kubectl apply -f echo-service.yaml  -f istio-echo-inbound.yaml  -f istio-moesif-outbound.yaml  -f moesif-wasm-plugin.yaml  Verify that the echo service is running:kubectl get pods -n defaultYou should see the echo pod in the Running status.  Test the echo service:kubectl port-forward svc/echo 8080:80Now you can send a request to the echo service running inside the cluster from the host machine:curl http://localhost:8080/echoYou should get a response: Hello from echo service validating the service is running.Moesif WASM Plugin ConfigurationThe WasmPlugin YAML definition in moesif-wasm-plugin.yaml configures the Moesif Istio WASM Plugin.  The pluginConfig section of the YAML definition is shown below:    moesif_application_id: &amp;lt;YOUR MOESIF APPLICATION ID&amp;gt;    upstream: outbound|443||api.moesif.netThis configuration allows the plugin to capture and log the requests and responses flowing through the Istio service mesh. To use the plugin, you need a Moesif application id, which is set in the moesif_application_id field in the plugin configuration. You can get this from your Moesif dashboard.Remember to replace the moesif_application_id and upstream values in with your actual values.  The upstream string value is the cluster name that points to Moesif’s API in the Istio outbound configuration.  debug is set to true to enable debug logging for the example, but this should be set to false in production.Accessing the echo service via Istio Ingress GatewayNext, access the echo service via Istio Ingress Gateway, you first need to determine the ingress IP and ports:  For Minikube:export INGRESS_HOST=$(minikube ip)export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath=&#39;{.spec.ports[?(@.name==&quot;http2&quot;)].nodePort}&#39;)Now, you can send a request to the echo service through the Istio Ingress Gateway and the Moesif WASM Plugin:curl -sS &quot;http://${INGRESS_HOST}:${INGRESS_PORT}/echo&quot;The response should be Hello from echo service.Finished, Check LogsAfter the configuration is applied, you can check the events in your https://moesif.com account to see the plugin in action.Other IntegrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/envoy-wasm-plugin/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-express-gateway": {
      "title": "Server Integration Guide - Express Gateway",
      "content"	 : "Moesif Plugin for Express GatewayExpress Gateway is an open-source API Gateway/API Management application built on the Node.js express framework.Moesif is an API analytics, monitoring and log analysis platform.This package is a plugin for Express Gateway to easily add Moesif’s API analytics to your APIs served by Express Gateway.How to install      Follow instructions for setting up Express Gateway    Install express-gateway-plugin-moesif:Within the folder of the Gateway created by Express Gateway, type in:    npm install --save express-gateway-plugin-moesif            Add the moesif plugin to system.config.yml    plugins:  # express-gateway-plugin-example:  #   param1: &#39;param from system.config&#39;  moesif:    applicationId: &#39;Your Moesif Application Id&#39;      Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking Installation.Other configuration options includes,  debug: turn on debug messages      sessionTokenHeader: Set the HTTP header key that contains your API’s Authorization token/API key. Moesif tries to detect sessions automatically. However, if we cannot detect it correctly, you can specify which header field to use.        Add moesif policy to whitelist of your gateway.config.yml    policies:  - proxy  # other policies.  - moesif        Add moesif policy to your pipelines also in the gateway.config.yml.    pipelines:- name: getting-started  apiEndpoints:    - api  policies:    - moesif:    - key-auth:    - proxy:        - action:            serviceEndpoint: httpbin            changeOrigin: true      To capture all data for a pipeline, please make sure to put Moesif at the top of the pipeline. If You have multiple pipelines, be sure to add the moesif policy to each pipeline you want to capture data for.Additional Info:This plugin is a simple wrapper around the moesif-express middleware.Since Express Gateway’s configuration is designed to be declarative, some of the options from moesif-express that require a function are not ported over. We’ll do so in the future.In the mean time, if you need to use additional options, the easiest way is to fork this repo and add your required options to the middlewareCreator.js file.",
      "url": " /server-integration/express-gateway/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-gin": {
      "title": "Server Integration Guide - Go (Gin)",
      "content"	 : "Moesif Middleware for Go Gin Frameworkby Moesif, the API analytics and API monetization platform.Moesif middleware for Go Gin Framework logs API calls and sends them to Moesif for API analytics and log analysis. This middleware allows you to integrate Moesif’s API analytics and API monetization features into your Go Gin applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareUse go get with the version for Go modulesgo get github.com/moesif/moesifgin@v1.0.0Configure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseThe following snippet shows how to use the middleware:import (    &quot;github.com/gin-gonic/gin&quot;    &quot;github.com/moesif/moesifgin&quot;)func main() {    r := gin.New()    moesifOptions := map[string]interface{}{        &quot;Application_Id&quot;:   &quot;YOUR_MOESIF_APPLICATION_ID&quot;,        &quot;Log_Body&quot;:         true,    }    r.Use(moesifgin.MoesifMiddleware(moesifOptions))    r.POST(&quot;/test&quot;, func(c *gin.Context) {c.JSON(201, gin.H{&quot;message&quot;: &quot;hello world&quot;})})    r.Run(&quot;:8080&quot;)}Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Optional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third-party services through the following method:moesifgin.StartCaptureOutgoing(moesifOptions)moesifOptions (Required)A map[string]interface{} type containing the configuration options for your application. See the example Gin server code for better understanding.See Configuration Options for the common configuration options. See Options for Logging Outgoing Calls for configuration options specific to capturing and logging outgoing API calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailConfiguration OptionsThe following sections describe the available configuration options for this middleware. You can set these options in the Moesif initialization options object. See the example to understand how you can specify these options.Application_Id (Required)         Data type              string     A string that identifies your application in Moesif.Should_Skip         Data type          Parameters          Return type              Function          (c *gin.Context)          bool     Optional.A function that takes a *gin.Context, and returns true if you want to skip logging this particular event.Identify_User         Data type          Parameters          Return type              Function          (c *gin.Context)          string     Optional, but highly recommended.A function that takes a *gin.Context, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.Identify_Company         Data type          Parameters          Return type              Function          (c *gin.Context)          string     Optional.A function that takes a *gin.Context, and returns a string that represents the company ID for this event.Get_Metadata         Data type          Parameters          Return type              Function          (c *gin.Context)          map[string]interface{}     Optional.A function that returns a map that allows you to add custom metadata that will be associated with the event.The metadata must be a map that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.Get_Session_Token         Data type          Parameters          Return type              Function          (c *gin.Context)          string     Optional.A function that takes a *gin.Context, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, provide this function to help identify sessions.Request_Header_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns an array of strings to mask specific request header fields.Request_Body_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns an array of strings to mask specific request body fields.Response_Header_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns an array of strings to mask specific response header fields.Response_Body_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns an array of strings to mask specific response body fields.Debug         Data type              bool     Optional.Set to true to see debugging messages. This may help you troubleshoot integration issues.Log_Body         Data type          Default              bool          true     Optional.Set to false to not log the request and response body to Moesif.Event_Queue_Size         Data type          Default              int          10000     An optional field name that specifies the maximum number of events to hold in queue before sending to Moesif. In case of network issues, the middleware may fail to connect to or send events to Moesif. For those scenarios, this option helps prevent adding new events to the queue to prevent memory overflow.Batch_Size         Data type          Default              int          200     An optional field name that specifies the maximum batch size when sending to Moesif.Timer_Wake_Up_Seconds         Data type          Default              int          2     An optional field that specifies a time in seconds how often background thread runs to send events to Moesif.Options for Logging Outgoing CallsThe following configuration options apply to outgoing API calls. The request and response objects passed in are *http.Request and *http.Response objects of the Go standard library.Should_Skip_Outgoing         Data type          Parameters          Return type              Function          (req *http.Request, resp *http.Response)          bool     Optional.A function that takes a request and response, and returns true if you want to skip logging this particular event.Identify_User_Outgoing         Data type          Parameters          Return type              Function          (req *http.Request, resp *http.Response)          string     Optional, but highly recommended.A function that takes a request and response, and returns a string that represents the user ID used by your system.Identify_Company_Outgoing         Data type          Parameters          Return type              Function          (req *http.Request, resp *http.Response)          string     Optional.A function that takes a request and response, and returns a string that represents the company ID for this event.Get_Metadata_Outgoing         Data type          Parameters          Return type              Function          (req *http.Request, resp *http.Response)          map[string]interface{}     Optional.A function that returns a map that allows you to add custom metadata that will be associated with the event.Get_Session_Token_Outgoing         Data type          Parameters          Return type              Function          (req *http.Request, resp *http.Response)          string     Optional.A function that takes a request and response, and returns a string that represents the session token for this event.Log_Body_Outgoing         Data type          Default              bool          true     Optional.Set to false to not log the request and response body to Moesif.Examples  Example Go Gin app using this middlewareThe following examples demonstrate some common operations:  Updating a single user  Updating users in batch  Updating a single company  Updating companies in batch  Updating a single subscription  Updating subscriptions in batchUpdate UserUpdateUser MethodUse this method to create or update a user profile in Moesif.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,    &quot;Log_Body&quot;: true,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom mapmetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduser := models.UserModel{  UserId:    &quot;12345&quot;,  CompanyId: literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}// Update Usermoesifgin.UpdateUser(&amp;amp;user, moesifOptions)The metadata field can contain any user demographic or other information you want to store.Only the UserId field is required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.UpdateUsersBatch MethodSimilar to UpdateUser, but to update a list of users in one batch.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,}// List of Usersvar users []*models.UserModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom mapmetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduserA := models.UserModel{  UserId:    &quot;12345&quot;,  CompanyId: literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}users = append(users, &amp;amp;userA)// Update Usersmoesifgin.UpdateUsersBatch(users, moesifOptions)The metadata field can contain any user demographic or other information you want to store.Only the UserId field is required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentationUpdate CompanyUpdateCompany MethodUse this method to create or update a company profile in Moesif.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom mapmetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompany := models.CompanyModel{    CompanyId:     &quot;67890&quot;,    // The only required field is your company id    CompanyDomain: literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info     Campaign:      &amp;amp;campaign,    Metadata:      &amp;amp;metadata,}// Update Companymoesifgin.UpdateCompany(&amp;amp;company, moesifOptions)The metadata field can be any company demographic or other info you want to store.Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.UpdateCompaniesBatch MethodSimilar to UpdateCompany, but to update a list of companies in one batch.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,}// List of Companiesvar companies []*models.CompanyModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom mapmetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompanyA := models.CompanyModel{    CompanyId:     &quot;67890&quot;,    // The only required field is your company id    CompanyDomain: literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info     Campaign:      &amp;amp;campaign,    Metadata:      &amp;amp;metadata,}companies = append(companies, &amp;amp;companyA)// Update Companiesmoesifgin.UpdateCompaniesBatch(companies, moesifOptions)The metadata field can be any company demographic or other info you want to store.Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.Update SubscriptionUpdateSubscription MethodUse this method to create or update a subscription profile in Moesif.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,}// metadata can be any custom mapmetadata := map[string]interface{}{  &quot;plan_name&quot;: &quot;Pro&quot;,  &quot;deal_stage&quot;: &quot;Customer&quot;,  &quot;mrr&quot;: 48000,  &quot;demographics&quot;: map[string]interface{}{      &quot;subscription_length&quot;: 12,      &quot;subscription_type&quot;: &quot;annual&quot;,  },}// Prepare subscription modelsubscription := models.SubscriptionModel{    SubscriptionId: &quot;12345&quot;,    // Required subscription id    CompanyId:      &quot;67890&quot;,    // Required company id    Metadata:       &amp;amp;metadata,}// Update Subscriptionmoesifgin.UpdateSubscription(&amp;amp;subscription, moesifOptions)The metadata field can be any subscription demographic or other information you want to store.Only the SubscriptionId and CompanyId fields are required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.UpdateSubscriptionsBatch methodSimilar to UpdateSubscription, but to update a list of subscriptions in one batch.import (    &quot;github.com/moesif/moesifgin&quot;    &quot;github.com/moesif/moesifapi-go/models&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}moesifOptions := map[string]interface{} {    &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,}// List of Subscriptionsvar subscriptions []*models.SubscriptionModel// metadata can be any custom mapmetadata := map[string]interface{}{  &quot;plan_name&quot;: &quot;Pro&quot;,  &quot;deal_stage&quot;: &quot;Customer&quot;,  &quot;mrr&quot;: 48000,  &quot;demographics&quot;: map[string]interface{}{      &quot;subscription_length&quot;: 12,      &quot;subscription_type&quot;: &quot;annual&quot;,  },}// Prepare subscription modelsubscriptionA := models.SubscriptionModel{    SubscriptionId: &quot;12345&quot;,    // Required subscription id    CompanyId:      &quot;67890&quot;,    // Required company id    Metadata:       &amp;amp;metadata,}subscriptions = append(subscriptions, &amp;amp;subscriptionA)// Update Subscriptionsmoesifgin.UpdateSubscriptionsBatch(subscriptions, moesifOptions)The metadata field can be any subscription demographic or other information you want to store.Only the SubscriptionId and CompanyId fields are required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/gin/",
      "author": "Sakib",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-go": {
      "title": "Server Integration Guide - Go",
      "content"	 : "Moesif Middleware for Goby Moesif, the API analytics and API monetization platform.Moesif middleware for Go logs API calls and sends to Moesif for API analytics and log analysis. This middleware allows you to integrate Moesif’s API analytics and API monetization features into your Go applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareUse go get:go get github.com/moesif/moesifmiddleware-goIf you are using Go modules, you can specify a version number as well:go get github.com/moesif/moesifmiddleware-go@v1.2.3Configure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseThe following snippet shows how to use the middleware:import(    moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func handle(w http.ResponseWriter, r *http.Request) {// Your API Logic}var moesifOptions = map[string]interface{} {        &quot;Application_Id&quot;: &quot;YOUR_MOESIF_APPLICATION_ID&quot;,        &quot;Log_Body&quot;: true,}http.Handle(&quot;/api&quot;, moesifmiddleware.MoesifMiddleware(http.HandlerFunc(handle), moesifOption))Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Optional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third party services through the following method:moesifmiddleware.StartCaptureOutgoing(moesifOption)handler func(ResponseWriter, *Request) (Required)The handler function registers the handler function for the given pattern through the HandlerFunc adapter. See the example application code for better understanding.moesifOption (Required)A map[string]interface{} type containing the configuration options for your application. See the example application code for better understanding.See Configuration Options for the common configuration options. See Options for Logging Outgoing Calls for configuration options specific to capturing and logging outgoing API calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailConfiguration OptionsThe following sections describe the available configuration options for this middleware. You can set these options in the Moesif initialization options object. See the the example application code to understand how you can specify these options.Application_Id (Required)         Data type              string     A string that identifies your application in Moesif.Should_Skip         Data type          Parameters          Return type              Function          (request, response)          boolean     Optional.A function that takes a request and a response,and returns true if you want to skip this particular event.Identify_User         Data type          Parameters          Return type              Function          (request, response)          string     Optional, but highly recommended.A function that takes a request and a response, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.Identify_Company         Data type          Parameters          Return type              Function          (request, response)          string     Optional.A function that takes a request and response, and returns a string that represents the company ID for this event.Get_Metadata         Data type          Parameters          Return type              Function          (request, response)          dictionary     Optional.A function that returns an object that allows you to add custom metadata that will be associated with the event.The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.Get_Session_Token         Data type          Parameters          Return type              Function          (request, response)          string     Optional.A function that takes a request and response, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, provide this function to help identify sessions.Request_Header_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns an array of strings to mask specific request header fields.Request_Body_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns array of strings to mask specific request body fields.Response_Header_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns array of strings to mask specific response header fields.Response_Body_Masks         Data type          Parameters          Return type              Function          ()          []string     Optional.A function that returns array of strings to mask specific response body fields.Debug         Data type              boolean     Optional.Set to true to see debugging messages. This may help you troubleshoot integration issues.Log_Body         Data type          Default              boolean          true     Optional.Set to false to not log the request and response body to Moesif.Event_Queue_Size         Data type          Default              int          10000     An optional field name that specifies the maximum number of events to hold in queue before sending to Moesif. In case of network issues, the middleware may fail to connect to or send events to Moesif. For those scenarios, this option helps prevent adding new events to the queue to prevent memory overflow.Batch_Size         Data type          Default              int          200     An optional field name that specifies the maximum batch size when sending to Moesif.Timer_Wake_Up_Seconds         Data type          Default              int          2     An optional field that specifies a time in seconds how often background thread runs to send events to Moesif.Options for Logging Outgoing CallsThe following configuration options apply to outgoing API calls. The request and response objects passed in are Request and Response objects of the Go standard library.Should_Skip_Outgoing         Data type          Parameters          Return type              Function          (request, response)          boolean     Optional.A function that takes a request and response, and returns true if you want to skip this particular event.Identify_User_Outgoing         Data type          Parameters          Return type              Function          (request, response)          string     Optional, but highly recommended.A function that takes a request and a response, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.Identify_Company_Outgoing         Data type          Parameters          Return type              Function          (request, response)          string     Optional.A function that takes request and response, and returns a string that represents the company ID for this event.Get_Metadata_Outgoing         Data type          Parameters          Return type              Function          (request, response)          dictionary     Optional.A function that returns an object that allows you to add custom metadata that will be associated with the event.The metadata must be a dictionary that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.Get_Session_Token_Outgoing         Data type          Parameters          Return type              Function          (request, response)          string     Optional.A function that takes a request and response, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, provide this function to help identify sessions and replay them.Log_Body_Outgoing         Data type          Default              boolean          true     Optional.Set to false to not log the request and response body to Moesif.Examples  Example Go app that using this middleware  Example Go app using this middleware and Google Cloud Run functionsThe following examples demonstrate some common operations:  Updating a single user  Updating users in batch  Updating a single company  Updating companies in batch  Updating a single subscription  Updating subscriptions in batchUpdate UserUpdateUser MethodUse this method to create or update a user profile in Moesif.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,&quot;Log_Body&quot;: true,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduser := models.UserModel{  UserId:  &quot;12345&quot;,  CompanyId:  literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}// Update Usermoesifmiddleware.UpdateUser(&amp;amp;user, moesifOption)The metadata field can contain any user demographic or other information you want to store.Only the UserId field is required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.UpdateUsersBatch MethodSimilar to UpdateUser, but to update a list of users in one batch.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// List of Usersvar users []*models.UserModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;email&quot;: &quot;john@acmeinc.com&quot;,  &quot;first_name&quot;: &quot;John&quot;,  &quot;last_name&quot;: &quot;Doe&quot;,  &quot;title&quot;: &quot;Software Engineer&quot;,  &quot;sales_info&quot;: map[string]interface{}{      &quot;stage&quot;: &quot;Customer&quot;,      &quot;lifetime_value&quot;: 24000,      &quot;account_owner&quot;: &quot;mary@contoso.com&quot;,  },}// Only UserId is requireduserA := models.UserModel{  UserId:  &quot;12345&quot;,  CompanyId:  literalFieldValue(&quot;67890&quot;), // If set, associate user with a company object  Campaign:  &amp;amp;campaign,  Metadata:  &amp;amp;metadata,}users = append(users, &amp;amp;userA)// Update Usermoesifmiddleware.UpdateUsersBatch(users, moesifOption)The metadata field can contain any company demographic or other information you want to store.Only the UserId field is required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentationUpdate CompanyUpdateCompany MethodUse this method to create or update a company profile in Moesif.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompany := models.CompanyModel{CompanyId:  &quot;67890&quot;,// The only required field is your company idCompanyDomain:  literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info Campaign:   &amp;amp;campaign,Metadata:    &amp;amp;metadata,}// Update Companymoesifmiddleware.UpdateCompany(&amp;amp;company, moesifOption)The metadata field can be any company demographic or other info you want to store.Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.UpdateCompaniesBatch MethodSimilar to UpdateCompany, but to update a list of companies in one batch.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// List of Companiesvar companies []*models.CompanyModel// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign := models.CampaignModel {  UtmSource: literalFieldValue(&quot;google&quot;),  UtmMedium: literalFieldValue(&quot;cpc&quot;),   UtmCampaign: literalFieldValue(&quot;adwords&quot;),  UtmTerm: literalFieldValue(&quot;api+tooling&quot;),  UtmContent: literalFieldValue(&quot;landing&quot;),}  // metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;org_name&quot;: &quot;Acme, Inc&quot;,  &quot;plan_name&quot;: &quot;Free&quot;,  &quot;deal_stage&quot;: &quot;Lead&quot;,  &quot;mrr&quot;: 24000,  &quot;demographics&quot;: map[string]interface{}{      &quot;alexa_ranking&quot;: 500000,      &quot;employee_count&quot;: 47,  },}// Prepare company modelcompanyA := models.CompanyModel{CompanyId:  &quot;67890&quot;,// The only required field is your company idCompanyDomain:  literalFieldValue(&quot;acmeinc.com&quot;), // If domain is set, Moesif will enrich your profiles with publicly available info Campaign:   &amp;amp;campaign,Metadata:    &amp;amp;metadata,}companies = append(companies, &amp;amp;companyA)// Update Companiesmoesifmiddleware.UpdateCompaniesBatch(companies, moesifOption)The metadata field can be any company demographic or other info you want to store.Only the CompanyId field is required.This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.Update SubscriptionUpdateSubscription MethodUse this method to create or update a subscription profile in Moesif.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;plan_name&quot;: &quot;Pro&quot;,  &quot;deal_stage&quot;: &quot;Customer&quot;,  &quot;mrr&quot;: 48000,  &quot;demographics&quot;: map[string]interface{}{      &quot;subscription_length&quot;: 12,      &quot;subscription_type&quot;: &quot;annual&quot;,  },}// Prepare subscription modelsubscription := models.SubscriptionModel{SubscriptionId: &quot;12345&quot;,// Required subscription id  CompanyId: &quot;67890&quot;,       // Required company idMetadata: &amp;amp;metadata,}// Update Subscriptionmoesifmiddleware.UpdateSubscription(&amp;amp;subscription, moesifOptions)The metadata field can be any subscription demographic or other information you want to store.Only the SubscriptionId and CompanyId fields are required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.UpdateSubscriptionsBatch methodSimilar to UpdateSubscription, but to update a list of subscriptions in one batch.import (moesifmiddleware &quot;github.com/moesif/moesifmiddleware-go&quot;)func literalFieldValue(value string) *string {    return &amp;amp;value}var moesifOptions = map[string]interface{} {&quot;Application_Id&quot;: &quot;Your Moesif Application Id&quot;,}// List of Subscriptionsvar subscriptions []*models.SubscriptionModel// metadata can be any custom dictionarymetadata := map[string]interface{}{  &quot;plan_name&quot;: &quot;Pro&quot;,  &quot;deal_stage&quot;: &quot;Customer&quot;,  &quot;mrr&quot;: 48000,  &quot;demographics&quot;: map[string]interface{}{      &quot;subscription_length&quot;: 12,      &quot;subscription_type&quot;: &quot;annual&quot;,  },}// Prepare subscription modelsubscriptionA := models.SubscriptionModel{SubscriptionId: &quot;12345&quot;,// Required subscription id  CompanyId: &quot;67890&quot;,       // Required company idMetadata: &amp;amp;metadata,}subscriptions = append(subscriptions, &amp;amp;subscriptionA)// Update Subscriptionsmoesifmiddleware.UpdateSubscriptionsBatch(subscriptions, moesifOptions)The metadata field can be any subscription demographic or other information you want to store.Only the SubscriptionId and CompanyId fields are required.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/go/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-gravitee": {
      "title": "Server Integration Guide - gravitee.io",
      "content"	 : "Gravitee.io - Moesif IntegrationThis integration enables you to understand customer API usage and monetize your APIs by logging API traffic to Moesif API Monetization and Analytics. With Moesif, you can:  Analyze customer API usage  Get alerted of issues  Monetize APIs with usage-based billing  Enforce quotas and contract terms  Guide users with behavioral emailsHow to Install and Configure the Gravitee.io Integration with MoesifStep 1: Download the Moesif Plugin packages for Gravitee.ioDownload both of the custom plugins required for the integration: Download Plugin ZIPs  Moesif Gravitee Policy Plugin: Captures API event information from HTTP requests and responses. e.g. moesif-gravitee-policy-1.1.zip  Moesif Gravitee Resource Plugin: Sends captured API event data to Moesif for analytics and monitoring with efficient, non-blocking I/O. e.g.  moesif-gravitee-resource-1.1.zipStep 2: Install the Resource and PolicyLocate the Plugins Directory  You’ll need to add the plugin to the Management API and Gateway Gravitee servers  The default plugins directory is ${GRAVITEE_HOME}/plugins, but this can be modified in the gravitee.yaml file.  For example, in the reference installation containers in this repo, the Gateway and Management API plugins folders are located at:          /opt/graviteeio-management-api/plugins      /opt/graviteeio-gateway/plugins      You should see the default plugins in these directories already.Upload the Plugins  Do not unzip the downloaded Policy and Resource plugin ZIP files.  Ensure that the plugin files remain zipped and are both correctly copied in to the specified ${GRAVITEE_HOME}/plugins directories of both services.Gateway Server    opt/graviteeio-gateway/plugins/moesif-gravitee-policy-1.1.zip    opt/graviteeio-gateway/plugins/moesif-gravitee-resource-1.1.zipManagement API Server    /opt/graviteeio-management-api/plugins/moesif-gravitee-policy-1.1.zip    /opt/graviteeio-management-api/plugins/moesif-gravitee-resource-1.1.zipThis setup allows the Gravitee APIM to recognize and load the plugins upon restart.Step 3: Restart GraviteeAfter copying the plugin files, restart the Management API and Gateway services to load the new plugins.Step 4: Verify the Installation  Log in to the Gravitee Management Console:          Navigate to the Gravitee Management Console in your web browser.        Check Installed Plugins:          Go to the Plugins section and verify that the Policy and Resource plugins are listed and enabled.      ConfigurationStep 5: Configure the Resource Plugin  Add the Resource to an API:          Navigate to the API’s “Resources” tab in the Gravitee Management Console.      You should see the Moesif Resource plugin listed as an available resource. Add it to the API.        Configure Resource Settings:          Name the resource moesif-resource      Set Moesif Application ID (API access token). This is required.      Optional settings include:                  baseUrl (default: Moesif prod “https://api.moesif.net”) This is only for development testing and should not be configured for production use.          batchSize (default: 100) This is the maximum number of events to send in a batch.          batchWaitTime (default: 1000 ms) This is the maximum time to wait before sending a batch of events in milliseconds.          queueSize (default: 100000) This is the maximum number of events that can be queued in memory before dropping events.          concurrency (default: 1) This will be configurable in the future but is hard-coded to 1 for initial release.          debug (default: false) This enables very verbose logging of request and response payloads. This should not be enabled in production.                    Step 6: Configure the Policy Plugin  Add the Policy to an API:          In the Gravitee Management Console, navigate to the Organization -&amp;gt; Policies page.      Go to the “Design” tab and add the Policy to the request and response flow for the appropriate flow(s).        Configure Policy Settings:          Set the necessary configuration parameters for the Policy, such as event types to capture, logging levels, and any filters.      Configure the userIdHeader and companyIdHeader fields to specify which request headers to read in order to populate the user and company IDs in the Moesif API event.      UsageOnce the plugins are installed and configured, they will automatically start capturing and sending API event data to Moesif. You can log in to your Moesif account to view detailed analytics and monitoring data.TroubleshootingCheck Plugin Logs  Review the Gravitee logs for any errors related to the custom plugins. For enhanced logging, you can enable debug mode in the plugins as well as modify the gravity log configuration to increase the log level for these plugins specifically.  There is an example of this in the reference install logback.xmlVerify Configuration  Ensure Moesif API Application ID is in the resource and that:          The Moesif Resource is added to the API.      The Moesif Policy is added to the API’s request and response flow.      The Policy and Resource have been saved and deployed      SupportFor additional support, please contact Moesif",
      "url": " /server-integration/gravitee/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-okhttp": {
      "title": "Server Integration Guide - Java OkHttp",
      "content"	 : "Moesif Java OkHttp Interceptor SDK   Introductionmoesif-java-okhttp-interceptor is a Java OkHttp interceptor that logs outbound HTTP(s) calls and sends events to Moesif for API analytics and monitoring    .The SDK includes Java and Kotlin examples. It is implemented as a OkHttp Interceptorand can be used either as Application Interceptor  or Network Interceptor. It requires Moesif Application Id credentials to submit events to Moesif.With a single statement .addInterceptor(new MoesifOkHttp3Interceptor()) it can start capturing events.Source Code and samples on GitHubHow to installFor Maven users, add dependency to your pom.xml:&amp;lt;dependency&amp;gt;&amp;lt;groupId&amp;gt;com.moesif&amp;lt;/groupId&amp;gt;&amp;lt;artifactId&amp;gt;moesif-okhttp-interceptor&amp;lt;/artifactId&amp;gt;&amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt;&amp;lt;/dependency&amp;gt; For Gradle users, add to your project’s build.gradle file:repositories {    dependencies {         implementation &#39;com.moesif:moesif-okhttp-interceptor:1.2.0&#39;}How to useSet the Moesif Application Id environment variable. Alternatively, this key can also be directly passed using MoesifApiConnConfig.$ export MOESIF_APPLICATION_ID = &quot;Your Moesif App Id Here&quot;  Build the OkHttp client.The Moesif OkHttp Interceptor can be utilized for both types of OkHttp interceptors Link                   Application Interceptor                  Java      addInterceptor(new MoesifOkHttp3Interceptor())              Kotlin      addInterceptor(MoesifOkHttp3Interceptor())      For Network Interceptor, change addInterceptor to addNetworkInterceptorTo pass Moesif Application Id directly in lieu of setting as environment variable:Change MoesifOkHttp3Interceptor() to MoesifOkHttp3Interceptor(&quot;Your Moesif Application Id here&quot;) The Official OkHttp3 recipe for Synchronous Gethas been modified below.Example (Kotlin)$ export MOESIF_APPLICATION_ID = &quot;Your Moesif App Id Here&quot;  import com.moesif.sdk.okhttp3client.MoesifOkHttp3Interceptorval client = OkHttpClient.Builder() .addInterceptor(MoesifOkHttp3Interceptor()) // The only modification to official sample .build()val request = Request.Builder()   .url(&quot;https://publicobject.com/helloworld.txt&quot;) .build()  client.newCall(request).execute().use { response -&amp;gt;    if (!response.isSuccessful) throw IOException(&quot;Unexpected code $response&quot;)    for ((name, value) in response.headers) {    println(&quot;$name: $value&quot;)  }println(response.body!!.string())}Example (Java)$ export MOESIF_APPLICATION_ID = &quot;Your Moesif App Id Here&quot;  import com.moesif.sdk.okhttp3client.MoesifOkHttp3Interceptor;    private final OkHttpClient client = new OkHttpClient.Builder()   .addInterceptor(new MoesifOkHttp3Interceptor())  // The only modification to official sample .build();  public void run() throws Exception {   Request request = new Request.Builder()   .url(&quot;https://publicobject.com/helloworld.txt&quot;)   .build();   try (Response response = client.newCall(request).execute()) {   if (!response.isSuccessful()) throw new IOException(&quot;Unexpected code &quot; + response);   Headers responseHeaders = response.headers();   for (int i = 0; i &amp;lt; responseHeaders.size(); i++) {      System.out.println(responseHeaders.name(i) + &quot;: &quot; +  responseHeaders.value(i));   }   System.out.println(response.body().string());    }}  Obtaining your Moesif Application IdYour Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking Installation.Advanced Configuration optionsFiltering, masking and customizing events sent to MoesifBy default, all events are submitted, and no content is masked.This default behavior is captured in the default config file DefaultEventFilterConfig.javaThis behavior can be overwritten by creating a custom config class that implements IInterceptEventFilter.Here is a sample customized config file “MyCustomEventFilterConfig.java”public static class MyCustomEventFilterConfig implements IInterceptEventFilter{    @Override    public EventModel maskContent(EventModel eventModel) {        if (eventModel.getRequest().getIpAddress() == &quot;127.0.0.1&quot;)            eventModel.getRequest().setIpAddress(&quot;0.0.0.0&quot;);        return eventModel;    }    @Override    public boolean skip(Request request, Response response) {        return request.method() == &quot;DELETE&quot;;    }    @Override    public Optional&amp;lt;String&amp;gt; identifyUser(Request request, Response response) {        return Optional.of(&quot;customUser&quot;);    }    @Override    public Optional&amp;lt;String&amp;gt; identifyCompany(Request request, Response response) {        return Optional.of(&quot;customCompany&quot;);    }    @Override    public Optional&amp;lt;String&amp;gt; sessionToken(Request request, Response response) {        return Optional.of(&quot;customSessionToken&quot;);    }    @Override    public @Nullable Map&amp;lt;String, Object&amp;gt; getMetadata(Request request, Response response) {        Map&amp;lt;String, Object&amp;gt; customMetadata = new HashMap&amp;lt;String, Object&amp;gt;();        Map&amp;lt;String, Object&amp;gt; subObject = new HashMap&amp;lt;String, Object&amp;gt;();        subObject.put(&quot;destructive_method&quot;, request.method() == &quot;DELETE&quot;);        customMetadata.put(&quot;cost_center&quot;, &quot;a554411&quot;);        customMetadata.put(&quot;retention_months&quot;, 12);        customMetadata.put(&quot;method_detais&quot;, subObject);        return customMetadata;    }    @Override    public Optional&amp;lt;String&amp;gt; getApiVersion(Request request, Response response) {        return Optional.of(&quot;v-3.1415&quot;);    }}To use this custom config, update it prior to constructing the interceptorMoesifApiConnConfig cfg = new MoesifApiConnConfig();cfg.setEventFilterConfig(new MyCustomEventFilterConfig());cfg.setDebug(false);MoesifOkHttp3Interceptor interceptor = new MoesifOkHttp3Interceptor(cfg);Batch size of events submitted to MoesifBy default, events submitted asynchronously to Moesif are batched in sizes of 5 as configured in MoesifApiConnConfig.javaTo configure the batch size to any value greater than zero:int customSize = 20; // submit events in batch of size 20new MoesifOkHttp3Interceptor(customSize)ORMoesifApiConnConfig cfg = new MoesifApiConnConfig();cfg.setEventsBufferSize(customSize);new MoesifOkHttp3Interceptor(cfg);Per current implementation, the batch has to be full to send events. Minimum batch size is 1 - which will send individual events immediately. The buffered events are not modified based on aging of these events.Note that this events buffer is in memory. It is lost if the process is ended. It is emptied every time events are submitted to Moesif. Setting the buffer to be large can also increase memory consumption.The events are submitted asynchronously to Moesif. So if the program ends immediately after making an OkHttp request, the event may not have been submitted to Moesif even if the event buffer is size 1. In such case, adding a slight delay may help eg: TimeUnit.SECONDS.sleep(3);Credits:com.moesif.external.facebook.stetho.inspector.network contains code borrowed (and modified for Moesif) from Facebook/Stetho Official site | Code on GithubThank you Facebook/Stetho!Built for OkHttpOfficial Readme | Code on GithubThank you Square/OkHttp!",
      "url": " /server-integration/okhttp/",
      "author": "Akash",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-servlet": {
      "title": "Server Integration Guide - Java Servlet (Spring, Jersey)",
      "content"	 : "Moesif Servlet Integration Documentationby Moesif, the API analytics and API monetization platform.moesif-servlet is a Java servlet filter that logs incoming API calls and sends to Moesif for API analytics and monitoring.OverviewWe’ve implemented the SDK as a Javax servlet filterwithout importing framework specific dependencies. Any framework built on Java Servlet API such as Spring, Struts, and Jersey can use this SDK with minimal configuration.An identical implementation moesif-servlet-jakarta uses the newer Jakarta Servlet API. This implementation works with Java 17+ Tomcat 10 and Spring Boot 3.0. You can find its source code in the moesif-servlet-jakarta folder.PrerequisitesBefore using this SDK, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the SDKMaven UsersAdd the Moesif dependency to your project’s pom.xml file:&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;com.moesif.servlet&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;moesif-servlet&amp;lt;/artifactId&amp;gt;    &amp;lt;version&amp;gt;1.8.3&amp;lt;/version&amp;gt;&amp;lt;/dependency&amp;gt;&amp;lt;!-- OR for newer Jakarta--&amp;gt;&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;com.moesif.servlet&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;moesif-servlet-jakarta&amp;lt;/artifactId&amp;gt;    &amp;lt;version&amp;gt;2.2.3&amp;lt;/version&amp;gt;&amp;lt;/dependency&amp;gt;Gradle UsersAdd the Moesif dependency to your project’s build.gradle file:dependencies {       compile &#39;com.moesif.servlet:moesif-servlet:1.8.3&#39;}// OR for newer Jakartadependencies {       compile &#39;com.moesif.servlet:moesif-servlet-jakarta:2.2.3&#39;}How to UseDifferent Java web frameworks have different way of configuring servlet filters.The following sections describe the instructions for different frameworks:  Spring Boot  Spring MVC  Jersey Servlet  Spark Servlet  Generic Java Servlet  Spring Boot 3.x using Jakarta          Spring Boot 3.0 Jakarta with Tomcat      Spring Boot 3.2 Jakarta with Undertow      Spring BootIn your Spring configuration file, install the MoesifFilter object.import com.moesif.servlet.MoesifFilter;import javax.servlet.Filter;import org.springframework.web.servlet.config.annotation.*;import org.springframework.context.annotation.*;import org.springframework.http.converter.*;@Configurationpublic class MyConfig implements WebMvcConfigurer {  @Bean  public Filter moesifFilter() {    return new MoesifFilter(&quot;Your Moesif Application Id&quot;);  }}To customize the filter, pass in a object that implements MoesifConfiguration suchas MoesifConfigurationAdapter.@Configurationpublic class MyConfig implements WebMvcConfigurer {  MoesifConfiguration config = new MoesifConfigurationAdapter() {    @Override    public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {      return request.getHeader(&quot;Authorization&quot;);    }  };  @Bean  public Filter moesifFilter() {    return new MoesifFilter(&quot;Your Moesif Application Id&quot;, config);  }}For for more information about MoesifConfiguration, see the configuration options.Running the Spring Boot Starter ExampleTo run spring-boot-starter-example, make sure you have the following installed:  Java 8+  Maven version 3.0.x or above.You can check Maven version with the following command:mvn -vThen follow these steps:      Clone the repository    git clone https://github.com/Moesif/moesif-servletcd moesif-servlet            In the spring-boot-starter-example/src/main/java/com/moesif/servlet/spring/MyConfig.java file, specify your Moesif Application ID in the applicationId variable.        Compile:    cd spring-boot-starter-examplemvn clean install            Run:    java -jar target/spring-boot-starter-example*.jar        Alternatively:    mvn  spring-boot:run            Using Postman or cURL, make a few API calls to http://localhost:8080/api or the port that Spring Boot is running on.        Verify that the API calls log to your Moesif account web portal.  Spring MVC (Java Config)import com.moesif.servlet.MoesifFilter;import javax.servlet.Filter;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class MyWebInitializer extendsAbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Filter[] getServletFilters() {return new Filter[]{new MoesifFilter(&quot;Your Moesif Application Id&quot;)};}}Spring MVC (XML Config)In Spring MVC + XML configuration, you can register the filters using web.xml file:  &amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;com.moesif.servlet.MoesifFilter&amp;lt;/filter-class&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;application-id&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;Your Moesif Application Id&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;false&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;logBody&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;  &amp;lt;/filter&amp;gt;  &amp;lt;filter-mapping&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;  &amp;lt;/filter-mapping&amp;gt;You may have to override onStartup() to pass in the MoesifConfiguration object.Jersey ServletYou can run Jersey in multiple ways, as a Java servlet or embedded with a Java NIO framework like Grizzly. This subsection focuses on running Jersey as a servlet.Edit the web.xml file and add your Moesif Application ID.  &amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;com.moesif.servlet.MoesifFilter&amp;lt;/filter-class&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;application-id&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;Your Application Id&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;false&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;logBody&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;  &amp;lt;/filter&amp;gt;  &amp;lt;filter-mapping&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;  &amp;lt;/filter-mapping&amp;gt;Running the Jersey Servlet ExampleTo run jersey-servlet-example, make sure you have the following installed:  Java 8+  Maven version 3.0.x or above.You can check Maven version with the following command:mvn -vThen follow these steps:      Clone the repository:    git clone https://github.com/Moesif/moesif-servletcd moesif-servlet/            Edit the jersey-servlet-example/src/main/webapp/WEB-INF/web.xml file and add your Moesif Application ID.        Compile and run:    cd jersey-servlet-examplemvn clean installjava -jar target/dependency/webapp-runner.jar target/*.war            Go to http://localhost:8080/api/demo or the port that Tomcat is running on.  In your Moesif account web portal, you should see events logged and monitored.You can shut down the server manually by pressing Ctrl + C.Spark ServletYou can run Spark in multiple ways, as a Java servlet or embedded with a server like Jetty. This subsection focuses on running Spark as a servlet.Edit the web.xml file and add your Moesif Application ID.  &amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;com.moesif.servlet.MoesifFilter&amp;lt;/filter-class&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;application-id&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;Your Moesif Application Id&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;false&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;logBody&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;  &amp;lt;/filter&amp;gt;  &amp;lt;filter-mapping&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;  &amp;lt;/filter-mapping&amp;gt;Running the Spark Servlet ExampleTo run spark-servlet-example, make sure you have the following installed:  Java 8+  Maven version 3.0.x or above.You can check Maven version with the following command:mvn -vThen follow these steps:      Clone the repository:    git clone https://github.com/Moesif/moesif-servletcd moesif-servlet            Edit the spark-servlet-example/src/main/webapp/WEB-INF/web.xml file and add your Moesif Application ID there. In the spark-servlet-example/src/main/java/com/moesif/servlet/spark/example/SparkDemo.java file, add your Moesif Application ID as an argument to MoesifAPIClient object.        Compile and run:    cd spark-servlet-examplemvn clean installjava -jar target/dependency/webapp-runner.jar target/*.war            Go to http://localhost:8080/api/demo or the port that Tomcat is running on.  In your Moesif account web portal, you should see event logged and monitored.You can shut down the server manually by pressing Ctrl + C.Generic Java ServletEdit the web.xml file and add your Moesif Application ID.  &amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;com.moesif.servlet.MoesifFilter&amp;lt;/filter-class&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;application-id&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;Your Moesif Application Id&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;false&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;logBody&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;  &amp;lt;/filter&amp;gt;  &amp;lt;filter-mapping&amp;gt;    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;  &amp;lt;/filter-mapping&amp;gt;Running the Generic Servlet Exampleservlet-example implements the Servlet Filter directly in a generic servlet app rather than using a higher level framework like Spring MVC or Spring Boot.To run this example, make sure you have the following installed:  Java 8+  Maven version 3.0.x or above.You can check Maven version with the following command:mvn -vThen follow these steps:      Clone the repository:    git clone https://github.com/Moesif/moesif-servletcd moesif-servlet            Edit the servlet-example/src/main/webapp/WEB-INF/web.xml file and add your Moesif Application ID there.        Compile and run:    cd servlet-examplemvn clean installjava -jar target/dependency/webapp-runner.jar target/*.war            Go to http://localhost:8080/api/demo or the port that Tomcat is running on.  In your Moesif account web portal, you should see event logged and monitored.You can shut down the server manually by pressing Ctrl + C.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide. To print debug logs to help troubleshooting, follow the instructions in How to Print Debug Logs.Other troubleshooting supports:  FAQ  Moesif support emailHow to Print Debug LogsIf you need to print debugs logs, you can set the debug switch when initializing the MoesifFilter object.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, debug)If you are using XML configuration, you can set the debug switch like below:    &amp;lt;filter-name&amp;gt;MoesifFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;com.moesif.servlet.MoesifFilter&amp;lt;/filter-class&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;application-id&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;Your Moesif Application Id&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;    &amp;lt;init-param&amp;gt;      &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;      &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &amp;lt;/init-param&amp;gt;  &amp;lt;/filter&amp;gt;How to Test  Manually clone this repository.  Enter moesif-servlet and run mvn clean install -U -Dgpg.skip if you haven’t done so.  Add your own application id to src/test/java/com/moesif/servlet/MoesifServletTests.java. You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; Installation  From terminal/cmd navigate to the root directory of the moesif-servlet.  Invoke mvn -Dtest=MoesifServletTests test to run the tests.Configuration OptionsTo configure the filter, extend the MoesifConfigurationAdapter class to override a few configuration parametersor implement the entire MoesifConfiguration interface. Both will achieve similar results.ParametersOverride the following parameters, if needed.batchSize            Required      Type      Default Value      Description                  No      Number      100      The batch size of API events that triggers flushing of queue and sending the data to Moesif.      batchMaxTime            Required      Type      Default Value      Description                  No      Number (seconds)      2      The maximum wait time (approximately) before the SDK triggers flushing of the queue and sends data to Moesif.      queueSize| Required | Type | Default Value | Description || – | – | – | – || No | Number | 1000000 | Maximum queue capacity to hold events in memory. |retry| Required | Type | Default Value | Description || – | – | – | – || No | Number | 0 | Number of time to retry if the SDK fails to send data to Moesif. Set the value between 0 to 3. |updateConfigTime| Required | Type | Default Value | Description || – | – | – | – || No | Number (seconds) | 300 (seconds) | The maximum wait time (approximately) to pull the latest app configuration and update the cache. |logBody| Required | Type | Default Value | Description || – | – | – | – || No | boolean | true | Whether to log request and response body to Moesif. |requestMaxBodySize| Required | Type | Default Value | Description                                                                                  || – | – |—————|———————————————————————————————-|| No | Number | 1,048,576     | The maximum request body size in bytes to log when sending the data to Moesif. Default 1 MiB |responseMaxBodySize| Required | Type | Default Value | Description                                                                     || – | – |—————|———————————————————————————|| No | Number | 1,048,576     | The maximum response body size in bytes to log when sending the data to Moesif. Default 1 MiB |Interface MethodsThe MoesifConfiguration class provides several methods that you can override to customize its behavior or extract information from your requests/responses with custom logic.Overridable Methods  boolean skip (HttpServletRequest request, HttpServletResponse response)  String getApiVersion (HttpServletRequest request, HttpServletResponse response)  Object getMetadata (HttpServletRequest request, HttpServletResponse response)  String identifyUser (HttpServletRequest request, HttpServletResponse response)  String identifyCompany (HttpServletRequest request, HttpServletResponse response)  String getSessionToken (HttpServletRequest request, HttpServletResponse response)  EventModel maskContent (EventModel eventModel)Calling BehaviorThe above methods are called at different times during the processing of each HTTP request and response.On Request Only  skip, this is called first before the Moesif filter processes the request any further.  If true, the MoesifFilter immediately continues the request through the filter chain without logging or any further processing by Moesif.  getApiVersion, called on request onlyOn Request and On ResponseEach of the following interface methods is called twice per HTTP request/response cycle to expose information from the request, the response, or both, depending on your needs.  getMetadata  identifyUser  identifyCompany  getSessionToken  On Request: The method is called before the request is fully processed and there is no response yet, so the response HttpServletResponse parameter is always null for the first call.  On Response: The method is called a second time after the response is generated by your application. Both HttpServletRequest and HttpServletResponse are passed as parameters and non-null.Note: If you need to use these callbacks for governance features, such as transforming or blocking requests, the necessary information must be available in the request phase. This is because request governance operates before the response is generated.After Request/Response Processing  maskContent, is called twice but at each point, after all of the above methods are called, and this method gets the partial then the final Moesif Event model that would eventually be sent. This method allows you to remove sensitive data from the HTTP headers or body or inspect/change any Event property in general before sending to Moesifpublic boolean skip(HttpServletRequest request, HttpServletResponse response)Return true if you want to skip logging arequest to Moesif. For example, you may skip requests like health probes.  @Override  public boolean skip(HttpServletRequest request, HttpServletResponse response) {    // Skip logging health probes    return request.getRequestURI().contains(&quot;health/probe&quot;);  }2. public Object getMetadata(HttpServletRequest request, HttpServletResponse response)Return a Java Object that allows you to add custom metadata to the event like instanceId or traceId.The metadata must be a simple Java object that can be converted to JSON.public Object getMetadata(HttpRequest request, ClientHttpResponse response) {  Map&amp;lt;String, Object&amp;gt; customMetadata = new HashMap&amp;lt;String, Object&amp;gt;();  customMetadata.put(&quot;service_name&quot;, System.getProperty(&quot;app_name&quot;));  return customMetadata;}3. public String identifyUser(HttpServletRequest request, HttpServletResponse response)Highly recommended.Returns a user ID as a String. This enables Moesif to attribute API requests to individual users so you can understand who is calling your API.You can use this function simultaneously with identifyCompany() to track both individual customers and the companies that they are a part of.  @Override  public String identifyUser(HttpServletRequest request, HttpServletResponse response) {    if (request.getUserPrincipal() == null) {        return null;    }    return request.getUserPrincipal().getName();  }4. public String identifyCompany(HttpServletRequest request, HttpServletResponse response)Returns a company ID as a String.If you have a B2B business, this enables Moesif to attribute API requests to specific companies or organizations so you can understand which accounts are calling your API. You can use this function simultaneously with identifyUser() to track both individual customers and the companies they are a part of.  @Override  public String identifyCompany(HttpServletRequest request, HttpServletResponse response) {    return &quot;12345&quot;;  }5. public String getSessionToken(HttpServletRequest request, HttpServletResponse response)Moesif automatically detects the end user’s session token or API key, but you can manually define the token for finer control.  @Override  public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {    return request.getHeader(&quot;Authorization&quot;);  }The following example uses the session ID:  @Override  public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {    return request.getRequestedSessionId();  }6. public String getApiVersion(HttpServletRequest request, HttpServletResponse response)Returns a string to tag requests with a specific version of your API.  @Override  public String getApiVersion(HttpServletRequest request, HttpServletResponse response) {    return request.getHeader(&quot;X-Api-Version&quot;);  }7. public EventModel maskContent(EventModel eventModel)If you want to remove any sensitive data in the HTTP headers or body before sending to Moesif, use maskContent.Usage ExamplesFor the methods which are called once on request and again on response, here are the patterns we recommend for each use case of reading a value from the request only, reading a value from the response only, and logging values that require both request and response.1. Reading a Value from the Request OnlyIf you need to extract information that is available in the request, you can implement the method using only the request parameter.@Overridepublic String identifyUser(HttpServletRequest request, HttpServletResponse response) {    // Extract user ID from request header    return request.getHeader(&quot;X-User-Id&quot;);}In this example, the user ID is obtained from a custom request header. Since this information is available in the request, it can be accessed during both the request and response phases.2. Reading a Value from the Response OnlyIf the information you need is only available in the response, you can implement the method to check if the response is not null.@Overridepublic String identifyCompany(HttpServletRequest request, HttpServletResponse response) {    if (response != null) {        // Extract company ID from response header        return response.getHeader(&quot;X-Company-Id&quot;);    }    // Response not yet available, return null to set no value on request phase    return null;}In this example, the company ID is obtained from a response header. Since the response is null during the request phase, we return null in that case.3. Reading a Value Using Both Request and ResponseIf you need to use information from both the request and the response, you can implement the method accordingly.@Overridepublic Object getMetadata(HttpServletRequest request, HttpServletResponse response) {    Map&amp;lt;String, Object&amp;gt; metadata = new HashMap&amp;lt;&amp;gt;();    // Add request information to metadata up front in the event of an error response    metadata.put(&quot;value_id&quot;, request.getHeader(&quot;X-Value-Id&quot;));    if (response != null) {        // if you only need a request value when response is also available        int start = request.getIntHeader(&quot;X-Start-Value&quot;);        int end = response.getIntHeader(&quot;X-End-Value&quot;);        metadata.put(&quot;value_delta&quot;, end - start);    }    // The on request value is set first, then overwritten by the on response return value    // if a value is set on request, but null is returned on response, the on request value is retained and logged    return metadata;}In this example, we build a metadata object that includes information from both the request and the response. During the request phase, response is null, so only request information is read. During the response phase, both request and response information are read for the complete .Building moesif-servlet LocallyIf you are contributing to moesif-servlet, you can build it locally and install in local Maven Repo:cd moesif-servletmvn clean installExamplesThe following examples demonstrate how to add and update customer information.The methods these examples use are accessible through the Moesif Java API library that this SDK already imports as a dependency.Update a Single UserTo create or update a user profile in Moesif, use the updateUser() function.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemaCampaignModel campaign = new CampaignBuilder()        .utmSource(&quot;google&quot;)        .utmCampaign(&quot;cpc&quot;)        .utmMedium(&quot;adwords&quot;)        .utmTerm(&quot;api+tooling&quot;)        .utmContent(&quot;landing&quot;)        .build();// Only userId is required// metadata can be any custom objectUserModel user = new UserBuilder()    .userId(&quot;12345&quot;)    .companyId(&quot;67890&quot;) // If set, associate user with a company object    .campaign(campaign)    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +        &quot;&quot;first_name&quot;: &quot;John&quot;,&quot; +        &quot;&quot;last_name&quot;: &quot;Doe&quot;,&quot; +        &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +        &quot;&quot;sales_info&quot;: {&quot; +            &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +            &quot;&quot;lifetime_value&quot;: 24000,&quot; +            &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateUser(user);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Java API reference.Update Users in BatchTo update a list of users in one batch, use the updateUsersBatch() function. You can update users synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());List&amp;lt;UserModel&amp;gt; users = new ArrayList&amp;lt;UserModel&amp;gt;();UserModel userA = new UserBuilder()        .userId(&quot;12345&quot;)        .companyId(&quot;67890&quot;)        .campaign(campaign)        .metadata(APIHelper.deserialize(&quot;{&quot; +            &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +            &quot;&quot;first_name&quot;: &quot;John&quot;,&quot; +            &quot;&quot;last_name&quot;: &quot;Doe&quot;,&quot; +            &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +            &quot;&quot;sales_info&quot;: {&quot; +                &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +                &quot;&quot;lifetime_value&quot;: 24000,&quot; +                &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +              &quot;}&quot; +            &quot;}&quot;))        .build();users.add(userA);UserModel userB = new UserBuilder()        .userId(&quot;54321&quot;)        .companyId(&quot;67890&quot;)        .campaign(campaign)        .metadata(APIHelper.deserialize(&quot;{&quot; +            &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +            &quot;&quot;first_name&quot;: &quot;John&quot;,&quot; +            &quot;&quot;last_name&quot;: &quot;Doe&quot;,&quot; +            &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +            &quot;&quot;sales_info&quot;: {&quot; +                &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +                &quot;&quot;lifetime_value&quot;: 24000,&quot; +                &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +              &quot;}&quot; +            &quot;}&quot;))        .build();users.add(userB);filter.updateUsersBatch(users, callBack);The metadata field can contain any customer demographic or other info you want to store. MOesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation inMoesif Java API reference.Update a Single CompanyTo update a single company, use the updateCompany() function.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemaCampaignModel campaign = new CampaignBuilder()        .utmSource(&quot;google&quot;)        .utmCampaign(&quot;cpc&quot;)        .utmMedium(&quot;adwords&quot;)        .utmTerm(&quot;api+tooling&quot;)        .utmContent(&quot;landing&quot;)        .build();// Only companyId is required// metadata can be any custom objectCompanyModel company = new CompanyBuilder()    .companyId(&quot;67890&quot;)    .companyDomain(&quot;acmeinc.com&quot;) // If set, Moesif will enrich your profiles with publicly available info     .campaign(campaign)     .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;org_name&quot;: &quot;Acme, Inc&quot;,&quot; +        &quot;&quot;plan_name&quot;: &quot;Free&quot;,&quot; +        &quot;&quot;deal_stage&quot;: &quot;Lead&quot;,&quot; +        &quot;&quot;mrr&quot;: 24000,&quot; +        &quot;&quot;demographics&quot;: {&quot; +            &quot;&quot;alexa_ranking&quot;: 500000,&quot; +            &quot;&quot;employee_count&quot;: 47&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateCompany(company);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Java API reference.Update Companies in BatchTo update a list of companies in one batch, use the updateCompaniesBatch() function. You can update companies synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemaCampaignModel campaign = new CampaignBuilder()        .utmSource(&quot;google&quot;)        .utmCampaign(&quot;cpc&quot;)        .utmMedium(&quot;adwords&quot;)        .utmTerm(&quot;api+tooling&quot;)        .utmContent(&quot;landing&quot;)        .build();// Only companyId is required// metadata can be any custom objectCompanyModel company = new CompanyBuilder()    .companyId(&quot;67890&quot;)    .companyDomain(&quot;acmeinc.com&quot;) // If set, Moesif will enrich your profiles with publicly available info     .campaign(campaign)     .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;org_name&quot;: &quot;Acme, Inc&quot;,&quot; +        &quot;&quot;plan_name&quot;: &quot;Free&quot;,&quot; +        &quot;&quot;deal_stage&quot;: &quot;Lead&quot;,&quot; +        &quot;&quot;mrr&quot;: 24000,&quot; +        &quot;&quot;demographics&quot;: {&quot; +            &quot;&quot;alexa_ranking&quot;: 500000,&quot; +            &quot;&quot;employee_count&quot;: 47&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateCompaniesBatch(companies);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Java API reference.Update a Single SubscriptionTo create or update a subscription profile in Moesif, use the updateSubscription() function.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Only subscriptionId, companyId, and status are required// metadata can be any custom objectSubscriptionModel subscription = new SubscriptionBuilder()    .subscriptionId(&quot;sub_12345&quot;)    .companyId(&quot;67890&quot;)    .status(&quot;active&quot;)    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +        &quot;&quot;string_field&quot;: &quot;value_1&quot;,&quot; +        &quot;&quot;number_field&quot;: 0,&quot; +        &quot;&quot;object_field&quot;: {&quot; +        &quot;&quot;field_1&quot;: &quot;value_1&quot;,&quot; +        &quot;&quot;field_2&quot;: &quot;value_2&quot;&quot; +        &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateSubscription(subscription);The metadata field can store any subscription-related information you wish to keep. The subscription_id, company_id, and status fields are all required. This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Java API reference.Update Subscriptions in BatchTo update a list of subscriptions in one batch, use the updateSubscriptionsBatch() function.You can update subscriptions synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());List&amp;lt;SubscriptionModel&amp;gt; subscriptions = new ArrayList&amp;lt;&amp;gt;();subscriptions.add(new SubscriptionBuilder()    .subscriptionId(&quot;sub_12345&quot;)    .companyId(&quot;67890&quot;)    .status(&quot;active&quot;)    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +        &quot;&quot;string_field&quot;: &quot;value_1&quot;,&quot; +        &quot;&quot;number_field&quot;: 0,&quot; +        &quot;&quot;object_field&quot;: {&quot; +        &quot;&quot;field_1&quot;: &quot;value_1&quot;,&quot; +        &quot;&quot;field_2&quot;: &quot;value_2&quot;&quot; +        &quot;}&quot; +        &quot;}&quot;))    .build());// Add more subscriptions as neededfilter.updateSubscriptionsBatch(subscriptions);The subscription_id, company_id, and status fields are required for each subscription in the list. This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Java API reference.How to Get HelpIf you face any issues using Moesif Servlet SDK, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentationTrack Outgoing Calls to Third PartiesThis SDK captures API calls to your own API. If you want to track outgoing calls to third parties, see Moesif Spring Request SDK.",
      "url": " /server-integration/servlet/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-springrequest": {
      "title": "Server Integration Guide - Java Spring Request",
      "content"	 : "Moesif Spring Request SDKIntroductionmoesif-springrequest is a Java SDK for capturing outgoing API traffic and sending to Moesif for analysis.The SDK is implemented as a Spring Request Interceptor.For more info, visit Moesif’s Developer DocsHow to installMaven usersAdd the Moesif dependency to your project’s pom.xml file:&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;com.moesif.springrequest&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;moesif-springrequest&amp;lt;/artifactId&amp;gt;    &amp;lt;version&amp;gt;1.2.2&amp;lt;/version&amp;gt;&amp;lt;/dependency&amp;gt;Gradle usersAdd the Moesif dependency to your project’s build.gradle file:dependencies {       compile &#39;com.moesif.springrequest:moesif-springrequest:1.2.2&#39;}How to use1. Inject The Moesif InterceptorRestTemplate template = new RestTemplate();final List&amp;lt;ClientHttpRequestInterceptor&amp;gt; interceptors = new ArrayList&amp;lt;ClientHttpRequestInterceptor&amp;gt;();interceptors.add(new MoesifSpringRequestInterceptor(&quot;{{props.appId}}&quot;));template.setInterceptors(interceptors);2. Make HTTP requests using the same RestTemplatetemplate.exchange(  &quot;https://jsonplaceholder.typicode.com/posts&quot;,  HttpMethod.POST,  &quot;{&quot;id&quot;: &quot;1&quot;}&quot;,  String.class);Configuration optionsTo configure the filter, extend the MoesifRequestConfiguration class to override a few config params.1. public boolean skip(HttpRequest request, ClientHttpResponse response)Return true if you want to skip logging arequest to Moesif i.e. to skip boring requests like health probes.  @Override  public boolean skip(HttpRequest request, ClientHttpResponse response) {    // Skip logging health probes    return request.getURI().toString().contains(&quot;health/probe&quot;);  }2. public EventModel maskContent(EventModel eventModel)If you want to remove any sensitive data in the HTTP headers or body before sending to Moesif, you can do so with maskContent3. public String identifyUser(HttpRequest request, ClientHttpResponse response)Highly recommended. Even though Moesif automatically detects the end userId if possible, setting this configurationensures the highest accuracy with user attribution.  @Override  public String identifyUser(HttpRequest request, ClientHttpResponse response) {    return request.getHeaders().getFirst(&quot;user&quot;);  }4. public String identifyCompany(HttpRequest request, ClientHttpResponse response)You can set this configuration to add company Id to the event.  @Override  public String identifyCompany(HttpRequest request, ClientHttpResponse response) {    return &quot;12345&quot;;  }5. public String getSessionToken(HttpRequest request, ClientHttpResponse response)Moesif automatically detects the end user’s session token or API key, but you can manually define the token for finer control.  @Override  public String getSessionToken(HttpRequest request, ClientHttpResponse response) {    return request.getHeaders().getFirst(&quot;Authorization&quot;);  }6. public String getApiVersion(HttpRequest request, ClientHttpResponse response)You can optionally add an API versionto the event.  @Override  public String getApiVersion(HttpRequest request, ClientHttpResponse response) {    return request.getHeaders().getFirst(&quot;X-Api-Version&quot;);  }Building moesif-springrequest locallyIf you are contributing to moesif-springrequest, you can build it locally and install in local Maven Repo:cd moesif-springrequestmvn clean installEnable Debug MesssagesRequestConfig requestConfig = new RequestConfig();requestConfig.debug = true;interceptors.add(new MoesifSpringRequestInterceptor(  &quot;Enter your Moesif AppId here&quot;,  requestConfig));Disable Logging Request and Response BodyOptional, Default true. Set logBody flag to false to remove logging request and response body to Moesif.RequestConfig requestConfig = new RequestConfig();    // Set logBody flag to false to remove logging request and response body to MoesifrequestConfig.logBody = true;interceptors.add(new MoesifSpringRequestInterceptor(  &quot;Enter your Moesif AppId here&quot;,  requestConfig));Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/springrequest/",
      "author": "Matt",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-kong-api-gateway": {
      "title": "Server Integration Guide - Kong API Gateway",
      "content"	 : "Moesif Plugin for Kong GatewayOverviewThe Moesif plugin for Kong Gateway enables you to get powerful API analytics and observability directly within your Kong environment. It works by logging API traffic to Moesif API Analytics and Monetization platform.  Kong Gateway is an open-source API management platform.  Moesif is an API analytics and monetization service.With the Moesif plugin for Kong Konnect, you can:  Understand customer API usage  Get alerted on API consumption and issues  Monetize APIs with usage-based billing  Enforce quotas and limits  Guide customers using your APIsThe plugin is designed to log REST, GraphQL, XML/SOAP, and other API traffic without adding any latency. It supports both open-source and enterprise editions of Kong Gateway including Kong AI Gateway.Source Code on GitHubPackage on LuarocksHow to install  If you are using Kong’s Kubernetes Ingress Controller, review the docs for Kong Ingress. If you’re using Kong Konnect, review the docs for Kong KonnectThe .rock file is a self-contained package that can be installed locally or from a remote server.If the luarocks utility is installed in your system (this is likely the case if you used one of the official installation packages), you can install the ‘rock’ in your LuaRocks tree (a directory in which LuaRocks installs Lua modules).1. Install the Moesif pluginluarocks install --server=http://luarocks.org/manifests/moesif kong-plugin-moesif      Make sure the unzip package is installed on your machine.    For example when using the apt package manager, run apt-get update; apt-get install curl vim unzip.    Make sure the lua-zlib lib dependencies (git, zlib1g-dev, gcc) have been installed on the system.    For example when using the apt package manager, run apt-get update; apt-get install git zlib1g-dev gcc.  2. Update your loaded plugins listIn your kong.conf, append moesif to the plugins field (or custom_plugins if old version of Kong). Make sure the field is not commented out.plugins = bundled,moesif         # Comma-separated list of plugins this node                                 # should load. By default, only plugins                                 # bundled in official distributions are                                 # loaded via the `bundled` keyword.If you don’t have a kong.conf, create one from the default using the following command: cp /etc/kong/kong.conf.default /etc/kong/kong.conf3. Restart KongAfter the luarock is installed, restart Kong before enabling the pluginkong restart4. Enable the Moesif plugincurl -i -X POST --url http://localhost:8001/plugins/ --data &quot;name=moesif&quot; --data &quot;config.application_id=YOUR_APPLICATION_ID&quot;;5. Restart Kong againIf you don’t see any logs in Moesif, you may need to restart Kong again.kong restartHow to useHow to configure Kong Moesif plugin:Terminology  plugin: a plugin executing actions inside Kong before or after a request has been proxied to the upstream API.  Service: the Kong entity representing an external upstream API or microservice.  Route: the Kong entity representing a way to map downstream requests to upstream services.  Consumer: the Kong entity representing a developer or machine using the API. When using Kong, a Consumer only communicates with Kong which proxies every call to the said upstream API.  Credential: a unique string associated with a Consumer, also referred to as an API key.upstream service: this refers to your own API/service sitting behind Kong, to which client requests are forwarded.  API: a legacy entity used to represent your upstream services. Deprecated in favor of Services since CE 0.13.0 and EE 0.32.Enabling the plugin GloballyA plugin which is not associated to any Service, Route or Consumer (or API, if you are using an older version of Kong) is considered “global”,and will be run on every request. Read the Plugin Reference and thePlugin Precedence sections for more information.curl -X POST http://localhost:8001/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps or by going to API keys section within Moesif settings.Enabling the plugin on a ServiceConfigure this plugin on a Service by making the following request on your Kong server:curl -X POST http://localhost:8001/services/{service}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys  service: the id or name of the Service that this plugin configuration will target.Enabling the plugin on a RouteConfigure this plugin on a Route with:curl -X POST http://localhost:8001/routes/{route_id}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys.  route_id: the id of the Route that this plugin configuration will target.Enabling the plugin on a ConsumerYou can use the http://localhost:8001/plugins endpoint to enable this plugin on specific Consumers:curl -X POST http://localhost:8001/plugins     --data &quot;name=moesif&quot;     --data &quot;consumer_id={consumer_id}&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys.  consumer_id: the id of the Consumer we want to associate with this plugin.You can combine consumer_id and service_id in the same request, to furthermore narrow the scope of the plugin.Enabling the plugin on an APIIf you are using an older version of Kong with the legacy API entity(deprecated in favor of Services since CE 0.13.0 and EE 0.32.),you can configure this plugin on top of such an API by making the following request:curl -X POST http://localhost:8001/apis/{api}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;ParametersThe Moesif Kong Plugin has a variety of options for things like data scrubbing and tweaking performance.            Parameter      Default(Kong gateway 1.x, 2.x)      Default(Kong gateway 3.x onwards)      Description                  name                    The name of the plugin to use, in this case moesif              service_id                    The id of the Service which this plugin will target.              route_id                    The id of the Route which this plugin will target.              enabled      true      true      Whether this plugin will be applied.              consumer_id                    The id of the Consumer which this plugin will target.              api_id                    The id of the API which this plugin will target. Note: The API Entity is deprecated in favor of Services since CE 0.13.0 and EE 0.32.              config.application_id                    The Moesif application token provided to you by Moesif.              config.api_endpoint      https://api.moesif.net      https://api.moesif.net      URL for the Moesif API.              config.timeout (deprecated)      1000      1000      Timeout in milliseconds when connecting/sending data to Moesif.              config.connect_timeout      1000      1000      Timeout in milliseconds when connecting to Moesif.              config.send_timeout      5000      5000      Timeout in milliseconds when sending data to Moesif.              config.keepalive      5000      5000      Value in milliseconds that defines for how long an idle connection will live before being closed.              config.api_version      1.0      1.0      API Version you want to tag this request with.              config.disable_capture_request_body      false      false      Disable logging of request body.              config.disable_capture_response_body      false      false      Disable logging of response body.              config.request_header_masks      {}      {}      An array of request header fields to mask.              config.request_body_masks      {}      {}      An array of request body fields to mask.              config.response_header_masks      {}      {}      An array of response header fields to mask.              config.response_body_masks      {}      {}      An array of response body fields to mask.              config.batch_size      50      50      Maximum batch size when sending to Moesif.              config.user_id_header      ’’      nil      Request or response header to use for identifying the User. See identifying users.              config.company_id_header      ’’      nil      Request or response header to use for identifying the Company. See identifying companies.              config.authorization_header_name      authorization      authorization      Request header containing a Bearer or Basic token to extract user id. See identifying users. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.              config.authorization_user_id_field      sub      sub      Field name in JWT/OpenId token’s payload for identifying users. Only applicable if authorization_header_name is set and is a Bearer token. See identifying users.              config.authorization_company_id_field      ’’      nil      Field name in JWT/OpenId token’s payload for identifying companies. Only applicable if authorization_header_name is set and is a Bearer token. See identifying companies.              config.disable_gzip_payload_decompression      false      false      If set to true, will disable decompressing body in Kong.              config.max_callback_time_spent      750      750      Limiter on how much time to send events to Moesif per worker cycle.              config.request_max_body_size_limit      100000      100000      Maximum request body size in bytes to log.              config.response_max_body_size_limit      100000      100000      Maximum response body size in bytes to log.              config.request_query_masks      {}      {}      An array of query string params fields to mask.              config.event_queue_size      100000      100000      Maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new to event to queue to prevent memory overflow.              config.debug      false      false      If set to true, prints internal log messages for debugging integration issues.              enable_compression      false      If set to true, requests are compressed before sending to Moesif.             Updating Plugin VersionTo automatically upgrade to the latest version of the plugin, run the following command:luarocks install --server=http://luarocks.org/manifests/moesif kong-plugin-moesifTo upgrade to a specific version, run the following command:luarocks install --server=http://luarocks.org/manifests/moesif kong-plugin-moesif 2.0.2Restart KongAfter upgrading the plugin, restart Kong to load the new version of the plugin.kong restartUpdating Plugin ConfigurationIf you need to update a configuration parameter, you must fetch and update the existing plugin instance.Be careful not to call POST http://localhost:8001/plugins/ again as this will create a duplicate instance of a plugin, which Kong does not support.To update plugin config:1. Retrieve the plugin instance idUsing the GET /plugins, get the current instance id of the Moesif plugin.curl -X GET http://localhost:8001/plugins/2. Update the plugin instanceUse the plugin id from the previous step, update the plugin with desired configuration using PATCH /plugins/{plugin id}curl -X PATCH http://localhost:8001/plugins/{plugin id}     --data “config.application_id=YOUR_APPLICATION_ID”     --data “config.debug=true&quot;Identifying usersThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey.The default algorithm covers most authorization designs and works as follows:  If the config.user_id_header option is set, read the value from the specified HTTP header key config.user_id_header.  Else if Kong defined a value for x-consumer-custom-id, x-consumer-username, or x-consumer-id (in that order), use that value.  Else if an authorization token is present in config.authorization_header_name, parse the user id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_user_id_field (by default is sub).      If header contains Basic, base64 decode the string and use the username portion (before the : character).      For advanced configurations, you can define a custom header containing the user id via config.user_id_header or override the options config.authorization_header_name and config.authorization_user_id_field.Identifying companiesYou can associate API users to companies for tracking account-level usage. This can be done either:  Defining config.company_id_header, Moesif will use the value present in that header.  Use the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.  Else if an authorization token is present in config.authorization_header_name, parse the company id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_company_id_field (by default is ``).      TroubleshootingDuplicate key for moesif when enabling pluginKong only allows a single instance of a plugin enabled. This error message is shown when you already have Moesif enabled and trying to install a new instance of it.If you’re trying to update the config for Moesif, you need to update the existing instance by following these instructions.How to print debug logsIf you want to print Moesif debug logs, you can set --data “config.debug=true&quot; when you enable the plugin.If you already have Moesif installed, you must update the configuration of the existing instance and not install Moesif twice.Otherwise, you will have multiple instances of a plugin installed, which Kong does not support.To update existing plugin with debug option:1. Retrieve the plugin instance idUsing the GET /plugins, get the current instance id of the running Moesif plugin.curl -X GET http://localhost:8001/plugins/2. Update the plugin instanceUse the plugin id from the previous step, update the plugin with your new configuration using PATCH /plugins/{plugin id}. In this case, ensure --data “config.debug=true&quot;curl -X PATCH http://localhost:8001/plugins/{plugin id}     --data “config.application_id=YOUR_APPLICATION_ID”     --data “config.debug=true&quot;You should also set log_level to debug in /etc/kong/kong.conf.  If you need technical support from Moesif, attaching debug logs with your email to support can help shorten our resolution time.No events logged to MoesifYou may have the plugin enabled twice for the same scope (global, service, route, etc), which Kong does not support.Make sure you remove all instances of the Moesif plugin and re-enable it only once. To confirm if you are running into duplicate instances, you may see this in your Kong logs:init.lua:394: insert(): ERROR: duplicate key value violates unique constraint &quot;plugins_cache_key_key&quot;Key (cache_key)=(plugins:moesif::::) already exists., client: 127.0.0.1, server: kong_admin, request: &quot;POST /plugins/ HTTP/1.1&quot;, host: &quot;localhost:8001&quot;Another reason plugin may not be running is if you didn’t restart Kong after enabling the plugin. Make sure you restart your Kong instance.Kong Gateway fails to recognize customer_id as user_id for each API callIf you’re using Kong Gateway with Moesif and having trouble linking the customer_id to user_id for API calls, it’s likely related to authentication plugin configuration. Make sure you have the appropriate auth plugin enabled in Kong.API keys must be correctly utilized, and it’s important to note that API calls are only identified as linked to a user if the route is a protected one. If you’ve already sent requests using an API key generated via Kong but can’t see them automatically linked to the customer ID, check your auth plugin settings.Warning: Failed searching manifest when installing pluginWhen installing the plugin you may encounter the following warning:Warning: Failed searching manifest: Failed extracting manifest file: &#39;unzip -n&#39; program not found. Make sure unzip is installed and is available in your PATH (or you may want to edit the &#39;variables.UNZIP&#39; value in file &#39;/usr/local/etc/luarocks/config-5.1.lua&#39;)Warning: Failed searching manifest: Failed extracting manifest file: &#39;unzip -n&#39; program not found. Make sure unzip is installed and is available in your PATH (or you may want to edit the &#39;variables.UNZIP&#39; value in file &#39;/usr/local/etc/luarocks/config-5.1.lua&#39;)Error: No results matching query were found for Lua 5.1.To check if it is available for other Lua versions, use --check-lua-versions.`You may be missing certain packages that are required to install the plugin. To remedy this, make sure the unzip package is installed on your machine. For example, when using the apt package manager, run the following command:apt-get update; apt-get install curl vim unzipSSL certificate error: unable to get local issuer certificateIf you see an error similar to this in your Kong data plane logs after otherwise successful plugin configuration, but data is not being logged to Moesif:[error] 2430#0: *4473 [lua] log.lua:54: prepare_request(): [moesif] failed to send request: 20: unable to get local issuer certificate, context: ngx.timerThis error indicates that the Kong data plane cannot verify SSL certificates when connecting to the Moesif API. Follow these steps to resolve the issue:      Verify system SSL certificates are present: First, confirm that the Kong pods have access to system base SSL certificates. You can test this by running the following command inside the data plane pod containers:    curl https://api.moesif.net        If this command fails, the system SSL certificates are missing and need to be installed in the container.        Configure Kong to use system SSL certificates: Ensure that the lua_ssl_trusted_certificate config for your Kong data plane pods includes the value system to use system-wide SSL certificates. In Helm chart values, this is configured as env.lua_ssl_trusted_certificate with a value of or including system.    Reference: lua_ssl_trusted_certificate documentation    After updating this configuration, restart your Kong data plane pods for the changes to take effect.  Tested VersionFor tested versions, see this page on Kong docs.Examples  View example Dockerfile.Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/kong-api-gateway/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-kong-ingress-controller": {
      "title": "Server Integration Guide - Kong Ingress Controller",
      "content"	 : "Moesif Plugin for Kong Ingress ControllerOverviewThe Moesif plugin for Kong Ingress Controller enables you to get powerful API analytics and observability directly within your Kong environment. It works by logging API traffic to Moesif API Analytics and Monetization platform.  Kong Ingress Controller is a kubernetes native API gateway and AI gateway.  Moesif is an API analytics and monetization service.With the Moesif plugin for Kong Konnect, you can:  Understand customer API usage  Get alerted on API consumption and issues  Monetize APIs with usage-based billing  Enforce quotas and limits  Guide customers using your APIsThe plugin is designed to log REST, GraphQL, XML/SOAP, and other API traffic without adding any latency. It supports both open-source and enterprise editions of Kong Ingress Controller.Source Code on GitHubPackage on LuarocksHow to InstallPrerequisite      Make sure the lua-zlib lib dependencies (git, zlib1g-dev, gcc) have been installed on the system.    For example when using the apt package manager, run apt-get update; apt-get install git zlib1g-dev gcc.  Create a ConfigMap with the Moesif Plugin CodeYou’ll need to clone the kong-moesif-plugin and navigate to the kong/plugins directory to create a configMap usingkubectl create configmap kong-plugin-moesif --from-file=moesif -n kongPlease ensure that this is created in the same namespace as the one in which Kong is going to be installed.Add Kong ChartPlease Note that this section assumes that you’ve helm kong chart available, if not please add kong helm chart. If you already have helm kong chart available, please skip this step.You’ll need to add the kong chart and update the repo via Helm.# Add kong chart helm repo add kong https://charts.konghq.com# Update helm repohelm repo updateLoad Moesif PluginWith Helm, you could load the Moesif plugin by adding the following values to your values.yaml file:# values.yamlplugins:  configMaps:  - name: kong-plugin-moesif    pluginName: moesifDeploy the Kubernetes Ingress ControllerYou’ll need to patch the kong ingress controller deployment with the Moesif plugin and rollout the deployment.helm upgrade kong kong/kong --namespace kong --values values.yamlEnabling the plugin GloballyCreate a global-plugin.yaml fileapiVersion: configuration.konghq.com/v1kind: KongClusterPluginmetadata:  name: moesif  annotations:    kubernetes.io/ingress.class: kong  labels:    global: &quot;true&quot;config:  application_id: Your Moesif Application Id  debug: falseplugin: moesifand then apply the plugin globally.kubectl  apply -f global-plugin.yamlYour Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps or by going to API keys section within Moesif settings.Please note that setting the label global to “true” will apply the plugin globally in Kong, meaning it will be executed for every request that is proxied via Kong.Please ensure that this is created in the same namespace as the one in which Kong is installed. If your namespace is different from kong, you should change this command accordingly.How to useHow to configure Kong Moesif plugin:Terminology  plugin: a plugin executing actions inside Kong before or after a request has been proxied to the upstream API.  Service: the Kong entity representing an external upstream API or microservice.  Route: the Kong entity representing a way to map downstream requests to upstream services.  Consumer: the Kong entity representing a developer or machine using the API. When using Kong, a Consumer only communicates with Kong which proxies every call to the said upstream API.  Credential: a unique string associated with a Consumer, also referred to as an API key.upstream service: this refers to your own API/service sitting behind Kong, to which client requests are forwarded.  API: a legacy entity used to represent your upstream services. Deprecated in favor of Services since CE 0.13.0 and EE 0.32.Enabling the plugin GloballyA plugin which is not associated to any Service, Route or Consumer (or API, if you are using an older version of Kong) is considered “global”,and will be run on every request. Read the Plugin Reference and thePlugin Precedence sections for more information.curl -X POST http://localhost:8001/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking API Keys.Enabling the plugin on a ServiceConfigure this plugin on a Service by making the following request on your Kong server:curl -X POST http://localhost:8001/services/{service}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys  service: the id or name of the Service that this plugin configuration will target.Enabling the plugin on a RouteConfigure this plugin on a Route with:curl -X POST http://localhost:8001/routes/{route_id}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys.  route_id: the id of the Route that this plugin configuration will target.Enabling the plugin on a ConsumerYou can use the http://localhost:8001/plugins endpoint to enable this plugin on specific Consumers:curl -X POST http://localhost:8001/plugins     --data &quot;name=moesif&quot;     --data &quot;consumer_id={consumer_id}&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;  config.application_id: You can find your Moesif Application Id from Moesif Dashboard -&amp;gt; Top Right Menu -&amp;gt; API Keys.  consumer_id: the id of the Consumer we want to associate with this plugin.You can combine consumer_id and service_id in the same request, to furthermore narrow the scope of the plugin.Enabling the plugin on an APIIf you are using an older version of Kong with the legacy API entity(deprecated in favor of Services since CE 0.13.0 and EE 0.32.),you can configure this plugin on top of such an API by making the following request:curl -X POST http://localhost:8001/apis/{api}/plugins     --data &quot;name=moesif&quot;      --data &quot;config.application_id=MY_MOESIF_APPLICATION_ID&quot;ParametersThe Moesif Kong Plugin has a variety of options for things like data scrubbing and tweaking performance.            Parameter      Default(Kong gateway 1.x, 2.x)      Default(Kong gateway 3.x onwards)      Description                  name                    The name of the plugin to use, in this case moesif              service_id                    The id of the Service which this plugin will target.              route_id                    The id of the Route which this plugin will target.              enabled      true      true      Whether this plugin will be applied.              consumer_id                    The id of the Consumer which this plugin will target.              api_id                    The id of the API which this plugin will target. Note: The API Entity is deprecated in favor of Services since CE 0.13.0 and EE 0.32.              config.application_id                    The Moesif application token provided to you by Moesif.              config.api_endpoint      https://api.moesif.net      https://api.moesif.net      URL for the Moesif API.              config.timeout (deprecated)      1000      1000      Timeout in milliseconds when connecting/sending data to Moesif.              config.connect_timeout      1000      1000      Timeout in milliseconds when connecting to Moesif.              config.send_timeout      5000      5000      Timeout in milliseconds when sending data to Moesif.              config.keepalive      5000      5000      Value in milliseconds that defines for how long an idle connection will live before being closed.              config.api_version      1.0      1.0      API Version you want to tag this request with.              config.disable_capture_request_body      false      false      Disable logging of request body.              config.disable_capture_response_body      false      false      Disable logging of response body.              config.request_header_masks      {}      {}      An array of request header fields to mask.              config.request_body_masks      {}      {}      An array of request body fields to mask.              config.response_header_masks      {}      {}      An array of response header fields to mask.              config.response_body_masks      {}      {}      An array of response body fields to mask.              config.batch_size      50      50      Maximum batch size when sending to Moesif.              config.user_id_header      ’’      nil      Request or response header to use for identifying the User. See identifying users.              config.company_id_header      ’’      nil      Request or response header to use for identifying the Company. See identifying companies.              config.authorization_header_name      authorization      authorization      Request header containing a Bearer or Basic token to extract user id. See identifying users. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.              config.authorization_user_id_field      sub      sub      Field name in JWT/OpenId token’s payload for identifying users. Only applicable if authorization_header_name is set and is a Bearer token. See identifying users.              config.authorization_company_id_field      ’’      nil      Field name in JWT/OpenId token’s payload for identifying companies. Only applicable if authorization_header_name is set and is a Bearer token. See identifying companies.              config.disable_gzip_payload_decompression      false      false      If set to true, will disable decompressing body in Kong.              config.max_callback_time_spent      750      750      Limiter on how much time to send events to Moesif per worker cycle.              config.request_max_body_size_limit      100000      100000      Maximum request body size in bytes to log.              config.response_max_body_size_limit      100000      100000      Maximum response body size in bytes to log.              config.request_query_masks      {}      {}      An array of query string params fields to mask.              config.event_queue_size      100000      100000      Maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new to event to queue to prevent memory overflow.              config.debug      false      false      If set to true, prints internal log messages for debugging integration issues.              enable_compression      false      If set to true, requests are compressed before sending to Moesif.             Updating Plugin VersionTo automatically upgrade to the latest version of the plugin, run the following command:luarocks install --server=http://luarocks.org/manifests/moesif kong-plugin-moesifTo upgrade to a specific version, run the following command:luarocks install --server=http://luarocks.org/manifests/moesif kong-plugin-moesif 2.0.2Restart KongAfter upgrading the plugin, restart Kong to load the new version of the plugin.kong restartUpdating Plugin ConfigurationIf you need to update a configuration parameter, you must fetch and update the existing plugin instance.Be careful not to call POST http://localhost:8001/plugins/ again as this will create a duplicate instance of a plugin, which Kong does not support.To update plugin config:1. Retrieve the plugin instance idUsing the GET /plugins, get the current instance id of the Moesif plugin.curl -X GET http://localhost:8001/plugins/2. Update the plugin instanceUse the plugin id from the previous step, update the plugin with desired configuration using PATCH /plugins/{plugin id}curl -X PATCH http://localhost:8001/plugins/{plugin id}     --data “config.application_id=YOUR_APPLICATION_ID”     --data “config.debug=true&quot;Identifying usersThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey.The default algorithm covers most authorization designs and works as follows:  If the config.user_id_header option is set, read the value from the specified HTTP header key config.user_id_header.  Else if Kong defined a value for x-consumer-custom-id, x-consumer-username, or x-consumer-id (in that order), use that value.  Else if an authorization token is present in config.authorization_header_name, parse the user id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_user_id_field (by default is sub).      If header contains Basic, base64 decode the string and use the username portion (before the : character).      For advanced configurations, you can define a custom header containing the user id via config.user_id_header or override the options config.authorization_header_name and config.authorization_user_id_field.Identifying companiesYou can associate API users to companies for tracking account-level usage. This can be done either:  Defining config.company_id_header, Moesif will use the value present in that header.  Use the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.  Else if an authorization token is present in config.authorization_header_name, parse the company id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_company_id_field (by default is ``).      TroubleshootingDuplicate key for moesif when enabling pluginKong only allows a single instance of a plugin enabled. This error message is shown when you already have Moesif enabled and trying to install a new instance of it.If you’re trying to update the config for Moesif, you need to update the existing instance by following these instructions.How to print debug logsIf you want to print Moesif debug logs, you can set --data “config.debug=true&quot; when you enable the plugin.If you already have Moesif installed, you must update the configuration of the existing instance and not install Moesif twice.Otherwise, you will have multiple instances of a plugin installed, which Kong does not support.To update existing plugin with debug option:1. Retrieve the plugin instance idUsing the GET /plugins, get the current instance id of the running Moesif plugin.curl -X GET http://localhost:8001/plugins/2. Update the plugin instanceUse the plugin id from the previous step, update the plugin with your new configuration using PATCH /plugins/{plugin id}. In this case, ensure --data “config.debug=true&quot;curl -X PATCH http://localhost:8001/plugins/{plugin id}     --data “config.application_id=YOUR_APPLICATION_ID”     --data “config.debug=true&quot;You should also set log_level to debug in /etc/kong/kong.conf.  If you need technical support from Moesif, attaching debug logs with your email to support can help shorten our resolution time.No events logged to MoesifYou may have the plugin enabled twice for the same scope (global, service, route, etc), which Kong does not support.Make sure you remove all instances of the Moesif plugin and re-enable it only once. To confirm if you are running into duplicate instances, you may see this in your Kong logs:init.lua:394: insert(): ERROR: duplicate key value violates unique constraint &quot;plugins_cache_key_key&quot;Key (cache_key)=(plugins:moesif::::) already exists., client: 127.0.0.1, server: kong_admin, request: &quot;POST /plugins/ HTTP/1.1&quot;, host: &quot;localhost:8001&quot;Another reason plugin may not be running is if you didn’t restart Kong after enabling the plugin. Make sure you restart your Kong instance.Kong Gateway fails to recognize customer_id as user_id for each API callIf you’re using Kong Gateway with Moesif and having trouble linking the customer_id to user_id for API calls, it’s likely related to authentication plugin configuration. Make sure you have the appropriate auth plugin enabled in Kong.API keys must be correctly utilized, and it’s important to note that API calls are only identified as linked to a user if the route is a protected one. If you’ve already sent requests using an API key generated via Kong but can’t see them automatically linked to the customer ID, check your auth plugin settings.Warning: Failed searching manifest when installing pluginWhen installing the plugin you may encounter the following warning:Warning: Failed searching manifest: Failed extracting manifest file: &#39;unzip -n&#39; program not found. Make sure unzip is installed and is available in your PATH (or you may want to edit the &#39;variables.UNZIP&#39; value in file &#39;/usr/local/etc/luarocks/config-5.1.lua&#39;)Warning: Failed searching manifest: Failed extracting manifest file: &#39;unzip -n&#39; program not found. Make sure unzip is installed and is available in your PATH (or you may want to edit the &#39;variables.UNZIP&#39; value in file &#39;/usr/local/etc/luarocks/config-5.1.lua&#39;)Error: No results matching query were found for Lua 5.1.To check if it is available for other Lua versions, use --check-lua-versions.`You may be missing certain packages that are required to install the plugin. To remedy this, make sure the unzip package is installed on your machine. For example, when using the apt package manager, run the following command:apt-get update; apt-get install curl vim unzipTested VersionFor tested versions, see this page on Kong docs.Examples  View example Dockerfile.Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/kong-ingress-controller/",
      "author": "Keyur",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-kong-konnect": {
      "title": "Server Integration Guide - Kong Konnect",
      "content"	 : "Moesif Plugin for Kong KonnectOverviewThe Moesif plugin for Kong Konnect enables you to get powerful API analytics and observability directly within your Kong environment. It works by logging API traffic to Moesif API Analytics and Monetization platform.  Kong Konnect is a cloud hosted API gateway and AI gateway.  Moesif is an API analytics and monetization service.With the Moesif plugin for Kong Konnect, you can:  Understand customer API usage  Get alerted on API consumption and issues  Monetize APIs with usage-based billing  Enforce quotas and limits  Guide customers using your APIsThis plugin is designed to log REST, GraphQL, XML/SOAP, and other API traffic without adding any latency. This integration supports both Kong Konnect via Docker and Kong Konnect via Kubernetes.Source Code on GitHubPackage on LuarocksHow to install (Docker)Prerequisites:  Clone the kong-moesif-plugin  Ensure that the docker image has the require library and dependencies installed. You could build the custom image using Dockerfile -FROM kong/kong-gateway:3.10# Switch to root userUSER rootRUN apt-get update; apt-get install -y curl vim unzip git zlib1g-dev gcc# Install luarocks dependenciesRUN luarocks install lua-resty-httpRUN luarocks install lua-zlib# Revert back to default userUSER kongand build using docker build -t kong/kong-gateway-custom .Please note that you’d change the kong-gateway image to the kong version you’re using.1. Add Moesif Plugin to Data Plane Node  In your control plane, go to Data Plane Nodes, then click New Data Plane Node.  Choose Linux (Docker) and Generate a certificate.      Copy the generated docker run command and add the following snippet to it:    Substitute the PATH_TO_DIR in the snippet to the path where kong-plugin-moesif directory resides in your system.    -v &quot;/{PATH_TO_DIR}/kong:/tmp/custom_plugins/kong&quot; -e &quot;KONG_PLUGINS=bundled,moesif&quot; -e &quot;KONG_LUA_PACKAGE_PATH=/tmp/custom_plugins/?.lua;;&quot;         Use the docker image kong/kong-gateway-custom build earlier  Run the command to start a data plane node with Moesif plugin loaded in.Please note that if you are running Kong Konnect on Docker, the plugin needs to be installed inside the Kong Konnect container for each node. Mount the plugin’s source code into the container.2. Enable Moesif plugin in Konnect  From the Gateway Manager, open a control plane.  Open Plugins from the side navigation, then click Add Plugin.  Open the Custom Plugins tab, then click Create on the Custom Plugin tile.  Upload Schema File: /kong/plugins/moesif/schema.lua from the kong-plugin-moesif repo.  Open the Moesif plugin and add your Moesif Application Id. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps or by going to API keys section within Moesif settings.How to install (Kubernetes)Prerequisites:  kubectl or oc access: You have kubectl or oc (if working with OpenShift) installed and configured to communicate to your Kubernetes TLS.  Helm 3 is installed.1. Set up HelmOn your local machine, create a namespace in your Kubernetes cluster and pull down the Kong Helm repo.  Create a namespace:    kubectl create namespace kong        Add the Kong charts repository:    helm repo add kong https://charts.konghq.com        Update Helm:    helm repo update      2. Create a ConfigMap with the Moesif Plugin CodeYou’ll need to clone the kong-moesif-plugin and navigate to the kong/plugins directory to create a configMap usingkubectl create configmap kong-plugin-moesif --from-file=moesif -n kongPlease ensure that this is created in the same namespace as the one in which Kong is going to be installed. This step will add moesif-plugin to data plane nodes when Kong Konnect is created.3. Enable Moesif plugin for control planeKonnect requires the custom plugin’s schema.lua file. Using that file, it creates a plugin entry in the plugin catalog for your control plane.  From the Gateway Manager, open a control plane.  Open Plugins from the side navigation, then click Add Plugin.  Open the Custom Plugins tab, then click Create on the Custom Plugin tile.  Upload the schema.lua file located on GitHub.  Check that your file displays correctly in the preview, then click Save.  Open the newly saved plugin and add your Moesif Application Id. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps or by going to API keys section within Moesif settings.Uploading a custom plugin schema adds the plugin to a specific control plane. If you need it to be available in multiple control planes, add the schema individually to each one.4. Generate certificatesGenerate the certificates Konnect requires through the UI, then copy and save them to your local machine as tls.crt and tls.key. Next create a Kubernetes secret containing the certificates that we will reference from the Helm chart values.yaml.Create Secret using tls.crt and .key files:kubectl create secret tls kong-cluster-cert -n kong --cert=/{PATH_TO_FILE}/tls.crt --key=/{PATH_TO_FILE}/tls.key5. Load Moesif PluginWith Helm, you could load the Moesif plugin by adding the following values to your values.yaml file:# values.yamlplugins:  configMaps:  - name: kong-plugin-moesif    pluginName: moesifExample Configuration parameters for GatewayExample values.yaml : Copy and paste this text into a file called values.yaml on your local machine. Please update image.tag if needed.Note: moesif-plugin has been added in plugins section to load moesif-plugin in data plane nodes.# values.yamlimage:  repository: kong/kong-gateway  tag: &#39;3.5.0.1&#39;secretVolumes:  - kong-cluster-certadmin:  enabled: falseenv:  role: data_plane  database: &#39;off&#39;  cluster_mtls: pki  cluster_control_plane: 1820776ca7.us.cp0.konghq.com:443  cluster_server_name: 1820776ca7.us.cp0.konghq.com  cluster_telemetry_endpoint: 1820776ca7.us.tp0.konghq.com:443  cluster_telemetry_server_name: 1820776ca7.us.tp0.konghq.com  cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt  cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key  lua_ssl_trusted_certificate: system  konnect_mode: &#39;on&#39;  vitals: &#39;off&#39;# Add kong moesif plugin plugins:  configMaps:  - name: kong-plugin-moesif    pluginName: moesifingressController:  enabled: false  installCRDs: false6. Create GatewayApply the values.yaml with Helm install to deploy your Gateway data plane nodes:helm install my-kong kong/kong -n kong --values ./values.yamlYou should see Gateway data plane pod up and in running state on success. To check pod’s state, run the following:kubectl get pods -n kongHow to useParametersThe Moesif Kong Plugin has a variety of options for things like data scrubbing and tweaking performance.            Parameter      Default(Kong gateway 1.x, 2.x)      Default(Kong gateway 3.x onwards)      Description                  name                    The name of the plugin to use, in this case moesif              service_id                    The id of the Service which this plugin will target.              route_id                    The id of the Route which this plugin will target.              enabled      true      true      Whether this plugin will be applied.              consumer_id                    The id of the Consumer which this plugin will target.              api_id                    The id of the API which this plugin will target. Note: The API Entity is deprecated in favor of Services since CE 0.13.0 and EE 0.32.              config.application_id                    The Moesif application token provided to you by Moesif.              config.api_endpoint      https://api.moesif.net      https://api.moesif.net      URL for the Moesif API.              config.timeout (deprecated)      1000      1000      Timeout in milliseconds when connecting/sending data to Moesif.              config.connect_timeout      1000      1000      Timeout in milliseconds when connecting to Moesif.              config.send_timeout      5000      5000      Timeout in milliseconds when sending data to Moesif.              config.keepalive      5000      5000      Value in milliseconds that defines for how long an idle connection will live before being closed.              config.api_version      1.0      1.0      API Version you want to tag this request with.              config.disable_capture_request_body      false      false      Disable logging of request body.              config.disable_capture_response_body      false      false      Disable logging of response body.              config.request_header_masks      {}      {}      An array of request header fields to mask.              config.request_body_masks      {}      {}      An array of request body fields to mask.              config.response_header_masks      {}      {}      An array of response header fields to mask.              config.response_body_masks      {}      {}      An array of response body fields to mask.              config.batch_size      50      50      Maximum batch size when sending to Moesif.              config.user_id_header      ’’      nil      Request or response header to use for identifying the User. See identifying users.              config.company_id_header      ’’      nil      Request or response header to use for identifying the Company. See identifying companies.              config.authorization_header_name      authorization      authorization      Request header containing a Bearer or Basic token to extract user id. See identifying users. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.              config.authorization_user_id_field      sub      sub      Field name in JWT/OpenId token’s payload for identifying users. Only applicable if authorization_header_name is set and is a Bearer token. See identifying users.              config.authorization_company_id_field      ’’      nil      Field name in JWT/OpenId token’s payload for identifying companies. Only applicable if authorization_header_name is set and is a Bearer token. See identifying companies.              config.disable_gzip_payload_decompression      false      false      If set to true, will disable decompressing body in Kong.              config.max_callback_time_spent      750      750      Limiter on how much time to send events to Moesif per worker cycle.              config.request_max_body_size_limit      100000      100000      Maximum request body size in bytes to log.              config.response_max_body_size_limit      100000      100000      Maximum response body size in bytes to log.              config.request_query_masks      {}      {}      An array of query string params fields to mask.              config.event_queue_size      100000      100000      Maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new to event to queue to prevent memory overflow.              config.debug      false      false      If set to true, prints internal log messages for debugging integration issues.              enable_compression      false      If set to true, requests are compressed before sending to Moesif.             Identifying usersThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey.The default algorithm covers most authorization designs and works as follows:  If the config.user_id_header option is set, read the value from the specified HTTP header key config.user_id_header.  Else if Kong defined a value for x-consumer-custom-id, x-consumer-username, or x-consumer-id (in that order), use that value.  Else if an authorization token is present in config.authorization_header_name, parse the user id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_user_id_field (by default is sub).      If header contains Basic, base64 decode the string and use the username portion (before the : character).      For advanced configurations, you can define a custom header containing the user id via config.user_id_header or override the options config.authorization_header_name and config.authorization_user_id_field.Identifying companiesYou can associate API users to companies for tracking account-level usage. This can be done either:  Defining config.company_id_header, Moesif will use the value present in that header.  Use the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.  Else if an authorization token is present in config.authorization_header_name, parse the company id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by config.authorization_company_id_field (by default is ``).      TroubleshootingNo events logged to MoesifYou may have the plugin enabled twice for the same scope (global, service, route, etc), which Kong does not support.Make sure you remove all instances of the Moesif plugin and re-enable it only once. To confirm if you are running into duplicate instances, you may see this in your Kong logs:init.lua:394: insert(): ERROR: duplicate key value violates unique constraint &quot;plugins_cache_key_key&quot;Key (cache_key)=(plugins:moesif::::) already exists., client: 127.0.0.1, server: kong_admin, request: &quot;POST /plugins/ HTTP/1.1&quot;, host: &quot;localhost:8001&quot;Another reason plugin may not be running is if you didn’t restart Kong after enabling the plugin. Make sure you restart your Kong instance.Kong Konnect fails to recognize customer_id as user_id for each API callIf you’re using Kong Konnect with Moesif and having trouble linking the customer_id to user_id for API calls, it’s likely related to authentication plugin configuration. Make sure you have the appropriate auth plugin enabled in Kong.API keys must be correctly utilized, and it’s important to note that API calls are only identified as linked to a user if the route is a protected one. If you’ve already sent requests using an API key generated via Kong but can’t see them automatically linked to the customer ID, check your auth plugin settings.Examples  View example Dockerfile.Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/kong-konnect/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-krakend": {
      "title": "Server Integration Guide - KrakenD",
      "content"	 : "KrakenDMoesif KrakenD plugin is available only on KrakenD Enterprise.Since KrakenD 2.5, Moesif has native integration with KrakenD Enterprise. This means you only need add the necessary configuration in krakend.json file to start using Moesif.Enabling the Moesif plugin in KrakenDSince the Moesif plugin is available in KrakenD Enterprise by default, the only thing required to enable Moesif in KrakenD is to add a telemetry/moesif entry into the krakend.json configuration file. To push data to your Moesif account, you must add your Moesif Application ID to this config.  In order to track Users and Companies in Moesif, you must add few additional settings that are covered further down on the page.Below is an example of a krakend.json file that includes the extra_config section to use Moesif with KrakenD. The application_id field is the only value that is required.{  &quot;version&quot;: 3,  &quot;extra_config&quot;: {    &quot;telemetry/moesif&quot;: {      &quot;@comment&quot;: &quot;Push user activity to Moesif based on the information contained in JWT, every second, in batches of 1000 events&quot;,      &quot;application_id&quot;: &quot;Sign in to get your Moesif Application Id&quot;,      &quot;debug&quot;: false,      &quot;log_body&quot;: false,      &quot;event_queue_size&quot;: 1000000,      &quot;batch_size&quot;: 1000,      &quot;timer_wake_up_seconds&quot;: 1    }  }}See additional documentation from KrakenD for more details.Tracking UsersTo allow Moesif to track API calls by a user ID, you can identify the user that made the call through the JWT they use. To do this, you’ll need to set the user_id_headers parameter within the configuration. Additionally, if using a JWT you’ll need to also set the user_id_jwt_claim parameter.Setting the user_id_headersIn the Moesif configuration, you will need to add the user_id_headers field. This field defines the list of possible headers that can identify a user uniquely. When the header is Authorization and the auth type is Basic, KrakenD will automatically extract the username with no additional configuration.If tokens are used and passed as an Authorization: Bearer header, KrakenD will extract the user ID from the JWT claim based on what is configured in the corresponding user_id_jwt_claim field (covered below).In the case where multiple headers may contain the user information, an array of options can be passed. Below is an example of an array with multiple headers.&quot;user_id_headers&quot;: [  &quot;X-User-Id&quot;,  &quot;Authorization&quot;],Of the list that is passed, all entries are tested in the given order. The first header to match in the list is used to extract the user ID (successfully or not).Setting the user_id_jwt_claimWhen using JWT tokens, the user_id_jwt_claim defines which claim in the JWT contains the user ID. The field must be a string. By default, KrakenD will use the value that is stored in the JWT’s sub claim. Below is an example of how to set up KrakenD to use a JWT to extract a user ID.&quot;user_id_jwt_claim&quot;: &quot;sub&quot;,&quot;identify_company&quot;: {  &quot;jwt_claim&quot;: &quot;company_id&quot;},Tracking CompaniesIdentifying the company to which an API call (and user) belongs can be done in 3 different ways: through a JWT claim, header value, or query string. It’s important to note that only one of these methods can be used at a time.Via JWT ClaimTo identify a company through a value in the JWT claim, you’ll want to specify which field in the JWT claim should be used. If your JWT payload looks similar to this:{  &quot;sub&quot;: &quot;1234567890&quot;,  &quot;name&quot;: &quot;John Doe&quot;,  &quot;iat&quot;: 1516239022,  &quot;company_id&quot;: &quot;123myCompany&quot;}you can add the following to your krakend.json Moesif configuration:&quot;identify_company&quot;: {  &quot;jwt_claim&quot;: &quot;company_id&quot;},  Note: the value where company_id is can be the name of whatever field you’d like to extract from the JWT.Via Request HeaderTo extract the company ID from a header, you will need to use the header option and specify which header to retrieve the value from. For instance, if there is a header in the request called X-Company-Id, it could be extracted by using the following entry in your config.&quot;identify_company&quot;: {  &quot;header&quot;: &quot;X-Company-Id&quot;},Via Query StringTo extract the value from a query parameter, you can use the query_string option and specify which query string the value should be extracted from. For instance, if a request contains a ?company_id=123mycompany query string, the company ID could be extracted using the following entry in your config:&quot;identify_company&quot;: {  &quot;query_string&quot;: &quot;company_id&quot;},ParametersBelow is a list of all the parameters that can be added to the krakend.json configuration file within the Moesif configuration object (telemetry/moesif).            Key      Title      Description      Type      Default      Examples                  application_id      Collector Application ID      The Collector Application ID is used to send events, actions, users, and companies to Moesif’s Collector API. Moesif provides it under the ‘API Keys’ section.      string                            debug      Enable debug      Set to true when configuring Moesif for the first time while in development, to see the activity in the logs. Set to false in production.      boolean      false                     log_body      Send the body      Send the body of all endpoints and requests to Moesif.      boolean      true                     event_queue_size      Event Queue Size      Sends the number of events you can hold in-memory to send them asynchronously to Moesif. If the throughput of your API generates more events than the size of the queue, the exceeding events will be discarded and not reported.      integer      1000000                     batch_size      Batch Size      Number of events you will send on every batch reporting asynchronously to Moesif. For high throughput you will need to increase this value.      integer      200                     timer_wake_up_seconds      Timer Wake Up      Specifies how often a background thread runs to send events to Moesif. Value in seconds.      integer      2                     request_header_masks      Request header masks      The list of request headers that you want to mask their values before sending them to Moesif.      array             [“Authorization”]              response_header_masks      Response header masks      The list of response headers that you want to mask their values before sending them to Moesif.      array             [“Cookie”]              request_body_masks      Request body masks      The list of fields in the request body that you want to mask before sending them to Moesif. You can set log_body to false to prevent any body being sent.      array             [“password”, “credit_card”]              response_body_masks      Response body masks      The list of fields in the response body that you want to mask before sending them to Moesif. You can set log_body to false to prevent any body being sent.      array             [“password”, “credit_card”]              user_id_headers      User ID headers      Defines the list of possible headers that can identify a user uniquely.      array             [“X-User-ID”, “Authorization”]              user_id_jwt_claim      User ID JWT claim      When using JWT tokens, it defines which claim contains the user ID. The field must be a string.      string      “sub”                     identify_company      Identify company      It sets which strategy you want to use to identify the company. Identifying the company helps you efficiently govern your API. Choose the system you wish to apply (declare only one property).      object             jwt_claim, header, query_string      Example ConfigHere is an example of a krakend.json that includes the elements required to track users and companies.{  &quot;version&quot;: 3,  &quot;extra_config&quot;: {    &quot;telemetry/moesif&quot;: {      &quot;@comment&quot;: &quot;Push user activity to Moesif based on the information contained in JWT, every second, in batches of 1000 events&quot;,      &quot;application_id&quot;: &quot;yourapplicationid&quot;,      &quot;user_id_headers&quot;: [        &quot;Authorization&quot;      ],      &quot;user_id_jwt_claim&quot;: &quot;sub&quot;,      &quot;identify_company&quot;: {        &quot;jwt_claim&quot;: &quot;company_id&quot;      },      &quot;debug&quot;: false,      &quot;log_body&quot;: false,      &quot;event_queue_size&quot;: 1000000,      &quot;batch_size&quot;: 1000,      &quot;timer_wake_up_seconds&quot;: 1    }  }}",
      "url": " /server-integration/krakend/",
      "author": "Dylan",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-k8s-nginx-ingress": {
      "title": "Server Integration Guide - Kubernetes NGINX Ingress Controller",
      "content"	 : "Moesif Plugin for NGINX Ingress ControllerNGINX Ingress Controller built around Kubernetes Ingress resource, using a ConfigMap to store the NGINX configuration. This plugin will log API calls to Moesif for API analytics and monitoring.Github RepoHow to InstallClone the repoWe’ll clone this repo which has the codebase to create configmap, mount the plugin, and enable it during the build time.How to UseCreate a namespaceOnce the repo is cloned, we’ll create an ingress-nginx namespace.kubectl apply -f namespace.jsonCreate a configmap for MoesifAfter an ingress-nginx namespace is created, we’ll create a configmap for the moesif plugin.kubectl create -n ingress-nginx configmap moesif-plugin --from-file=moesif/ Create a configmap for LuasocketWe’ll also create a configmap for the luasocket library.kubectl create -n ingress-nginx configmap moesif-socket-plugin --from-file=moesif/socket/Please note that, we’re creating configmap for luasocket as to avoid installing luarocks and luasocket at runtime, since the moesif plugin depends on luasocket.Deploy the nginx ingress controllerBefore we install the nginx ingress controller, we’ll have to update the controller-deployment.yaml file to mount and enable config. Please refer to the Nginx Ingress Controller Installation Guide if you’re using another method to enable ingress. You could also refer to the default deployment used by Nginx Ingress Controller.We’re enabling the moesif plugin, configuring it, and setting the identify variable which Moesif uses downstream.# Source: ingress-nginx/templates/controller-configmap.yamlapiVersion: v1kind: ConfigMapmetadata:  labels:    helm.sh/chart: ingress-nginx-4.0.2    app.kubernetes.io/name: ingress-nginx    app.kubernetes.io/instance: ingress-nginx    app.kubernetes.io/version: 1.0.1    app.kubernetes.io/managed-by: Helm    app.kubernetes.io/component: controller  name: ingress-nginx-controller  namespace: ingress-nginxdata:  plugins: &quot;moesif&quot;  server-snippet: &quot;set $moesif_req_body nil; set $moesif_res_body nil; set $moesif_user_id nil; set $moesif_company_id nil; set $moesif_application_id &amp;lt;Your Moesif Application Id&amp;gt;;&quot;Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking API Keys.Please note that Moesif Application Id is required to be updated to capture api calls to your account. Also, don’t remove any of the identity variables set in server-snippet directive as Moesif plugin uses it downstream. Additionally, you can add other moesif config in server-snippet for example set $debug true;.Next, we’ll have to mount the plugins and set the Lua path in the nginx ingress controller deploymentapiVersion: apps/v1kind: Deploymentmetadata:  labels:    helm.sh/chart: ingress-nginx-4.0.2    app.kubernetes.io/name: ingress-nginx    app.kubernetes.io/instance: ingress-nginx    app.kubernetes.io/version: 1.0.1    app.kubernetes.io/managed-by: Helm    app.kubernetes.io/component: controller  name: ingress-nginx-controller  namespace: ingress-nginxspec:  selector:    matchLabels:      app.kubernetes.io/name: ingress-nginx      app.kubernetes.io/instance: ingress-nginx      app.kubernetes.io/component: controller  revisionHistoryLimit: 10  minReadySeconds: 0  template:    metadata:      labels:        app.kubernetes.io/name: ingress-nginx        app.kubernetes.io/instance: ingress-nginx        app.kubernetes.io/component: controller    spec:      dnsPolicy: ClusterFirst      containers:        - name: controller          image: k8s.gcr.io/ingress-nginx/controller:v1.0.1@sha256:26bbd57f32bac3b30f90373005ef669aae324a4de4c19588a13ddba399c6664e          imagePullPolicy: IfNotPresent          lifecycle:            preStop:              exec:                command:                  - /wait-shutdown          args:            - /nginx-ingress-controller            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller            - --election-id=ingress-controller-leader            - --controller-class=k8s.io/ingress-nginx            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller            - --validating-webhook=:8443            - --validating-webhook-certificate=/usr/local/certificates/cert            - --validating-webhook-key=/usr/local/certificates/key          securityContext:            capabilities:              drop:                - ALL              add:                - NET_BIND_SERVICE            runAsUser: 101            allowPrivilegeEscalation: true          env:            - name: POD_NAME              valueFrom:                fieldRef:                  fieldPath: metadata.name            - name: POD_NAMESPACE              valueFrom:                fieldRef:                  fieldPath: metadata.namespace            - name: LD_PRELOAD              value: /usr/local/lib/libmimalloc.so            - name: LUA_CPATH              value: &quot;/usr/local/lib/lua/?/?.so;/usr/local/lib/lua/?.so;/etc/nginx/lua/plugins/moesif/?.so;;&quot;            - name: LUA_PATH              value: &quot;/usr/local/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/lib/lua/?.lua;/etc/nginx/lua/plugins/moesif/?.lua;;&quot;          livenessProbe:            failureThreshold: 5            httpGet:              path: /healthz              port: 10254              scheme: HTTP            initialDelaySeconds: 10            periodSeconds: 10            successThreshold: 1            timeoutSeconds: 1          readinessProbe:            failureThreshold: 3            httpGet:              path: /healthz              port: 10254              scheme: HTTP            initialDelaySeconds: 10            periodSeconds: 10            successThreshold: 1            timeoutSeconds: 1          ports:            - name: http              containerPort: 80              protocol: TCP            - name: https              containerPort: 443              protocol: TCP            - name: webhook              containerPort: 8443              protocol: TCP          volumeMounts:            - name: webhook-cert              mountPath: /usr/local/certificates/              readOnly: true            - name: &quot;moesif-plugin&quot;              mountPath: &quot;/etc/nginx/lua/plugins/moesif&quot;            - name: &quot;moesif-socket-plugin&quot;              mountPath: &quot;/etc/nginx/lua/plugins/moesif/socket&quot;          resources:            requests:              cpu: 100m              memory: 90Mi      nodeSelector:        kubernetes.io/os: linux      serviceAccountName: ingress-nginx      terminationGracePeriodSeconds: 300      volumes:        - name: webhook-cert          secret:            secretName: ingress-nginx-admission        - name: &quot;moesif-plugin&quot;          configMap:            name: &quot;moesif-plugin&quot;        - name: &quot;moesif-socket-plugin&quot;          configMap:            name: &quot;moesif-socket-plugin&quot;Please note that you’ll have to edit the lua path if you’ve other lua packages at different location.- name: LUA_CPATH    value: &quot;/usr/local/lib/lua/?/?.so;/usr/local/lib/lua/?.so;/etc/nginx/lua/plugins/moesif/?.so;;&quot;- name: LUA_PATH    value: &quot;/usr/local/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/lib/lua/?.lua;/etc/nginx/lua/plugins/moesif/?.lua;;&quot;We’re attaching the configmap and mounting the files. We’ve updated the lua path and cpath to look for files at this location.volumes:  - name: webhook-cert    secret:      secretName: ingress-nginx-admission  - name: &quot;moesif-plugin&quot;    configMap:      name: &quot;moesif-plugin&quot;  - name: &quot;moesif-socket-plugin&quot;    configMap:      name: &quot;moesif-socket-plugin&quot;volumeMounts:  - name: webhook-cert    mountPath: /usr/local/certificates/       readOnly: true  - name: &quot;moesif-plugin&quot;    mountPath: &quot;/etc/nginx/lua/plugins/moesif&quot;  - name: &quot;moesif-socket-plugin&quot;    mountPath: &quot;/etc/nginx/lua/plugins/moesif/socket&quot;Finally, to deploy the nginx ingress controller -kubectl apply -f controller-deployment.yamlAllow sometime for the nginx-ingress-controller pod to be in a running stage before making requests. Congratulations! If everything was done correctly, Moesif should now be tracking all network requests that match the route you’ve specified in nginx.conf. If you have any issues with set up, please reach out to support@moesif.com.Configuration optionsmoesif_application_id(required), string, Application Id to authenticate with Moesif.disable_capture_request_body(optional) boolean, An option to disable logging of request body. false by default.disable_capture_response_body(optional) boolean, An option to disable logging of response body. false by default.request_header_masks(optional) string, An option to mask a specific request header fields. Separate multiple fields by comma such as &quot;header_a, header_b&quot;request_body_masks(optional) string, An option to mask a specific request body fields. Separate multiple fields by comma such as &quot;field_a, field_b&quot;response_header_masks(optional) string, An option to mask a specific response header fields. Separate multiple fields by comma such as &quot;header_a, header_b&quot;response_body_masks(optional) string, An option to mask a specific response body fields. Separate multiple fields by comma such as &quot;field_a, field_b&quot;disable_transaction_id(optional) boolean, Setting to true will prevent insertion of the X-Moesif-Transaction-Id header. false by default.debug(optional) boolean, Set to true to print debug logs if you’re having integration issues.authorization_header_name(optional) string, Request header field name to use to identify the User in Moesif. Defaults to authorization. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.authorization_user_id_field(optional) string, Field name to parse the User from authorization header in Moesif. Defaults to sub.Identifying usersThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey.The default algorithm covers most authorization designs and works as follows:  If the moesif_user_id_header option is set, read the value from the specified HTTP header key moesif_user_id_header.  Else if Nginx defined a value for credentials.app_id, credentials.user_key, or userid (in that order), use that value.  Else if an authorization token is present in authorization_header_name, parse the user id from the token as follows:          If header contains Bearer, base64 decode the string and use the value defined by authorization_user_id_field (by default is sub).      If header contains Basic, base64 decode the string and use the username portion (before the : character).      For advanced configurations, you can define a custom header containing the user id via moesif_user_id_header or override the options authorization_header_name and authorization_user_id_field.Identifying companiesYou can associate API users to companies for tracking account-level usage. This can be done either:  Defining moesif_company_id_header, Moesif will use the value present in that header.  Use the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.Other integrationsTo view more documentation on integration options, please visit the Integration Options.",
      "url": " /server-integration/k8s-nginx-ingress/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-nginx-openresty": {
      "title": "Server Integration Guide - NGINX",
      "content"	 : "Moesif Plugin for NGINXNGINX Lua plugin to log API calls to Moesif for API analytics and monitoring.This plugin supports any NGINX Open Source and NGINX Plus variant that has OpenResty installed including API gateways built on top of OpenResty like 3Scale API Gateway.Github RepoHow to installEnsure you have lua-nginx-module installed.If you’re running an OpenResty image, it’s already installed.If you’re using NGINX Plus, follow these instructions.Install Moesif Luarock:luarocks install --server=http://luarocks.org/manifests/moesif lua-resty-moesifHow to use (Generic OpenResty)Edit your nginx.conf file to add the Moesif plugin.If necessary, replace /usr/local/openresty/luajit/share/lua/5.1/resty with the correct lua plugin installation path.This can be found using find / -name &quot;moesif&quot; -type d. If there are multiple paths, just pick one.  NGINX supports using a directive like log_by_lua* only once in the same section. If you’re already using the same NGINX directives used by Moesif, you may need to adjust your config. See OpenResty docs.lua_shared_dict moesif_conf 5m;init_by_lua_block {   local config = ngx.shared.moesif_conf;   config:set(&quot;application_id&quot;, &quot;Your Moesif Application Id&quot;)   local mo_client = require &quot;moesifapi.lua.moesif_client&quot;   mo_client.get_moesif_client(ngx)}lua_package_cpath &quot;;;${prefix}?.so;${prefix}src/?.so;/usr/share/lua/5.1/lua/resty/moesif/?.so;/usr/share/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.so;/usr/local/share/lua/5.1/resty/moesif/?.so&quot;;lua_package_path &quot;;;${prefix}?.lua;${prefix}src/?.lua;/usr/share/lua/5.1/lua/resty/moesif/?.lua;/usr/share/lua/5.1/?.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.lua;/usr/local/share/lua/5.1/resty/moesif/?.lua&quot;;server {  listen 80;  resolver 8.8.8.8;  # Define the variables Moesif requires  set $moesif_user_id nil;  set $moesif_company_id nil;  set $moesif_req_body nil;  set $moesif_res_body nil;  # Optionally, set moesif_user_id and moesif_company_id such from  # a request header or NGINX var to identify customer  header_filter_by_lua_block  {     ngx.var.moesif_user_id = ngx.req.get_headers()[&quot;X-User-Id&quot;]    ngx.var.moesif_company_id = ngx.req.get_headers()[&quot;X-Company-Id&quot;]  }  # Add Moesif plugin. You may need to update install path  access_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/read_req_body.lua;  body_filter_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/read_res_body.lua;  log_by_lua_file /usr/local/openresty/luajit/share/lua/5.1/resty/moesif/send_event.lua;  # Sample Hello World API  location /api {     add_header Content-Type &quot;application/json&quot;;     return 200 &#39;{rn  &quot;message&quot;: &quot;Hello World&quot;,rn  &quot;completed&quot;: truern}&#39;;  }}How to use (3Scale API Gateway)Installing Moesif plugin for 3Scale API Gateway is the same as vanilla installation except for two changes:  Add 3scale specific configuration options to fetch additional user context from 3scale management API  Replace send_event.lua, with send_event_3Scale.luaEdit your nginx.conf file to add the Moesif plugin.If necessary, replace /usr/share/lua/5.1/lua/resty with the correct lua plugin installation path.This can be found using find / -name &quot;moesif&quot; -type d. If there are multiple paths, just pick one.  NGINX supports using a directive like log_by_lua* only once in the same section. If you’re already using the same NGINX directives used by Moesif, you may need to adjust your config. See OpenResty docs.Below is a sample configuration for 3scale:lua_shared_dict moesif_conf 5m;lua_shared_dict user_id_cache 5m;lua_shared_dict company_id_cache 5m;init_by_lua_block {   local config = ngx.shared.moesif_conf;   config:set(&quot;application_id&quot;, &quot;Your Moesif Application Id&quot;)   config:set(&quot;3scale_domain&quot;, &quot;YOUR_ACCOUNT-admin.3scale.net&quot;)   config:set(&quot;3scale_access_token&quot;, &quot;Your 3scale Access Token&quot;)   local mo_client = require &quot;moesifapi.lua.moesif_client&quot;   mo_client.get_moesif_client(ngx)}lua_package_cpath &quot;;;${prefix}?.so;${prefix}src/?.so;/usr/share/lua/5.1/lua/resty/moesif/?.so;/usr/share/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.so&quot;;lua_package_path &quot;;;${prefix}?.lua;${prefix}src/?.lua;/usr/share/lua/5.1/lua/resty/moesif/?.lua;/usr/share/lua/5.1/?.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.lua&quot;;server {  listen 80;  resolver 8.8.8.8;  # Customer identity variables that Moesif will read downstream  # Set automatically from 3scale management API  set $moesif_user_id &quot;&quot;;  set $moesif_company_id &quot;&quot;;  # Request/Response body variable that Moesif will use downstream  set $moesif_req_body &quot;&quot;;  set $moesif_res_body &quot;&quot;;  access_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/read_req_body.lua;  body_filter_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/read_res_body.lua;  log_by_lua_file /usr/share/lua/5.1/lua/resty/moesif/send_event_3Scale.lua;  # Sample Hello World API  location /api {      add_header Content-Type &quot;application/json&quot;;      return 200 &#39;{rn  &quot;message&quot;: &quot;Hello World&quot;,rn  &quot;completed&quot;: truern}&#39;;  }}Configuration optionsStatic options that are set once on startup such as in init_by_lua_block.application_id(required), string, Application Id to authenticate with Moesif.disable_capture_request_body(optional) boolean, An option to disable logging of request body. false by default.disable_capture_response_body(optional) boolean, An option to disable logging of response body. false by default.request_header_masks(optional) string, An option to mask a specific request header fields. Separate multiple fields by comma such as &quot;header_a, header_b&quot;request_body_masks(optional) string, An option to mask a specific request body fields. Separate multiple fields by comma such as &quot;field_a, field_b&quot;response_header_masks(optional) string, An option to mask a specific response header fields. Separate multiple fields by comma such as &quot;header_a, header_b&quot;response_body_masks(optional) string, An option to mask a specific response body fields. Separate multiple fields by comma such as &quot;field_a, field_b&quot;request_query_masks(optional) string, An option to mask a specific query string params. Separate multiple fields by comma such as &quot;param_a, param_b&quot;disable_transaction_id(optional) boolean, Setting to true will prevent insertion of the X-Moesif-Transaction-Id header. false by default.debug(optional) boolean, Set to true to print debug logs if you’re having integration issues.authorization_header_name(optional) string, Request header field name to use to identify the User in Moesif. Defaults to authorization. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.authorization_user_id_field(optional) string, Field name to parse the User from authorization header in Moesif. Defaults to sub.authorization_company_id_field(optional) string, Field name to parse the Company from authorization header in Moesif.batch_size(optional) number, Maximum batch size when sending to Moesif. Defaults to 50request_max_body_size_limit(optional)  number, Maximum request body size in bytes to log. Defaults to 100000response_max_body_size_limit(optional) number, Maximum response body size in bytes to log. Defaults to 100000enable_compression(optinoal) boolean, If set to true, requests are compressed before sending to Moesif. false by default.3Scale specific optionsIf you installed for 3Scale API Gateway using send_event_3Scale.lua, you have additional static options:3scale_domain(required), string, your full 3Scale admin domain such as  YOUR_ACCOUNT-admin.3scale.net.3scale_access_token(required), string, an admin ACCESS_TOKEN, that you can get from your 3scale admin portal.3scale_user_id_name(optional) string, The 3scale field name from 3scale’s application XML entity used to identify the user in Moesif. This is id by default., but other valid examples include user_account_id and service_id. More info.3scale_auth_api_key(optional) string, If you configured 3scale to authenticate via a single user_key string, set the field name here. This is user_key by default. More info.3scale_auth_app_id(optional) string, If you configured 3scale to authenticate via app_id and app_key pair, set app_id field name here.This is app_id by default. If set, you need to set 3scale_auth_app_key_pair. More info.3scale_auth_app_key_pair(optional) string, If you configured 3scale to authenticate via app_id and app_key pair, set app_key field name here. This is app_key by default. If set, you need to set 3scale_auth_app_id. More info.Dynamic variablesVariables that are dynamic for each HTTP request. Set these variables on the ngx.var dictionary such as in header_filter_by_lua_block or in a body_filter_by_lua_block.header_filter_by_lua_block  {   -- Read user id from request query param  ngx.var.moesif_user_id     = ngx.req.arg_user_id    -- Read version from request header  ngx.var.moesif_api_version = ngx.req.get_headers()[&quot;X-API-Version&quot;]}body_filter_by_lua_block  {   -- Read company id from response header  ngx.var.moesif_company_id  = ngx.resp.get_headers()[&quot;X-Company-Id&quot;]}moesif_user_id(optional) string, Attribute API requests to individual users so you can track who calling your API. This can also be used with ngx.var.moesif_company_id to track account level usage.If you installed for 3scale, you do not need to set this field as this is handled automaticallymoesif_company_id(optional) string, Attribute API requests to companies or accounts so you can track who calling your API. This can be used with ngx.var.moesif_company_id. If you installed for 3scale, you do not need to set this field as this is handled automaticallymoesif_api_version(optional) boolean, An optional API Version you want to tag this request with.moesif_log_event(optional) boolean, An optional flag if set to false, will skip capturing api call for that location context. By default, all the api calls will be captured. For example, when set $moesif_log_event false; for a location context, Moesif will not log api calls for that location.TroubleshootingResponse body not being loggedIf you find response body is not being logged in Moesif, your setup may requirean internal proxy_pass which can be added with a few lines of code to your nginx.conf.For the following sample server:server {  listen 80;  resolver 8.8.8.8;  # Sample Hello World API  location /api {     add_header Content-Type &quot;application/json&quot;;     return 200 &#39;{rn  &quot;message&quot;: &quot;Hello World&quot;,rn  &quot;completed&quot;: truern}&#39;;  }}One with proxy_pass would look like so:server {  listen 80;  resolver 8.8.8.8;  # Sample Hello World API  location /api {    proxy_pass http://127.0.0.1:80/internal;  }  location /internal {      add_header Content-Type &quot;application/json&quot;;      return 200 &#39;{rn  &quot;message&quot;: &quot;Hello World&quot;,rn  &quot;completed&quot;: truern}&#39;;  }}Upgrade Instructions for v2.0.0+When upgrading to version 2.0.0 or higher, please follow these steps to ensure a smooth transition:  Install Required DependenciesEnsure the necessary packages are installed on your system. The following commands are an example for Linux-based systems:apt-get updateapt-get install git zlib1g-dev gcc  Update nginx.confIn your nginx.conf file, add the following Lua code inside the init_by_lua block:local mo_client = require &quot;moesifapi.lua.moesif_client&quot;mo_client.get_moesif_client(ngx)This will initialize the custom client necessary for the plugin to function correctly.ExampleAn example Moesif integration is available based on the quick start tutorial of OpenrestyCongratulations! If everything was done correctly, Moesif should now be tracking all network requests that match the route you specified earlier. If you have any issues with set up, please reach out to support@moesif.com.Other integrationsTo view more documentation on integration options, please visit the Integration Options.",
      "url": " /server-integration/nginx-openresty/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-nginx-plus": {
      "title": "Server Integration Guide - NGINX Plus",
      "content"	 : "Moesif NGINX moduleNative NGINX module written in C to monitor and analyze API traffic in Moesif advanced analytics platform  This C module is for advanced use cases. Moesif recommends the Lua plugin for both Open Source and Plus variants.How it works?This low overhead module captures API request/response headers and body and periodically posts to Moesif servers. The module provides several options, explained below,to be able to choose which API’s data is captured and what part of API headers/body can be sent to Moesif.How to install1. Install the Moesif moduleDownload pre-build binaries from Releases,place them into ./modules sub-directory of nginx.Assuming standard NGINX plus deployment, create a symlink for the module as shown below.sudo ln -s /etc/nginx/modules/ngx_moesif_http_filter_module_1.19.0.so /etc/nginx/modules/ngx_http_moesif_filter_module.so2. Edit your nginx.confAdd the following line at the beginning of nginx.conf_If you’re unsure of the installation path, you can find it via: find / -name &quot;moesif&quot; -type d.load_module modules/ngx_http_moesif_filter_module.so;Also, edit your nginx.conf file to add the Moesif Plus plugin:http{    moesif  on;    moesif_application_id your-moesif-application-id    ...    server {        server_name acmeinc.com;                location /api {            proxy_pass 127.0.0.1:8080        }    }}3. Reload NGINXReload the NGINX config with the command nginx -s reloadAlternatively, you can install this module manually with the Nginx source, see the installation instructionsConfigurationYou can modify your configuration to install on specific services or to add additional data to the logged API calls such as User Id or Metadata.Example:http{    # turn on Moesif  function    moesif  on;    moesif_application_id  your-moesif-application-id;  # required field    moesif_sync_interval 1;  # optional field to configure how often API data is sent, defaults to 2 seconds    moesif_events_cache_size 50;  # optional field to configure events cache size, defaults to 25    moesif_metadata type http;    # optional metadata    ...    server {        server_name example.com;                moesif_metadata server east-1; #optional metadata        location /loc1 {                #moesif data is captured since moesif is on at a global level            moesif_user_id_header  X-USER-ID;            moesif_company_id_header X-COMPANY_ID;            moesif_api_version_header X-API-VERSION;             moesif_api_weight  1;            ...                proxy_pass 127.0.0.1:8080        }                location /loc2 {            moesif  off;  # moesif disabled. No API events captured at this location              ...             }                location /loc3 {            moesif  on;            moesif_skip_body on; # body is not captured at this location            moesif_metadata api mgmt; #optional metadata, all the metadata above is inherited            ...             }            }}Directivesmoesif_application_idsyntax: moesif_application_id &amp;lt;application_id&amp;gt;default: -context: httpYour Moesif Application Id can be found in the Moesif Portal.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking Installation.moesif_events_cache_sizesyntax: moesif_events_cache_size &amp;lt;cache_size&amp;gt;default: cache_size 25context: httpSets the cache_size as unsigned number.This is used to determine internal cache size module uses to save events.moesif_sync_intervalsyntax: moesif_sync_interval &amp;lt;seconds&amp;gt;default: moesif_sync_interval 2context: httpSpecifies the interval events are synced to Moesif.  Defaults to 2 seconds.moesifsyntax: moesif on | offdefault: moesif offcontext: http, server, locationEnables/Disables sending API data to Moesif at Main, Server or particular location level. Location level configuration takes precedence to Server level configuration. Similarly Server level configuration takes precedence to Main level configurationmoesif_skip_bodysyntax: moesif_skip_body on | offdefault: offcontext: http, server, locationThis flag can be used to skip body being sent to Moesif at location/server/global levelmoesif_user_id_headersyntax: moesif_user_id_header &amp;lt;header_name&amp;gt;default: **context: http, server, locationif set, module extracts header_name from API headers and uses that as ‘user’ of the API request. header_name could be request or response header. Response headers are matched first and its case in sensitivemoesif_company_id_headersyntax: moesif_company_id_header &amp;lt;header_name&amp;gt;default: **context: http, server, locationif set, module extracts header_name from API headers and uses that as ‘company’ of the API request. header_name could be request or response header. Response headers are matched first and its case in sensitivemoesif_api_version_headersyntax: moesif_api_version &amp;lt;api_version&amp;gt;default: **context: http, server, locationif set, module extracts header_name from API headers and uses that as ‘api_version’ of the API request. header_name could be request or response header. Response headers are matched first and its case in sensitivemoesif_api_weightsyntax: moesif_api_weight &amp;lt;weight&amp;gt;default: **context: http, server, locationThis directive can be used to set weight of API request at location/server/global levelmoesif_metadatasyntax: moesif_metadata &amp;lt;key&amp;gt; &amp;lt;value&amp;gt;default: **context: http, server, locationAdditional metadata can be configured with this directive to send as part of API metadata. Metadata configured at higher levels is inheritedAdvanced customizationIts possible to customize this module further using the interfaces available in ngx_http_moesif_custom_configuration.c and then see the installation instructions to build module.ngx_http_moesif_skip_event(ngx_http_request_t *r)if a particular event should be skipped logging, this function can be defined The parameter passed in is an ngx_http_request,which contains request headers, response headers, request body.ngx_http_moesif_identify_user(ngx_http_request_t *r, ngx_str_t *user)user id can be set in user-&amp;gt;data after extracting it from ngx_http_request_tngx_http_moesif_identify_company(ngx_http_request_t *r, ngx_str_t *company)company id can be set in company-&amp;gt;data after extracting it from ngx_http_request_tngx_http_moesif_get_api_version(ngx_http_request_t *r, ngx_str_t *api_version)API version of equest can be set in api_version-&amp;gt;data after extracting it from ngx_http_request_tngx_http_moesif_get_metadata(ngx_http_request_t *r, ngx_http_moesif_map_t *metadata, ngx_pool_t *pool)Additional metadata can be set in metadata. Any needed memory can be allocated from poolngx_http_moesif_mask_content(ngx_http_moesif_event_t *r)This function can be configured to mask content as desired before events sent to moesif. Moesif event model is defined in ngx_http_moesif_event.hBuild from sourceStep 1There are several ways to integrate Moesif module into NGINX.      Download pre-build binaries from Releases. Or        Build the binaries from sources  # grab nginx source code from nginx.org, then cd to /path/to/nginx-src/git clone https://github.com/Moesif/ngx_http_moesif_filter_module.git# to build as `static` module./configure --prefix=/opt/nginx --with-stream --add-module=ngx_http_moesif_filter_modulemake &amp;amp;&amp;amp; make install# to build as `dynamic` module./configure --prefix=/opt/nginx --add-dynamic-module=ngx_http_moesif_filter_modulemake modulesStep 2 (dynamic module only)Add the following lines at the beginning of nginx.conf:load_module modules/ngx_http_moesif_filter_module.so;Step 3http {  moesif                  on;  moesif_application_id   your-application-id;  ...}",
      "url": " /server-integration/nginx-plus/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-nodejs": {
      "title": "Server Integration Guide - Node.js",
      "content"	 : "Moesif Node.js Middleware Documentationby Moesif, the API analytics and API monetization platform.Moesif Node.js middleware automatically logs incoming and outgoing API callsand sends them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics andAPI monetization features into your Node.js applications with minimal configuration.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.Notes  Previously, this NPM package was called moesif-express. In version 3.0, it has been renamed to moesif-nodejs to reflect support for any Node.js app.  The library can capture both incoming and outgoing API Calls depending on how you configure the SDK. For more information, see the examples.  To make sure the SDK captures request body, if you use a body parser middleware like body-parser, apply Moesif middleware after it.Who This Middleware is ForThe middleware works with REST APIs, GraphQL APIs(such as with Apollo), and more.This SDK supports any Node.js framework including Express, Koa, and Nest.js. See the examples for more information.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareIn your project directory, install the middleware as a project dependency:npm install --save moesif-nodejsConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseThe following step shows how to import Moesif for an example app using Express.js.1. Import the Module// 1. Import Modulesvar express = require(&#39;express&#39;);var app = express();var moesif = require(&#39;moesif-nodejs&#39;);// 2. Set the options, the only required field is applicationId.var options = {  applicationId: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,  logBody: true,  identifyUser: function (req, res) {    if (req.user) {      return req.user.id;    }    return undefined;  },  getSessionToken: function (req, res) {    return req.headers[&#39;Authorization&#39;];  }};// 3. Initialize the middleware object with optionsvar moesifMiddleware = moesif(options);// 4a. Start capturing outgoing API Calls to 3rd parties like Stripe// Skip this step if you don&#39;t want to capture outgoing API callsmoesifMiddleware.startCaptureOutgoing();// 4b. Use the Moesif middleware to start capturing incoming API Calls// If you have a body parser middleware, apply Moesif middleware after any body parsers.// Skip this step if you don&#39;t want to capture incoming API callsapp.use(moesifMiddleware);Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.If you are using babel or newer versions of Node.js, you can using more modern syntax for importing—for example, import moesif from &#39;moesif-nodejs&#39;; . If you are using ECMAScript modules (ES modules), you can try the following method:const moesifImported = await import(&#39;moesif-nodejs&#39;);const moesif = moesifImported.default;2. Enter Your Moesif Application IDThe middleware expects your Moesif Application ID in the applicationId key of the Moesif initialization options object.For instructions on how to obtain your Application ID, see Get your Moesif Application ID.You can hardcode your Moesif Application ID value in applicationId. But we highly recommend that you use a more secure option like environment variables to store your Application ID. If you set the environment variable as MOESIF_APPLICATION_ID, Moesif automatically picks it up without you having to explicitly specify it in the applicationId key.var moesif = require(&#39;moesif-nodejs&#39;);const http = require(&#39;http&#39;);var options = {  applicationId: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,  logBody: true,};var server = http.createServer(function (req, res) {  moesif(options)(req, res, function () {    // Callback  });  req.on(&#39;end&#39;, function () {    res.write(JSON.stringify({      message: &quot;hello world!&quot;,      id: 2    }));    res.end();  });});server.listen(8080);Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.3. Call your APIFinally, grab the URL to your API endpoint and make some HTTP requests using a tool like Postman or cURL.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide. For troubleshooting issues with capturing outgoing API calls, see Troubleshoot Capturing Outgoing API CallsOther troubleshooting supports:  FAQ  Moesif support emailTroubleshoot Capturing Outgoing API CallsFor instrumenting or capturing outgoing API calls, it instruments standard HTTP or HTTPs from Node.js core.However, some third party SDKS may use customized HTTP clients to make API calls, which may interfere with instrumentation.Here are some tips:      Some SDKS, like the Stripe Node.js SDK, even though they have a very customized http client, lets you swap out to a more standard HTTP client like node-fetch.    import fetch from &#39;node-fetch&#39;; // you may have to add by `npm install node-fetch` or yarn equivalent.import Stripe from &#39;stripe&#39;;const stripeClient = Stripe(&#39;your secret key&#39;, {  // basically you are using node fetch as the httpClient.  httpClient: Stripe.createFetchHttpClient(fetch),});            Turn outgoingPatch flag to true in configuration options to make an attempt to cover non-standard HTTP client usage. However, it may not cover all cases.    {const moesifOptions = {  // ... other options,  outgoingPatch: true};      Repository Structure.├── app.js├── dist/├── eslint.config.mjs├── images/├── lib/├── LICENSE├── package.json├── package-lock.json├── README.md├── test/└── tsconfig.jsonConfiguration Options  Note: If you’re using Koa, you can access the state object through request.state.The following sections describe the available configuration options for this middleware. You can set these options in the Moesif initialization options object. See the example Express.js application code for an example.logBody         Data type          Default              Boolean          true     Whether to log request and response body to Moesif.identifyUser         Data type          Parameters          Return type              Function          (req, res)          String     A function that takes Express.js Request and Response objects as argumentsand returns a user ID. This allows Moesif to attribute API requests to individual unique usersso you can understand who is calling your API. You can use this simultaneously with identifyCompanyto track both individual customers and the companies they are a part of.var options = {  identifyUser: function (req, res) {    // your code here must return the user id as a string. Example Below    return req.user ? req.user.id : undefined;  }}identifyCompany         Data type          Parameters          Return type              Function          (req, res)          String     A function that takes Express.js Request and Response objects as argumentsand returns a company ID. If you have a B2B business, this allows Moesif to attributeAPI requests to specific companies or organizations so you can understand which accounts arecalling your API. You can use this simultaneously with identifyUser to track bothindividual customers and the companies they are a part of.var options = {  identifyCompany: function (req, res) {    // your code here must return the company id as a string. Example Below    return req.headers[&#39;X-Organization-Id&#39;]  }}getSessionToken         Data type          Parameters          Return type              Function          (req, res)          String     A function that takes Express.js Request and Response objects as arguments and returns asession token such as an API key.var options = {  getSessionToken: function (req, res) {    // your code here must return a string. Example Below    return req.headers[&#39;Authorization&#39;];  }}getApiVersion         Data type          Parameters          Return type              Function          (req, res)          String     A function that takes Express.js Request and Response objects as arguments andreturns a string to tag requests with a specific version of your API.var options = {  getApiVersion: function (req, res) {    // your code here must return a string. Example Below    return req.headers[&#39;X-Api-Version&#39;]  }}getMetadata         Data type          Parameters          Return type              Function          (req, res)          Object     A function that takes Express.js Request and Response objects as arguments and returns an object.This function allows youto add custom metadata that Moesif can associate with the request. The metadata must be a simple JavaScript object that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.var options = {  getMetadata: function (req, res) {    // your code here:    return {      foo: &#39;custom data&#39;,      bar: &#39;another custom data&#39;    };  }}skip         Data type          Parameters          Return type              Function          (req, res)          Boolean     A function that takes Express.js Request and Response objects as arguments and returns trueif you want to skip the event. Skipping an event means Moesif doesn’t log the event.The following example skips requests to the root path /:var options = {  skip: function (req, res) {    // your code here must return a boolean. Example Below    if (req.path === &#39;/&#39; || req.path === &#39;/health&#39;) {      // Skip logging traffic to root path or health probe.      return true;    }    return false  }}maskContent         Data type          Parameters          Return type              Function          (MoesifEventModel)          MoesifEventModel     A function that takes the final Moesif event model, rather than the Express request or response objects, as anargument before the middleware sends the event model object to Moesif.With maskContent, you can make modifications to headers or body such asremoving certain header or body fields.import _ from &#39;lodash&#39;;var options = {  maskContent: function(event) {    // remove any field that you don&#39;t want to be sent to Moesif.    const newEvent = _.omit(event, [&#39;request.headers.Authorization&#39;, &#39;event.response.body.sensitive_field&#39;])    return newEvent;  }};Moesif’s event model format looks like this:{  &quot;request&quot;: {    &quot;time&quot;: &quot;2022-08-08T04:45:42.914&quot;,    &quot;uri&quot;: &quot;https://api.acmeinc.com/items/83738/reviews/&quot;,    &quot;verb&quot;: &quot;POST&quot;,    &quot;api_version&quot;: &quot;1.1.0&quot;,    &quot;ip_address&quot;: &quot;61.48.220.123&quot;,    &quot;headers&quot;: {      &quot;Host&quot;: &quot;api.acmeinc.com&quot;,      &quot;Accept&quot;: &quot;*/*&quot;,      &quot;Connection&quot;: &quot;Keep-Alive&quot;,      &quot;Content-Type&quot;: &quot;application/json&quot;,      &quot;Content-Length&quot;: &quot;126&quot;,      &quot;Accept-Encoding&quot;: &quot;gzip&quot;    },    &quot;body&quot;: {      &quot;items&quot;: [        {          &quot;direction_type&quot;: 1,          &quot;item_id&quot;: &quot;fwdsfrf&quot;,          &quot;liked&quot;: false        },        {          &quot;direction_type&quot;: 2,          &quot;item_id&quot;: &quot;d43d3f&quot;,          &quot;liked&quot;: true        }      ]    }  },  &quot;response&quot;: {    &quot;time&quot;: &quot;2022-08-08T04:45:42.924&quot;,    &quot;status&quot;: 500,    &quot;headers&quot;: {      &quot;Vary&quot;: &quot;Accept-Encoding&quot;,      &quot;Pragma&quot;: &quot;no-cache&quot;,      &quot;Expires&quot;: &quot;-1&quot;,      &quot;Content-Type&quot;: &quot;application/json; charset=utf-8&quot;,      &quot;Cache-Control&quot;: &quot;no-cache&quot;    },    &quot;body&quot;: {      &quot;Error&quot;: &quot;InvalidArgumentException&quot;,      &quot;Message&quot;: &quot;Missing field location&quot;    }  },  &quot;user_id&quot;: &quot;my_user_id&quot;,  &quot;company_id&quot;: &quot;my_company_id&quot;,  &quot;session_token&quot;:&quot;end_user_session_token&quot;,  &quot;tags&quot;: &quot;tag1, tag2&quot;}For more information about the different fields of Moesif’s event model,see the following table or the Moesif Node.js API documentation.            Name      Required      Description                  request      Yes      The object that specifies the API request.              request.time      Yes      Timestamp for the request in ISO 8601 format.              request.uri      Yes      Full URI such as https://api.com/?query=string including host, query string, and so on.              request.verb      Yes      The HTTP method—for example, GET and POST.              request.api_version      No      API Version you want to tag this request with such as 1.0.0.              request.ip_address      No      IP address of the client. If not set, Moesif uses the IP address of your logging API calls.              request.headers      Yes      Headers of the  request as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              request.body      No      Body of the request in JSON format or base64 encoded binary data. To specify the transfer encoding, use request.transfer_encoding.              request.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the request body assumed to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           response      No      The object that specifies the response message. If not set, it implies a null response such as a timeout.              response.time      Yes      Timestamp for the response in ISO 8601 format.              response.status      Yes      HTTP response status code number such as 200 OK or 500 Internal Server Error.              response.ip_address      No      IP address of the responding server.              response.headers      Yes      Headers of the response as a Map&amp;lt;string, string&amp;gt; object. Multiple headers with the same key name should be combined together such that the values are joined by a comma. For more information, see HTTP Header Protocol on w3.org              response.body      No      Body of the response in JSON format or base64 encoded binary data. To specify the transfer encoding, use response.transfer_encoding              response.transfer_encoding      No      A string that specifies the transfer encoding of the request body sent to Moesif. If not specified, Moesif assumes the body to be JSON or text. Only supported value is base64 for sending binary data like protocol buffers.                                           session_token      Recommended      The end user session token such as a JWT or API key, which may or may not be temporary. Moesif automatically detects the session token if not set.              user_id      Recommended      Identifies this API call to a permanent user ID.              metadata      No      A JSON Object consisting of any custom metadata to be stored with this event.      debug         Data type          Default              Boolean          undefined     Set to true to print debug logs if you’re having integration issues.isNextJsAppRouter         Data type          Default              Boolean          undefined     Set to true to adapt the interface for NextJs App Router handlersnoAutoHideSensitive         Data type          Default              Boolean          false     Before sending any data for analysis, automatically checks the data (headers and body) and one wayhash strings or numbers that look like a credit card numbers or passwords. Setto true if you want to implement your specific maskContent function or you want to send all data to be analyzed.callback         Data type          Parameters          Return type              Function          (error)          null     For for internal errors. For example, if there has been an error sending eventsto Moesif or network issue, you can use this to check for any issues with integration.disableBatching         Data type          Default              Boolean          false     By default, Moesif Express batches the events. Set to true if you want to send the API events one by one.batchSize         Data type          Default              Number          200     If batching is enabled, this defines the batch size of API events that triggers flushing of queue and sending the data to Moesif. The value of the batch size must be greater than one.batchMaxTime         Data type          Default              Number          2000     If batching is enabled, this defines the maximum wait time (approximately) inmilliseconds before triggering flushing of the queue and sending to Moesif. Thevalue must be greater than 500 milliseconds.retry         Data type          Default              Number          1     The number of times to retry the middleware fails to send data to Moesif.The value must be a number between 0 and 3.requestMaxBodySize         Data type          Default              Number          100000     The maximum request body size in bytes to log when sending the data to Moesif.responseMaxBodySize         Data type          Default              Number          100000     The maximum response body size in bytes to log when sending the data to Moesif.Capture Outgoing API CallsIf you want to capture all outgoing API calls from your Node.js app to third parties likeStripe or to your own dependencies, call startCaptureOutgoing() to start capturing.var moesifMiddleware = moesif(options);moesifMiddleware.startCaptureOutgoing();You can use this method to capture outgoing API calls even if you are not using the Express middleware or having any incoming API calls.The same set of configuration options also applies to outgoing API calls, with a few key differences:There are several configuration option functions that take request and response objects as arguments. The request and response objects passed into those functionsare not Express or Node.js request or response objects when the request is outgoing, but Moesif mockssome of the fields for convenience.Only a subset of the Node.js request or response fields are available, specifically the following:mo_mocked         Data type          Description              Boolean          Set to true if it is a mocked request or response object, for example, outgoing API call.     headers         Data type          Description              Object          A mapping of header names to header values. Case sensitive.     url         Data type          Description              String          The full request URL.     method         Data type          Description              String          The HTTP method such as GET or POST.     statusCode         Data type          Description              Number          The HTTP response status code number.     getHeader         Data type          Parameters          Return type          Description              Function          (String)          String          Reads out a header on the request. Name is case insensitive     get         Data type          Parameters          Return type          Description              Function          (String)          String          Reads out a header on the request. Name is case insensitive     body         Data type          Description              JSON object          The request body as sent to Moesif.     Koa SupportSeveral of the Moesif configuration options take a Node.js request ane response objects as arguments. You can access the Koa state object through req.state.As an example, many Koa auth middleware save the authenticated user on ctx.state.user. You can access it through Moesif options like identifyUser:  identifyUser: function (req, res) {    if (req.state &amp;amp;&amp;amp; req.state.user) {      return req.state.user.sub;    }    return undefined;  },Examples  View example app with Express.js.  View example app with Koa.  View example app with Apollo.js GraphQL.  View example app with Express GraphQL.  View example app with Next.js  View example app with Fastify  View example app with HapiThe following examples demonstrate how to add and update customer information.Update a Single UserTo create or update a user profile in Moesif, use the updateUser() function.var moesifMiddleware = moesif(options);// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema// metadata can be any custom objectvar user = {  userId: &#39;12345&#39;,  companyId: &#39;67890&#39;, // If set, associate user with a company object  metadata: {    email: &#39;john@acmeinc.com&#39;,    firstName: &#39;John&#39;,    lastName: &#39;Doe&#39;,    title: &#39;Software Engineer&#39;,    salesInfo: {        stage: &#39;Customer&#39;,        lifetimeValue: 24000,        accountOwner: &#39;mary@contoso.com&#39;    }  }};moesifMiddleware.updateUser(user, callback);The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update Users in BatchTo update a list of users in one batch, use the updateUsersBatch() function.var moesifMiddleware = moesif(options);// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema// metadata can be any custom objectvar user = {  userId: &#39;12345&#39;,  companyId: &#39;67890&#39;, // If set, associate user with a company object  metadata: {    email: &#39;john@acmeinc.com&#39;,    firstName: &#39;John&#39;,    lastName: &#39;Doe&#39;,    title: &#39;Software Engineer&#39;,    salesInfo: {        stage: &#39;Customer&#39;,        lifetimeValue: 24000,        accountOwner: &#39;mary@contoso.com&#39;    }  }};var users = [user]moesifMiddleware.updateUsersBatch(users, callback);The metadata field can contain any customer demographic or other info you want to store. MOesif only requires the userId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update a Single CompanyTo update a single company, use the updateCompany() function.var moesifMiddleware = moesif(options);// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema// metadata can be any custom objectvar company = {  companyId: &#39;67890&#39;,  companyDomain: &#39;acmeinc.com&#39;, // If domain is set, Moesif will enrich your profiles with publicly available info  metadata: {    orgName: &#39;Acme, Inc&#39;,    planName: &#39;Free Plan&#39;,    dealStage: &#39;Lead&#39;,    mrr: 24000,    demographics: {      alexaRanking: 500000,      employeeCount: 47    }  }};moesifMiddleware.updateCompany(company, callback);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Update Companies in BatchTo update a list of companies in one batch, use the updateCompaniesBatch() function.var moesifMiddleware = moesif(options);// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema// metadata can be any custom objectvar company = {  companyId: &#39;67890&#39;,  companyDomain: &#39;acmeinc.com&#39;, // If domain is set, Moesif will enrich your profiles with publicly available info  metadata: {    orgName: &#39;Acme, Inc&#39;,    planName: &#39;Free Plan&#39;,    dealStage: &#39;Lead&#39;,    mrr: 24000,    demographics: {      alexaRanking: 500000,      employeeCount: 47    }  }};var companies = [company]moesifMiddleware.updateCompaniesBatch(companies, callback);The metadata field can contain any company demographic or other information you want to store. Moesif only requires the companyId field.This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in Moesif Node.js API reference.Add a single ActionTo track and log single Action in Moesif, use the sendAction() function.var moesifMiddleware = moesif(options);// Only `actionName` and `request` is required.// `metadata` is an object containing custom metadata about the Action.var action = {  transactionId: &quot;a3765025-46ec-45dd-bc83-b136c8d1d257&quot;,  actionName: &quot;Clicked Sign Up&quot;,  sessionToken: &quot;23jdf0owekfmcn4u3qypxg08w4d8ayrcdx8nu2nz]s98y18cx98q3yhwmnhcfx43f&quot;,  userId: &quot;12345&quot;,  companyId: &quot;67890&quot;,  metadata: {    email: &quot;johndoe@acmeinc.com&quot;,    button_label: &#39;Get Started&#39;,    sign_up_method: &#39;Google SSO&#39;  },  request: {    time: new Date(),    uri: &quot;https://api.acmeinc.com/items/reviews/&quot;,    ipAddress: &quot;61.48.220.123&quot;,  }};// Send the ActionmoesifMiddleware.sendAction(action, callback);The metadata field can contain any optional metadata about the Action you want to store. Moesif only requires the actionName and request fields.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif API reference.Add a batch of ActionsTo track and log a batch of Actions in Moesif, use the sendActionsBatch() function.var moesifMiddleware = moesif(options);// Define the request context objects for each action.var req_contextA = {  time: new Date(),  uri: &quot;https://api.acmeinc.com/items/reviews/&quot;,  ipAddress: &quot;61.48.220.123&quot;,  userAgentString: &quot;Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0&quot;};var req_contextB = {  time: new Date(),  uri: &quot;https://api.acmeinc.com/pricing/&quot;,  ipAddress: &quot;61.48.220.126&quot;,  userAgentString: &quot;PostmanRuntime/7.26.5&quot;};// Define the actions.// Only `actionName` and `request` is required.// `metadata` is an object containing custom metadata about the Action.var actionA = {  transactionId: &quot;a3765025-46ec-45dd-bc83-b136a8d1d357&quot;,  actionName: &quot;Clicked Sign Up&quot;,  sessionToken: &quot;23abf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f&quot;,  userId: &quot;18340&quot;,  companyId: &quot;25100&quot;,  metadata: {    email: &quot;alex@acmeinc.com&quot;,    button_label: &#39;Get Started&#39;,    sign_up_method: &#39;Google SSO&#39;  },  request: req_contextA};var actionB = {  transactionId: &quot;a3765024-46ee-45dd-bc83-b136c8d1d250&quot;,  actionName: &quot;Viewed pricing&quot;,  sessionToken: &quot;23jdf0owejfmbn4u3qypxg09w4d8ayrxdx8nu2ng]s98y18cx98q3yhwmnhcfx43f&quot;,  userId: &quot;12390&quot;,  companyId: &quot;97895&quot;,  metadata: {    email: &quot;kim@acmeinc.com&quot;,    button_label: &#39;See pricing&#39;,    sign_up_method: &#39;Google SSO&#39;  },  request: req_contextB};var actions = [  actionA,  actionB];// Send the batch of ActionsmoesifMiddleware.sendActionsBatch(actions, callback);The metadata field can contain any optional metadata about the Action you want to store. Moesif only requires the actionName and request fields.This method is a convenient helper that calls the Moesif API library. For more information, see Moesif API reference.How to Get HelpIf you face any issues using this middleware, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/nodejs/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-open-telemetry": {
      "title": "Server Integration Guide - OpenTelemetry",
      "content"	 : "Moesif OpenTelemetry IntegrationIntegrate Moesif API Analytics with your OpenTelemetry-instrumented applications to gain deep insights into your API traffic and performance. This integration allows you to send trace and log data from your OpenTelemetry setup directly to Moesif without any code changes or redeployments.How it worksThe integration works by configuring your OpenTelemetry exporter to send trace and log data to Moesif using the OTLP/HTTP protocol. Moesif treats each OpenTelemetry HTTP Request/Response Span as an API event, capturing key information like request and response details, user identification, and metadata. OpenTelemetry logs are ingested as structured log events that can be correlated with traces.By integrating with OpenTelemetry, you can leverage existing distributed tracing and logging to analyze API performance and user behavior across services and applications.How to InstallPrerequisites  An application instrumented with OpenTelemetry SDKs or an OpenTelemetry Collector which can export OTLP/HTTP for traces and logs.  A Moesif account.Steps      Configure the OpenTelemetry Exporter    Set up your OpenTelemetry SDK to export trace and log data to Moesif using the OTLP/HTTP protocol.    Example Configuration for Traces (YAML):    exporters:  otlphttp:    endpoint: https://api.moesif.net/v1/traces    headers:      X-Moesif-Application-Id: &#39;Your Moesif Application ID&#39;        Example Configuration for Logs (YAML):    exporters:  otlphttp/logs:    endpoint: https://api.moesif.net/v1/logs    headers:      X-Moesif-Application-Id: &#39;Your Moesif Application ID&#39;        Example Configuration (Environment Variables):    # Set the OTLP endpointsexport OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.moesif.net/v1/tracesexport OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://api.moesif.net/v1/logs# Include your Moesif Application ID in the headersexport OTEL_EXPORTER_OTLP_HEADERS=X-Moesif-Application-Id=&#39;Your Moesif Application ID&#39;        Replace &#39;Your Moesif Application ID&#39; with your actual Moesif Application ID. To get your Application ID:          Log into Moesif Portal.      Select the account icon to bring up the settings menu.      Select Installation or API Keys.      Copy your Moesif Application ID from the Collector Application ID field.            Set Up Authentication    Ensure your Moesif Application ID is included in the request headers as X-Moesif-Application-Id to authenticate requests.        Run Your Application    Start your application, and OpenTelemetry will begin sending trace and log data to Moesif.  Mapping OpenTelemetry Data to MoesifMoesif ingests two OpenTelemetry signals today: HTTP request-/response-spans and structured log records. Mapping details for each signal are below.SpansMoesif supports capturing HTTP request span data which follows the OpenTelemetry Semantic Conventions for HTTP SpansMoesif maps OpenTelemetry spans to its API event model. Each span is treated as a single API event in Moesif with the addition of Trace ID, Span ID, Parent Span, Span Links, and metadata.The HTTP semantic conventions for OpenTelemetry are recently stable.  We do our best to be backward compatible with prior HTTP tracing implementations as well.  To understand exactly how OpenTelemetry spans are mapped to Moesif API events, refer to the table below.Span to Moesif API Event Mapping            OpenTelemetry Span Field      Moesif Field      Notes                  trace_id      trace_id      Used to group spans into a single trace.              span_id      span.id      Unique identifier for the span.              parent_span_id      span.parent_id      Identifier of the parent span, if any.              name      action_name      Name of the span or the API action.              kind      direction      Mapped to incoming or outgoing based on span kind.              start_time_unix_nano      request.time      Start time of the request.              end_time_unix_nano      response.time      End time of the response.              attributes      Various fields (see below)      Attributes are mapped to Moesif fields and metadata.              status      span.status      Status of the span.      Span Attributes Mapping            Span Attribute Key      Moesif Field      Notes                  http.method      request.verb      HTTP method (GET, POST, etc.).              http.url or url.full      request.uri      Full request URI.              http.status_code      response.status      HTTP response status code.              http.request.header.&amp;lt;key&amp;gt;      request.headers.&amp;lt;key&amp;gt;      Request headers.              http.response.header.&amp;lt;key&amp;gt;      response.headers.&amp;lt;key&amp;gt;      Response headers.              http.request.body      request.body      Request body string/bytes.              http.response.body      response.body      Response body string/bytes.              client.address or net.peer.ip      request.ip_address      Client IP address.              user_agent.original      request.user_agent_string      User agent string.              user.id      user_id      ID for the user.              company.id      company_id      ID for the company.              subscription.id      subscription_id      ID for the subscription.              weight      weight      Weight for sampling.              Resource      resource      Resource attributes.              Scope      scope      Scope attributes.      LogsMoesif also supports OpenTelemetry log records. Each log record is ingested as a structured log event that can be correlated with traces.            Log Record Field      Moesif Field      Notes                  timeUnixNano      request.time      Log timestamp.              severityNumber      log.severity.number      Numeric severity level (1-24).              severityText      log.severity.text      Text severity (INFO, ERROR, etc.).              body      request.body      Log message content.              traceId      trace_id      Links logs to traces.              spanId      span.id      Links logs to spans.              attributes.user.id      user_id      Associates log with user.              attributes.company.id      company_id      Associates log with company.              EventName      action_name      Associates log with event name.              Resource      resource      Resource attributes.              Scope      scope      Scope attributes.      Common Attributes &amp;amp; MetadataAny span or log attributes that do not have a dedicated mapping are stored in the metadata field in Moesif.User, Company &amp;amp; Subscription TrackingThese IDs are determined by your custom data and are translated into the corresponding Moesif event fields for entity tracking. Associate API calls with entities by adding the relevant attribute (user.id, company.id, or subscription.id) to the span or log.Span.current().setAttribute(&quot;user.id&quot;, &quot;user_123&quot;);There are additional user and company tracking options available in Moesif. For more information, see Identifying Users.Sampling &amp;amp; Weight AttributeIf you are using OpenTelemetry’s sampling, you can set the weight attribute to an integer value that is the inverse of the sample rate to ensure Moesif metrics and counts reflect the correct scale. For example, if you are sampling 50 % of requests, set weight = int(1.0 / 0.5) = 2; use 3 for 33 % sampling, and so on.double sampleRate = 0.5;int weight = (int) (1.0 / sampleRate);Span.current().setAttribute(&quot;weight&quot;, weight);See also  OpenTelemetry Sampling Documentation  OpenTelemetry TraceIdRatioBased SamplerSpan-specific EnhancementsBody CapturingMoesif supports capturing request and response bodies from OpenTelemetry attributes. The bodies must be provided as raw strings or byte arrays.To include request and response bodies:  Set the http.request.body attribute on the span to the raw request body content.  Set the http.response.body attribute on the span to the raw response body content.Example (in Java):Span.current().setAttribute(&quot;http.request.body&quot;, requestBodyStringOrBytes);Span.current().setAttribute(&quot;http.response.body&quot;, responseBodyStringOrBytes);Note:  Only primitive string or byte values are supported. If necessary, ensure you convert any structured object to a string or byte array before setting these attributes.Span Action EventsIn addition to capturing main request/response spans, Moesif now supports capturing OpenTelemetry span events as separate span_action events. Span events are annotations or logs added to a span that provide deeper insights into what occurred during the operation represented by the span.How It Works:  Each event recorded on a span in OpenTelemetry is ingested into Moesif as a separate event of type span_action.  These span_action events:          Contain the trace_id and span_id linking them to the main API event (the span).      Include a request.time corresponding to the event’s timestamp.      Store any span event attributes as metadata for detailed analysis.        Unlike the primary api_call events, span_action events do not represent a full HTTP request/response. Instead, they provide supplemental details (e.g., internal logs, checkpoints, or custom annotations).Example (in Java):Span.current().addEvent(&quot;Database Query Start&quot;, Attributes.of(  stringKey(&quot;db.query&quot;), &quot;SELECT * FROM users&quot;,  stringKey(&quot;db.timing.notes&quot;), &quot;Cache miss&quot;));Moesif will ingest this as a separate span_action event linked to the original trace and span.  The key difference between a Span Event and an additional child Span is that the Span Event does not have a start_time or end_time and is not a full HTTP request/response.  They represent a named action with a single time point and potentially distinct metadata within the Span itself.  OpenTelemetry Span EventsExample IntegrationsIf you are using an OpenTelemetry Collector already, the integration will be as simple as including the exporter configuration above.If you are instrumenting an application from scratch for OpenTelemetry tracing, we have an example Node JS application that demonstrates how to set up OpenTelemetry with Moesif.  The example application is available atNode JS Tracing Example on GithubLimitationsThere are certain OpenTelemetry specific limitations to be aware of:  Traces, Logs, and HTTP Spans, Traces and Logs are supported, but not OpenTelemetry Metrics. Within Traces, HTTP Spans are supported. Spans for other types of information cannot be ingested at this release. See OpenTelemetry Semantic Conventions for HTTP Spans.  Governance Rules Are Not Supported, Moesif’s governance features, such as blocking or modifying API calls, are not supported through the OpenTelemetry integration.  Dynamic Sampling, Moesif’s dynamic sampling is not applied to data ingested via OpenTelemetry. Sampling must be configured manually within your OpenTelemetry tooling. If you do so, set the weight attribute as described above.  See the OpenTelemetry Sampling DocumentationTroubleshooting  Data not appearing in Moesif  Ensure your OpenTelemetry exporter is correctly configured with the Moesif endpoint and Application ID and that your traces include HTTP spans or logs are properly formatted.  Authentication errors  Verify that the X-Moesif-Application-Id header is correctly set with your valid Moesif Application ID for both traces and logs endpoints.  Logs not processing  If logs show Successfully processed 0 log records, verify that log records contain required fields and are properly formatted according to OpenTelemetry specifications.  Incomplete data  If certain fields are missing, check that you have correctly added custom span attributes or log attributes where necessary.Additional Resources  Moesif Server Integrations  OpenTelemetry Documentation  Identifying Users and Companies  OpenTelemetry Sampling Configuration",
      "url": " /server-integration/open-telemetry/",
      "author": "Brian Kennedy",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-laravel": {
      "title": "Server Integration Guide - PHP (Laravel)",
      "content"	 : "Moesif Laravel MiddlwareSource Code on GitHubMiddleware for PHP Laravel (&amp;gt; 5.1) to automatically log API Calls andsends to Moesif for API analytics and log analysisLaravel 4.2A Moesif SDK is available for Laravel 4.2. Credit for creating this goes to jonnypickett.How to installVia Composer$ composer require moesif/moesif-laravelor add ‘moesif/moesif-laravel’ to your composer.json file accordingly.How to useAdd Service Provider// In config/app.php&#39;providers&#39; =&amp;gt; [  /*   * Application Service Providers...   */    MoesifMiddlewareMoesifLaravelServiceProvider::class,];Add to MiddlewareIf website root is your API, add to the root level:// In App/Http/Kernel.phpprotected $middleware = [  /*   * The application&#39;s global HTTP middleware stack.   *   * These middleware are run during every request to your application.   */   MoesifMiddlewareMoesifLaravel::class,];If you only want to add tracking for APIs under specific route group, add to your route group, but be sure to remove from the globalmiddleware stack from above global list.// In App/Http/Kernel.phpprotected $middlewareGroups = [  /**   * The application&#39;s API route middleware group.   */   &#39;api&#39; =&amp;gt; [        //        MoesifMiddlewareMoesifLaravel::class,    ],];To track only certain routes, use route specific middleware setup.Publish the package config file$ php artisan vendor:publish --provider=&quot;MoesifMiddlewareMoesifLaravelServiceProvider&quot;Setup configEdit config/moesif.php file.// In config/moesif.phpreturn [    //    &#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;,    &#39;logBody&#39; =&amp;gt; true,];Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logginginto the Moesif Portal, click on the top right menu,and then clicking Installation.For other configuration options, see below.Configuration optionsTo support Laravel configuration caching, some configuration options have moved into a separate config class for v2.See Migration Guide v1.x.x to v2.x.xYou can define Moesif configuration options in the config/moesif.php file.applicationIdType: StringRequired, a string that identifies your application.disableForkingType: BooleanOptional, If true, this will disable forking. For the best performance, the SDK forks a process to send events by default. However, this requires your PHP environment to not have exec disabled via disable_functions.debugType: BooleanOptional, If true, will print debug messages using IlluminateSupportFacadesLoglogBodyType: BooleanOptional, Default true, Set to false to remove logging request and response body to Moesif.apiVersionType: StringOptional, a string to specify an API Version such as 1.0.1, allowing easier filters.configClassType: StringOptional, a string for the full path (including namespaces) to a class containing additional functions.The class can reside in any namespace, as long as the full namespace is provided.example:return [    ...    &#39;configClass&#39; =&amp;gt; &#39;MyAppMyConfigsCustomMoesifConfig&#39;,    ...];Configuration classBecause configuration hooks and functions cannot be placed in the config/moesif.php file, these reside in a PHP class that you create.Set the path to this class using the configClass option. You can define any of the following hooks:identifyUserIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for userId. Moesif automatically obtains end userId via $request-&amp;gt;user()[‘id’], In case you use a non standard way of injecting user into $request or want to override userId, you can do so with identifyUserId.identifyCompanyIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for companyId.identifySessionIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for sessionId. Moesif automatically sessionizes by processing at your data, but you can override this via identifySessionId if you’re not happy with the results.getMetadataType: ($request, $response) =&amp;gt; Associative ArrayOptional, a function that takes a $request and $response and returns $metdata which is an associative array representation of JSON.maskRequestHeadersType: $headers =&amp;gt; $headersOptional, a function that takes a $headers, which is an associative array, andreturns an associative array with your sensitive headers removed/masked.maskRequestBodyType: $body =&amp;gt; $bodyOptional, a function that takes a $body, which is an associative array representation of JSON, andreturns an associative array with any information removed.maskResponseHeadersType: $headers =&amp;gt; $headersOptional, same as above, but for Responses.maskResponseBodyType: $body =&amp;gt; $bodyOptional, same as above, but for Responses.skipType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and returns true ifthis API call should be not be sent to Moesif.Example config classnamespace MyAppMyConfigs;class CustomMoesifConfig{    public function maskRequestHeaders($headers) {      $headers[&#39;header5&#39;] = &#39;&#39;;      return $headers;    }    public function maskRequestBody($body) {      return $body;    }    public function maskResponseHeaders($headers) {      $headers[&#39;header2&#39;] = &#39;XXXXXX&#39;;      return $headers;    }    public function maskResponseBody($body) {      return $body;    }    public function identifyUserId($request, $response) {      if (is_null($request-&amp;gt;user())) {        return null;      } else {        $user = $request-&amp;gt;user();        return $user[&#39;id&#39;];      }    }    public function identifyCompanyId($request, $response) {      return &quot;67890&quot;;    }    public function identifySessionId($request, $response) {      if ($request-&amp;gt;hasSession()) {        return $request-&amp;gt;session()-&amp;gt;getId();      } else {        return null;      }    }    public function getMetadata($request, $response) {      return array(&quot;foo&quot;=&amp;gt;&quot;a&quot;, &quot;boo&quot;=&amp;gt;&quot;b&quot;);    }    public function skip($request, $response) {      $myurl = $request-&amp;gt;fullUrl();      if (strpos($myurl, &#39;/health&#39;) !== false) {        return true;      }      return false;    }}Update a Single UserCreate or update a user profile in Moesif.The metadata field can be any customer demographic or other info you want to store.Only the user_id field is required.use MoesifMiddlewareMoesifLaravel;// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema// metadata can be any custom object$user = array(    &quot;user_id&quot; =&amp;gt; &quot;12345&quot;,    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$middleware = new MoesifLaravel();$middleware-&amp;gt;updateUser($user);The metadata field can be any custom data you want to set on the user. The user_id field is required.Update Users in BatchSimilar to updateUser, but used to update a list of users in one batch.Only the user_id field is required.use MoesifMiddlewareMoesifLaravel;$userA = array(    &quot;user_id&quot; =&amp;gt; &quot;12345&quot;,    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$userB = array(    &quot;user_id&quot; =&amp;gt; &quot;12345&quot;,    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$users = array($userA);$middleware = new MoesifLaravel();$middleware-&amp;gt;updateUsersBatch($users);The metadata field can be any custom data you want to set on the user. The user_id field is required.Update a Single CompanyCreate or update a company profile in Moesif.The metadata field can be any company demographic or other info you want to store.Only the company_id field is required.use MoesifMiddlewareMoesifLaravel;// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema// metadata can be any custom object$company = array(    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;,    &quot;company_domain&quot; =&amp;gt; &quot;acmeinc.com&quot;, // If domain is set, Moesif will enrich your profiles with publicly available info    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,        &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,        &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,        &quot;mrr&quot; =&amp;gt; 24000,        &quot;demographics&quot; =&amp;gt; array(            &quot;alexa_ranking&quot; =&amp;gt; 500000,            &quot;employee_count&quot; =&amp;gt; 47        )    ));$middleware = new MoesifLaravel();$middleware-&amp;gt;updateCompany($company);The metadata field can be any custom data you want to set on the company. The company_id field is required.Update Companies in BatchSimilar to update_company, but used to update a list of companies in one batch.Only the company_id field is required.use MoesifMiddlewareMoesifLaravel;$companyA = array(    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;,    &quot;company_domain&quot; =&amp;gt; &quot;acmeinc.com&quot;, // If domain is set, Moesif will enrich your profiles with publicly available info    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,        &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,        &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,        &quot;mrr&quot; =&amp;gt; 24000,        &quot;demographics&quot; =&amp;gt; array(            &quot;alexa_ranking&quot; =&amp;gt; 500000,            &quot;employee_count&quot; =&amp;gt; 47        )    ));$companies = array($companyA);$middleware = new MoesifLaravel();$middleware-&amp;gt;updateCompaniesBatch($companies);The metadata field can be any custom data you want to set on the company. The company_id field is required.Credits for Moesif Laravel SDK  Parts of queuing &amp;amp; sending data via forked non-blocking process is based on Mixpanel’s PHP client code which is open sourced under Apache License, Version 2.0.Additional Tips:  The forked (i.e. non-blocking way) of sending data is using exec() with a cURL command. The Php exec() command can be successful but the cURL itself may have 401 errors.  So after integration, if you don’t see events and data show up in your Moesif Dash. Please turn on debug option, then the cURL command itself will logged. You can execute that cURL command and see what the issues are. The most common thing to check is if the Application ID is set correctly.In case you’ve exec() as a disabled function, you could set configuration option disableForking to true to send data to Moesif using curl PHP extension.Troubleshootingexec() must exist/exec() must be enabledBy default, Moesif forks a process to log API calls in an asynchronous method, which requires your PHP environment to have exec() enabled. For highest performance, the recommended fix is to ensure exec() is enabled for your hosting environment:  Instructions for DigitalOcean  Instructions for NamecheapIf you cannot enable exec (such as for shared hosting environments), you can disable forking by adding the following to your moesif.php.return [    &#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;,    &#39;disableForking&#39; =&amp;gt; true,];The PHP JSON extension is required.Make sure you install PHP with the JSON Extension enabled More Info.The PHP cURL extension is requiredThis error happens when you disabled forking and you do not have the cURL PHP extension enabled. The recommended fix is to enable forking by setting disableForking to false in your moesif.php. Otherwise, ensure you have enabled the PHP CURL extension. More info.No events show up in MoesifBecause Moesif forks a process, you may not see all errors from the child process. A common case for event not showing up is due to an incorrect application id.To see debug logs, you can add the following to your moesif.php:// In config/moesif.phpreturn [    //    &#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;,    &#39;debug&#39; =&amp;gt; true,];Test Laravel App with Moesif IntegratedMoesif Laravel TestsAn Example Laravel App with Moesif IntegratedMoesif Laravel ExampleBe sure to update cache after changing config:If you enabled config cache, after you update the configuration, please be sure to run php artisan config:cache again to ensure configuration is updated.Other integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.Migration Guide v1.x.x to v2.x.xv2.x.x now supports Laravel config caching. However, config:cache does not allow function closures in config files (See issue on github)so the SDK configuration has changed in v2.x.x. To migrate, you will need to move any functions from your config/moesif.php into a separate class such as CustomMoesifConfig.Then, reference this class using configClass.For example, if you had these previously:$identifyUserId = function($request, $response) {    // Your custom code that returns a user id string    $user = $request-&amp;gt;user();    if ($request-&amp;gt;user()) {        return $user-&amp;gt;id;    }    return NULL;};return [  ...,  &#39;identifyUserId&#39; =&amp;gt; $identifyUserId,]In V2.X.X, you would do this:  Create a new class like this:namespace MyAppMyConfigs;class CustomMoesifConfig{    public function identifyUserId($request, $response) {      if (is_null($request-&amp;gt;user())) {        return null;      } else {        $user = $request-&amp;gt;user();        return $user[&#39;id&#39;];      }    }    // add other methods for closure based configs.}  In your moesif.php in the config folder:return [  ...,  &#39;configClass&#39; =&amp;gt; &#39;MyAppMyConfigsCustomMoesifConfig&#39;,]",
      "url": " /server-integration/laravel/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-slim": {
      "title": "Server Integration Guide - PHP (Slim)",
      "content"	 : "Moesif Slim MiddlwareSource Code on GitHubMiddleware for PHP Slim Framework to automatically log API Calls and sends to Moesif for API analytics and log analysisHow to installVia Composer$ composer require moesif/moesif-slimor add ‘moesif/moesif-slim’ to your composer.json file accordingly.How to useAdd MiddlewareAdd to the root level:use SlimApp;use SlimFactoryAppFactory;use MoesifMiddlewareMoesifSlim;// Create App instance$app = AppFactory::create();$moesifOptions = [    &#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;,];$app-&amp;gt;addErrorMiddleware(true, true, true);// Add Moesif Middleware$middleware = new MoesifSlim($moesifOptions);$app-&amp;gt;add($middleware);To track only certain routes, use route specific middleware setup.Setup configEdit config/moesif.php file.// In config/moesif.phpreturn [    //    &#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;,    &#39;logBody&#39; =&amp;gt; true,];Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking Installation.For other configuration options, see below.Configuration optionsYou can define Moesif configuration options in the config/moesif.php file. Some of these fields are functions. For options functions that take request and response as input arguments, the request and response objects passed in are Request request or Response objects.applicationIdType: StringRequired, a string that identifies your application.identifyUserIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for userId.// In config/moesif.php$identifyUserId = function($request, $response) {    // Your custom code that returns a user id string    return &#39;12345&#39;;};return [  //  &#39;identifyUserId&#39; =&amp;gt; $identifyUserId];identifyCompanyIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for companyId.// In config/moesif.php$identifyCompanyId = function($request, $response) {    # Your custom code that returns a company id string    return &#39;67890&#39;;};return [  //  &#39;identifyCompanyId&#39; =&amp;gt; $identifyCompanyId];identifySessionIdType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and return a string for sessionId. Moesif automatically sessionizes by processing at your data, but you can override this via identifySessionId if you’re not happy with the results.getMetadataType: ($request, $response) =&amp;gt; Associative ArrayOptional, a function that takes a $request and $response and returns $metdata which is an associative array representation of JSON.// In config/moesif.php$getMetadata = function($request, $response) {  return array(&quot;foo&quot;=&amp;gt;&quot;Slim Framework example&quot;, &quot;boo&quot;=&amp;gt;&quot;custom data&quot;);};return [  //  &#39;getMetadata&#39; =&amp;gt; $getMetadata];apiVersionType: StringOptional, a string to specifiy an API Version such as 1.0.1, allowing easier filters.maskRequestHeadersType: $headers =&amp;gt; $headersOptional, a function that takes a $headers, which is an associative array, andreturns an associative array with your sensitive headers removed/masked.// In config/moesif.php$maskRequestHeaders = function($headers) {    $headers[&#39;password&#39;] = &#39;****&#39;;    return $headers;};return [  //  &#39;maskRequestHeaders&#39; =&amp;gt; $maskRequestHeaders];maskRequestBodyType: $body =&amp;gt; $bodyOptional, a function that takes a $body, which is an associative array representation of JSON, andreturns an associative array with any information removed.// In config/moesif.php$maskRequestBody = function($body) {    // remove any sensitive information.    $body[&#39;password&#39;] = &#39;****&#39;;    return $body;};return [  //  &#39;maskRequestBody&#39; =&amp;gt; $maskRequestBody];maskResponseHeadersType: $headers =&amp;gt; $headersOptional, same as above, but for Responses.maskResponseBodyType: $body =&amp;gt; $bodyOptional, same as above, but for Responses.skipType: ($request, $response) =&amp;gt; StringOptional, a function that takes a $request and $response and returns true ifthis API call should be not be sent to Moesif.debugType: BooleanOptional, If true, will print debug messages using IlluminateSupportFacadesLoglogBodyType: BooleanOptional, Default true, Set to false to remove logging request and response body to Moesif.disableForkingType: Boolean Optional, If true, this will disable forking. For the best performance, the SDK forks a process to send events by default. However, this requires your PHP environment to not have exec disabled via disable_functions.Update a Single UserCreate or update a user profile in Moesif.The metadata field can be any customer demographic or other info you want to store.Only the user_id field is required.use MoesifMiddlewareMoesifSlim;// Only userId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schema// metadata can be any custom object$user = array(    &quot;user_id&quot; =&amp;gt; &quot;12345&quot;,    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$middleware = new MoesifSlim([&#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;]);$middleware-&amp;gt;updateUser($user);The metadata field can be any custom data you want to set on the user. The user_id field is required.Update Users in BatchSimilar to updateUser, but used to update a list of users in one batch. Only the user_id field is required.use MoesifMiddlewareMoesifSlim;$userA = array(    &quot;user_id&quot; =&amp;gt; &quot;12345&quot;,    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$userB = array(    &quot;user_id&quot; =&amp;gt; &quot;1234&quot;,    &quot;company_id&quot; =&amp;gt; &quot;6789&quot;, // If set, associate user with a company object    &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,        &quot;first_name&quot; =&amp;gt; &quot;John&quot;,        &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,        &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,        &quot;sales_info&quot; =&amp;gt; array(            &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,            &quot;lifetime_value&quot; =&amp;gt; 24000,            &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;        )    ));$users = array($userA, $userB);$middleware = new MoesifSlim([&#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;]);$middleware-&amp;gt;updateUsersBatch($users);The metadata field can be any custom data you want to set on the user. The user_id field is required.Update a Single CompanyCreate or update a company profile in Moesif.The metadata field can be any company demographic or other info you want to store.Only the company_id field is required.use MoesifMiddlewareMoesifSlim;// Only companyId is required.// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schema// metadata can be any custom object$company = array(    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;,    &quot;company_domain&quot; =&amp;gt; &quot;acmeinc.com&quot;, // If domain is set, Moesif will enrich your profiles with publicly available info     &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,        &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,        &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,        &quot;mrr&quot; =&amp;gt; 24000,        &quot;demographics&quot; =&amp;gt; array(            &quot;alexa_ranking&quot; =&amp;gt; 500000,            &quot;employee_count&quot; =&amp;gt; 47        )    ));$middleware = new MoesifSlim([&#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;]);$middleware-&amp;gt;updateCompany($company);The metadata field can be any custom data you want to set on the company. The company_id field is required.Update Companies in BatchSimilar to update_company, but used to update a list of companies in one batch. Only the company_id field is required.use MoesifMiddlewareMoesifSlim;$companyA = array(    &quot;company_id&quot; =&amp;gt; &quot;67890&quot;,    &quot;company_domain&quot; =&amp;gt; &quot;acmeinc.com&quot;, // If domain is set, Moesif will enrich your profiles with publicly available info     &quot;campaign&quot; =&amp;gt; array(        &quot;utm_source&quot; =&amp;gt; &quot;google&quot;,        &quot;utm_medium&quot; =&amp;gt; &quot;cpc&quot;,        &quot;utm_campaign&quot; =&amp;gt; &quot;adwords&quot;,        &quot;utm_term&quot; =&amp;gt; &quot;api+tooling&quot;,        &quot;utm_content&quot; =&amp;gt; &quot;landing&quot;    ),    &quot;metadata&quot; =&amp;gt; array(        &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,        &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,        &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,        &quot;mrr&quot; =&amp;gt; 24000,        &quot;demographics&quot; =&amp;gt; array(            &quot;alexa_ranking&quot; =&amp;gt; 500000,            &quot;employee_count&quot; =&amp;gt; 47        )    ));$companies = array($companyA);$middleware = new MoesifSlim([&#39;applicationId&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;]);$middleware-&amp;gt;updateCompaniesBatch($companies);The metadata field can be any custom data you want to set on the company. The company_id field is required.An Example Slim App with Moesif IntegratedMoesif Slim ExampleOther integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/slim/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-symfony": {
      "title": "Server Integration Guide - PHP Symfony",
      "content"	 : "Moesif Symfony SDK Documentationby Moesif, the API analytics and API monetization platform.Moesif’s official SDK for PHP Symfony allows you to automatically capture API traffic and send to the Moesif API Analytics platform.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.Supported Symfony VersionsThe SDK currently supports all Symfony 5.x versions.PrerequisitesBefore using this SDK, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the SDKMoesif Symfony SDK is available through Composer, the dependency manager for PHP. After you have Composer installed, execute the following command:$ composer require moesif/moesif-symfonyOtherwise, manually add moesif/moesif-symfony to your composer.json file.Enable the SDKFollow these steps to enable the SDK:  In your project’s config/packages directory, add a moesif.yaml file. This file holds your configuration options.      The configuration file requires you to at least specify your Moesif Application ID. The following shows an example:     moesif:   moesif_application_id: &#39;YOUR_MOESIF_APPLICATION_ID.&#39;   debug: false   options:     max_queue_size: 50     max_batch_size: 25   hooks_class: &#39;AppConfigurationMyMoesifHooks&#39;        For more configuration options, see YAML Configuration Options.  Configure the SDKSee the available configuration options to learn how to configure the SDK for your use case.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailConfiguration OptionsThe following sections describe the available configuration options that you can define in moesif.yaml.applicationId (Required)         Data type              String     A string that identifies your application..debug         Data type              bool     Set to true to print debug messages into the debug and error logs. This can help you troubleshoot integration issues.options         Data type              Object     If set, contains various options to configure the SDK beyond the defaults.In this object, you can set the following options:max_queue_size         Data type          Default              Integer          15     If set, overrides the default max_queue_size before sending data to Moesif.max_batch_size         Data type          Default              Integer          10     If set, overrides the default max_batch_size that is sent over to Moesif.hooks_class         Data type              String     If set, this must be your implementation of MoesifHooksInterface.User Hook Class OptionsYou can override and customize certain functionalities within the plugin with hooks. For example, create a file MyMoesifHooks.php and implement the MoesifHooksInterface:use MoesifMoesifBundleInterfacesMoesifHooksInterface;use SymfonyComponentHttpFoundationRequest;use SymfonyComponentHttpFoundationResponse;class MyMoesifHooks implements MoesifHooksInterface {   // your implementation of every method follows.}See the Example Implementation for an example.Make sure to set the hooks_class configuration option to the path of your implementation file.The methods you need to implement for MoesifHooksInterface are the following:identifyUserId         Data type          Parameters          Return type              Function          ($request, $response)          String     Optional.This function takes the $request and $response arguments and returns a string for a user ID. This enables Moesif to attribute API requests to individual unique users so you can understand who calls your API. You can use this simultaneously with identifyCompanyId to track both individual customers and also the companies they are part of.identifyCompanyId         Data type          Parameters          Return type              Function          ($request, $response)          String     Optional.This function takes the $request and $response arguments and returns a string for a company ID. If you have a B2B business, this method enables Moesif to attribute API requests to specific companies or organizations so you can understand which accounts call your API. You can use this simultaneously with identifyUserId to track both individual customers and the companies they are part of.identifySessionToken         Data type          Parameters          Return type              Function          ($request, $response)          String     Optional.A function that takes the $request and $response arguments and returns a string for session or auth token. Moesif automatically creates sessions by processing your API data, but you can override this through the identifySessionId method if you’re not happy with the results.maskRequestHeaders         Data type          Parameters          Return type              Function          ($headers)          $headers     Optional.A function that takes the $headers argument for a request. The argument is an associative array. The methodreturns an associative array with your sensitive request headers removed or masked.maskRequestBody         Data type          Parameters          Return type              Function          ($body)          $body     Optional.A function that takes the $body argument for request body. The argument an associative array representation of JSON. The methodreturns an associative array with any request body information removed.maskResponseHeaders         Data type          Parameters          Return type              Function          ($headers)          $headers     Optional.Same as maskRequestHeaders, but for HTTP responses.maskResponseBody         Data type          Parameters          Return type              Function          ($body)          $body     Optional.Same as maskResponseBody, but for HTTP responses.getMetadata         Data type          Parameters          Return type              Function          ($request, $response)          Associative Array     Optional.A function that takes the $request and $response arguments and returns $metadata. $metadata is an associative array representation of JSON.skip         Data type          Parameters          Return type              Function          ($request, $response)          bool     Optional.A function that takes the $request and $response arguments. Returns true if you want to skip the event. Skipping an event means Moesif doesn’t log the event.Example ImplementationThe following example shows what the MyMoesifHooks.php file may look like with a MoesifHooksInterface implementation:&amp;lt;?phpnamespace AppConfiguration;use MoesifMoesifBundleInterfacesMoesifHooksInterface;use SymfonyComponentHttpFoundationRequest;use SymfonyComponentHttpFoundationResponse;class MyMoesifHooks implements MoesifHooksInterface {  public function __construct() {  }  public function identifyUserId(Request $request, Response $response): string|null  {    return &#39;nihao1&#39;;  }  public function identifyCompanyId(Request $request, Response $response): string|null  {    return $request-&amp;gt;headers-&amp;gt;get(&#39;X-Company-Id&#39;);  }  public function identifySessionToken(Request $request, Response $response): string|null  {    return null;  }  public function getMetadata(Request $request, Response $response): ?array  {      return null;  }  public function skip(Request $request, Response $response): bool  {      return false;  }  public function maskRequestHeaders(array $headers): array  {      return $headers;  }  public function maskResponseHeaders(array $headers): array  {      return $headers;  }  public function maskRequestBody($body)  {      // this can be a string or array object.      // because prior to php 8, can not declare union type (such as string|array)      return $body;  }  public function maskResponseBody($body)  {      // this can be a string or array object.      // because prior to php 8, can not declare union type (such as string|array)      return $body;  }}ExamplesThe following examples demonstrate how to add and update customer information.Update a Single UserThe following example shows how you can create or update a user profile in Moesif using the updateUser function.The metadata field can contain any customer demographic or other information you want to store.Only the user_id field is required.For more information, see the PHP API Reference about updating a singer user.&amp;lt;?phpuse MoesifMoesifBundleServiceMoesifApiService;private $moesifApiService;public function __construct(MoesifApiService $moesifApiService){    $this-&amp;gt;moesifApiService = $moesifApiService;}// metadata can be any custom object$data-&amp;gt;metadata = array(    &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,    &quot;first_name&quot; =&amp;gt; &quot;John&quot;,    &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,    &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,    &quot;sales_info&quot; =&amp;gt; array(        &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,        &quot;lifetime_value&quot; =&amp;gt; 24000,        &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;    ));$userData = [    &#39;user_id&#39; =&amp;gt; $data[&#39;userId&#39;],    &#39;user_email&#39; =&amp;gt; $data[&#39;userEmail&#39;],    &#39;company_id&#39; =&amp;gt; $data[&#39;companyId&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$this-&amp;gt;moesifApiService-&amp;gt;updateUser($userData);Update Users in BatchYou can use the updateUsersBatch function to update a list of users in one batch.Only the user_id field is required.For more information, see the PHP API Reference about updating users in batch.&amp;lt;?phpuse MoesifMoesifBundleServiceMoesifApiService;private $moesifApiService;public function __construct(MoesifApiService $moesifApiService){    $this-&amp;gt;moesifApiService = $moesifApiService;}// metadata can be any custom object$data-&amp;gt;metadata = array(    &quot;email&quot; =&amp;gt; &quot;john@acmeinc.com&quot;,    &quot;first_name&quot; =&amp;gt; &quot;John&quot;,    &quot;last_name&quot; =&amp;gt; &quot;Doe&quot;,    &quot;title&quot; =&amp;gt; &quot;Software Engineer&quot;,    &quot;sales_info&quot; =&amp;gt; array(        &quot;stage&quot; =&amp;gt; &quot;Customer&quot;,        &quot;lifetime_value&quot; =&amp;gt; 24000,        &quot;account_owner&quot; =&amp;gt; &quot;mary@contoso.com&quot;    ));$userDataA = [    &#39;user_id&#39; =&amp;gt; $data[&#39;userIdA&#39;],    &#39;user_email&#39; =&amp;gt; $data[&#39;userEmailA&#39;],    &#39;company_id&#39; =&amp;gt; $data[&#39;companyIdA&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$userDataB = [    &#39;user_id&#39; =&amp;gt; $data[&#39;userIdB&#39;],    &#39;user_email&#39; =&amp;gt; $data[&#39;userEmailB&#39;],    &#39;company_id&#39; =&amp;gt; $data[&#39;companyIdB&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$users = array($userDataA, $userDataB)$this-&amp;gt;moesifApiService-&amp;gt;updateUsersBatch($user);Update a Single CompanyTo create or update a company profile in Moesif, use the updateCompany function.The metadata field can contain any company demographic or other information you want to store.Only the company_id field is required.For more information, see the PHP API Reference about updating a single company.&amp;lt;?phpuse MoesifMoesifBundleServiceMoesifApiService;private $moesifApiService;public function __construct(MoesifApiService $moesifApiService){    $this-&amp;gt;moesifApiService = $moesifApiService;}// metadata can be any custom object$data-&amp;gt;metadata = array(    &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,    &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,    &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,    &quot;mrr&quot; =&amp;gt; 24000,    &quot;demographics&quot; =&amp;gt; array(        &quot;alexa_ranking&quot; =&amp;gt; 500000,        &quot;employee_count&quot; =&amp;gt; 47    ));// Prepare company data for Moesif$companyData = [    &#39;company_id&#39; =&amp;gt; $data[&#39;companyId&#39;],    &#39;company_domain&#39; =&amp;gt; $data[&#39;companyDomain&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$this-&amp;gt;moesifApiService-&amp;gt;updateCompany($companyData);Update Companies in BatchTo update a list of companies in one batch, use the updateCompaniesBatch function.Only the company_id field is required.For more information, see the PHP API Reference about updating companies in batch.&amp;lt;?phpuse MoesifMoesifBundleServiceMoesifApiService;private $moesifApiService;public function __construct(MoesifApiService $moesifApiService){    $this-&amp;gt;moesifApiService = $moesifApiService;}// metadata can be any custom object$data-&amp;gt;metadata = array(    &quot;org_name&quot; =&amp;gt; &quot;Acme, Inc&quot;,    &quot;plan_name&quot; =&amp;gt; &quot;Free&quot;,    &quot;deal_stage&quot; =&amp;gt; &quot;Lead&quot;,    &quot;mrr&quot; =&amp;gt; 24000,    &quot;demographics&quot; =&amp;gt; array(        &quot;alexa_ranking&quot; =&amp;gt; 500000,        &quot;employee_count&quot; =&amp;gt; 47    ));// Prepare company data for Moesif$companyDataA = [    &#39;company_id&#39; =&amp;gt; $data[&#39;companyIdA&#39;],    &#39;company_domain&#39; =&amp;gt; $data[&#39;companyDomainA&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$companyDataB = [    &#39;company_id&#39; =&amp;gt; $data[&#39;companyIdB&#39;],    &#39;company_domain&#39; =&amp;gt; $data[&#39;companyDomainB&#39;],    &#39;metadata&#39; =&amp;gt; $data[&#39;metadata&#39;] ?? [], // Include metadata if provided    // Add more fields as needed];$companies = array($companyDataA, $companyDataB)$this-&amp;gt;moesifApiService-&amp;gt;updateCompaniesBatch($companies);How to Get HelpIf you face any issues using this SDK, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/symfony/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-play": {
      "title": "Server Integration Guide - Play Framework based web applications",
      "content"	 : "Moesif Play Filter SDK   Introductionmoesif-play-filter is a Play framework Filter that logs API calls and sends to Moesif for API analytics and monitoring.The SDK is implemented as a Scala HTTP Filterwithout importing framework specific dependencies. Any Web Application built on Play can use this SDK with minimal configuration.Source Code on GitHubHow to installFor SBT users, add dependency to your build.sbt:libraryDependencies += &quot;com.moesif.filter&quot; %% &quot;moesif-play-filter&quot; % &quot;1.18.0&quot;For Maven users, add dependency to your pom.xml:&amp;lt;dependency&amp;gt;    &amp;lt;groupId&amp;gt;com.moesif.filter&amp;lt;/groupId&amp;gt;    &amp;lt;artifactId&amp;gt;moesif-play-filter_2.12&amp;lt;/artifactId&amp;gt;    &amp;lt;version&amp;gt;1.18.0&amp;lt;/version&amp;gt;&amp;lt;/dependency&amp;gt;For Gradle users, add the Moesif dependency to your project’s build.gradle file:dependencies {       compile &#39;com.moesif.filter:moesif-play-filter_2.12:1.18.0&#39;}OthersThe jars are available from a public repo.maven.apache.org - moesif-play-filter repository.How to useMoesifApiFilter can be enabled using play framework application configuration. More details Default HTTP filters and Scala Http filtersIn your play configuration file(default application.conf), enable MoesifApiFilter as belowplay.filters.enabled += &quot;com.moesif.filter.MoesifApiFilter&quot;play.modules.enabled += &quot;com.moesif.filter.MoesifApiFilterModule&quot;play.filters.moesifApiFilter.moesifApplicationId = &quot;Your Moesif application Id&quot;Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking Installation.With the above basic configuration setup Moesif filter will capture api events and send them to Moesif.Advanced Configuration optionsMoesif provides the most value when we can identify users. You may also want to specify metadata, mask certain data, or prevent tracking of certain requests entirely. This is possible with the hooks available in trait MoesifAdvancedFilterConfiguration.To configure the filter, extend the MoesifAdvancedFilterConfiguration class to override methods as desired and thenset config in MoesifAdvancedFilterConfiguration to override the default configimport com.moesif.filter.MoesifAdvancedFilterConfigurationimport play.api.mvc.{RequestHeader, Result}class CustomMoesifAdvancedConfig extends MoesifAdvancedFilterConfiguration {  override def getMetadata(request: RequestHeader, result: Result): Map[String, Object] = Map(&quot;customAttribute&quot; -&amp;gt; &quot;atrributeValue&quot;)}// In you root play application initialization code set custom configMoesifAdvancedFilterConfiguration.setConfig(new CustomMoesifAdvancedConfig())Advanced configuration options are explained beloe1. def skip(request: RequestHeader, result: Result): BooleanReturn true if you want to skip logging arequest to Moesif i.e. to skip boring requests like health probes.  override def skip(request: RequestHeader, result: Result): Boolean =  {    // Skip logging health probes    request.uri == &quot;health/probe&quot;;  }2. def maskContent(moesifEventModel: EventModel): EventModel = moesifEventModelIf you want to remove any sensitive data in the HTTP headers or body before sending to Moesif, you can do so with maskContent3. def identifyUser(request: RequestHeader, result: Result): Option[String]Highly recommended. Even though Moesif automatically detects the end userId if possible, setting this configurationensures the highest accuracy with user attribution.  override def identifyUser(request: RequestHeader, result: Result): Option[String] = {    request.headers.headers.find(_._1 == &quot;X-User-Id&quot;).map(_._2)  }4. def identifyCompany(request: RequestHeader, result: Result): Option[String]You can set this configuration to add company Id to the event.  override def identifyCompany(request: RequestHeader, result: Result): Option[String] = {    request.headers.headers.find(_._1 == &quot;X-Company-Id&quot;).map(_._2)  }5. def sessionToken(request: RequestHeader, result: Result): Option[String]Moesif automatically detects the end user’s session token or API key, but you can manually define the token for finer control.  override def sessionToken(request: RequestHeader, result: Result): Option[String] = {    request.headers.headers.toMap.get(&quot;Authorization&quot;)  }6. def getMetadata(request: RequestHeader, result: Result): Map[String, Object] You can add any additional tags as neededto the event. Ensure that returned metadata map is Json serializable7. debug(optional) boolean, a flag to see debugging messages.The below methods to update user and company are accessible via the Moesif Java API lib which Moesif Play Filter already imports as a dependency.Update a Single UserCreate or update a user profile in Moesif. The metadata field can be any customer demographic or other info you want to store.Only the user_id field is required.For details, visit the Java API Reference.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#users for campaign schemaCampaignModel campaign = new CampaignBuilder()        .utmSource(&quot;google&quot;)        .utmCampaign(&quot;cpc&quot;)        .utmMedium(&quot;adwords&quot;)        .utmTerm(&quot;api+tooling&quot;)        .utmContent(&quot;landing&quot;)        .build();// Only userId is required// metadata can be any custom objectUserModel user = new UserBuilder()    .userId(&quot;12345&quot;)    .companyId(&quot;67890&quot;) // If set, associate user with a company object    .campaign(campaign)    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +        &quot;&quot;first_name&quot;: &quot;John&quot;,&quot; +        &quot;&quot;last_name&quot;: &quot;Doe&quot;,&quot; +        &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +        &quot;&quot;sales_info&quot;: {&quot; +            &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +            &quot;&quot;lifetime_value&quot;: 24000,&quot; +            &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateUser(user);Update Users in BatchSimilar to UpdateUser, but used to update a list of users in one batch. Only the user_id field is required.For details, visit the Java API Reference.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());List&amp;lt;UserModel&amp;gt; users = new ArrayList&amp;lt;UserModel&amp;gt;();// Only userId is required// metadata can be any custom objectUserModel userA = new UserBuilder()    .userId(&quot;12345&quot;)    .companyId(&quot;67890&quot;) // If set, associate user with a company object    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;johndoe@acmeinc.com&quot;,&quot; +        &quot;&quot;first_name&quot;: &quot;John&quot;,&quot; +        &quot;&quot;last_name&quot;: &quot;Doe&quot;,&quot; +        &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +        &quot;&quot;sales_info&quot;: {&quot; +            &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +            &quot;&quot;lifetime_value&quot;: 24000,&quot; +            &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();// Only userId is required// metadata can be any custom objectUserModel userB = new UserBuilder()    .userId(&quot;54321&quot;)    .companyId(&quot;67890&quot;) // If set, associate user with a company object    .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;email&quot;: &quot;mary@acmeinc.com&quot;,&quot; +        &quot;&quot;first_name&quot;: &quot;Mary&quot;,&quot; +        &quot;&quot;last_name&quot;: &quot;Jane&quot;,&quot; +        &quot;&quot;title&quot;: &quot;Software Engineer&quot;,&quot; +        &quot;&quot;sales_info&quot;: {&quot; +            &quot;&quot;stage&quot;: &quot;Customer&quot;,&quot; +            &quot;&quot;lifetime_value&quot;: 48000,&quot; +            &quot;&quot;account_owner&quot;: &quot;mary@contoso.com&quot;&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();users.add(userA);users.add(userB);filter.updateUsersBatch(users);Update a Single CompanyUpdate user is accessible via the Moesif Java API lib which Moesif Play Filter already importsas a dependency.Create or update a company profile in Moesif.The metadata field can be any company demographic or other info you want to store.Only the company_id field is required.For details, visit the Java API Reference.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());// Campaign object is optional, but useful if you want to track ROI of acquisition channels// See https://www.moesif.com/docs/api#update-a-company for campaign schemaCampaignModel campaign = new CampaignBuilder()        .utmSource(&quot;google&quot;)        .utmCampaign(&quot;cpc&quot;)        .utmMedium(&quot;adwords&quot;)        .utmTerm(&quot;api+tooling&quot;)        .utmContent(&quot;landing&quot;)        .build();// Only companyId is required// metadata can be any custom objectCompanyModel company = new CompanyBuilder()    .companyId(&quot;67890&quot;)    .companyDomain(&quot;acmeinc.com&quot;) // If set, Moesif will enrich your profiles with publicly available info     .campaign(campaign)     .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;org_name&quot;: &quot;Acme, Inc&quot;,&quot; +        &quot;&quot;plan_name&quot;: &quot;Free&quot;,&quot; +        &quot;&quot;deal_stage&quot;: &quot;Lead&quot;,&quot; +        &quot;&quot;mrr&quot;: 24000,&quot; +        &quot;&quot;demographics&quot;: {&quot; +            &quot;&quot;alexa_ranking&quot;: 500000,&quot; +            &quot;&quot;employee_count&quot;: 47&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();filter.updateCompany(company);Update Companies in BatchSimilar to UpdateCompany, but used to update a list of companies in one batch. Only the company_id field is required.For details, visit the Java API Reference.MoesifFilter filter = new MoesifFilter(&quot;Your Moesif Application Id&quot;, new MoesifConfiguration());List&amp;lt;CompanyModel&amp;gt; companies = new ArrayList&amp;lt;CompanyModel&amp;gt;();// Only companyId is required// metadata can be any custom objectCompanyModel companyA = new CompanyBuilder()    .companyId(&quot;67890&quot;)    .companyDomain(&quot;acmeinc.com&quot;) // If set, Moesif will enrich your profiles with publicly available info     .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;org_name&quot;: &quot;Acme, Inc&quot;,&quot; +        &quot;&quot;plan_name&quot;: &quot;Free&quot;,&quot; +        &quot;&quot;deal_stage&quot;: &quot;Lead&quot;,&quot; +        &quot;&quot;mrr&quot;: 24000,&quot; +        &quot;&quot;demographics&quot;: {&quot; +            &quot;&quot;alexa_ranking&quot;: 500000,&quot; +            &quot;&quot;employee_count&quot;: 47&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();// Only companyId is required// metadata can be any custom objectCompanyModel companyB = new CompanyBuilder()    .companyId(&quot;09876&quot;)    .companyDomain(&quot;contoso.com&quot;) // If set, Moesif will enrich your profiles with publicly available info     .metadata(APIHelper.deserialize(&quot;{&quot; +        &quot;&quot;org_name&quot;: &quot;Contoso, Inc&quot;,&quot; +        &quot;&quot;plan_name&quot;: &quot;Free&quot;,&quot; +        &quot;&quot;deal_stage&quot;: &quot;Lead&quot;,&quot; +        &quot;&quot;mrr&quot;: 48000,&quot; +        &quot;&quot;demographics&quot;: {&quot; +            &quot;&quot;alexa_ranking&quot;: 500000,&quot; +            &quot;&quot;employee_count&quot;: 53&quot; +          &quot;}&quot; +        &quot;}&quot;))    .build();  companies.add(companyA);  companies.add(companyB);  filter.updateCompaniesBatch(companies);Other integrationsTo view more more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/play/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-python-asgi": {
      "title": "Server Integration Guide - Python ASGI (FastAPI)",
      "content"	 : "Moesif Middleware for Python ASGI-based FrameworksWith Moesif middleware for Python ASGI-based frameworks, you can automatically log API calls and send them to Moesif for API analytics and monitoring.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.OverviewThis middleware allows you to easily integrate Moesif’s API analytics and API monetization service with APIs built on Python ASGI-based (Asynchronous Server Gateway Interface) frameworks including FastAPI and Starlette.ASGIis a spiritual successor to WSGI (Web Server Gateway Interface) enabling async-capable applications.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall with pip using the following command:pip install moesifasgiConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseFastAPISimply add MoesifMiddleware to a FastAPI application using the add_middleware method:from moesifasgi import MoesifMiddlewaremoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    # ... For other options see below.}app = FastAPI()app.add_middleware(MoesifMiddleware, settings=moesif_settings)Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Other ASGI FrameworksIf you are using a framework that is built on top of ASGI, it should work just by adding the Moesif middleware.Please read the documentation for your specific framework on how to add middlewares.Optional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third party services through by setting the CAPTURE_OUTGOING_REQUESTS option:from moesifasgi import MoesifMiddlewaremoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    &#39;CAPTURE_OUTGOING_REQUESTS&#39;: False,}app = FastAPI()app.add_middleware(MoesifMiddleware, settings=moesif_settings)For configuration options specific to capturing outgoing API calls, see Options For Outgoing API Calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── BUILDING.md├── examples/├── images/├── LICENSE├── MANIFEST.in├── moesifasgi/├── README.md├── requirements.txt├── setup.cfg└── setup.pyConfiguration OptionsThe following sections describe the available configuration options for this middleware. You can set these options in a Python dictionary and then pass that as a parameter to add_middleware when you add this middleware. See the sample FastAPI code for an example.Some configuration options use request and response as input arguments. These correspond to the Requests and Responses objects respectively.APPLICATION_ID (Required)         Data type              String     A string that identifies your application in Moesif.SKIP         Data type          Parameters          Return type              Function          (request, response)          Boolean     Optional.A function that takes a request and a response,and returns True if you want to skip this particular event.IDENTIFY_USER         Data type          Parameters          Return type              Function          (request, response)          String     Optional, but highly recommended.A function that takes a request and a response, and returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.IDENTIFY_COMPANY         Data type          Parameters          Return type              Function          (request, response)          String     Optional.A function that takes a request and response, and returns a string that represents the company ID for this event.GET_METADATA         Data type          Parameters          Return type              Function          (request, response)          Dictionary     Optional.This function allows youto add custom metadata that Moesif can associate with the event. The metadata must be a simple Python dictionary that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.GET_SESSION_TOKEN         Data type          Parameters          Return type              Function          (request, response)          String     Optional.A function that takes a request and response, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, provide this function to help identify sessions.MASK_EVENT_MODEL         Data type          Parameters          Return type              Function          (EventModel)          EventModel     Optional.A function that takes the final Moesif event model and returns an event model with desired data removed.The return value must be a valid eventt model required by Moesif data ingestion API. For more information about the EventModel object, see the Moesif Python API documentation.DEBUG         Data type              Boolean     Optional.Set to True to print debug logs if you’re having integration issues.LOG_BODY         Data type          Default              Boolean          True     Optional.Whether to log request and response body to Moesif.BATCH_SIZE         Data type          Default              int          100     An optional field name that specifies the maximum batch size when sending to Moesif.EVENT_BATCH_TIMEOUT         Data type          Default              int          1     Optional.Maximum time in seconds to wait before sending a batch of events to Moesif when reading from the queue.EVENT_QUEUE_SIZE         Data type          Default              int          1000000     Optional.The maximum number of event objects queued in memory pending upload to Moesif. For a full queue, additional calls to MoesifMiddleware returns immediately without logging the event. Therefore, set this option based on the event size and memory capacity you expect.AUTHORIZATION_HEADER_NAME         Data type          Default               String          authorization     Optional.A request header field name used to identify the User in Moesif. It also supports a comma separated string. Moesif checks headers in order like &quot;X-Api-Key,Authorization&quot;.AUTHORIZATION_USER_ID_FIELD         Data type          Default               String          sub     Optional.A field name used to parse the user from authorization header in Moesif.BASE_URI         Data type              String     Optional.A local proxy hostname when sending traffic through secure proxy. Remember to set this field when using secure proxy. For more information, see Secure Proxy documentation..Options For Outgoing API CallsThe following options apply to outgoing API calls. These are calls you initiate using the Python Requests library to third parties like Stripe or to your own services.Several options use request and response as input arguments. These correspond to the Requests library’s request or response objects.If you are not using ASGI, you can import moesifpythonrequest directly.CAPTURE_OUTGOING_REQUESTS (Required)         Data type          Default               Boolean          False     Set to True to capture all outgoing API calls.GET_METADATA_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Dictionary     Optional.A function that enables you to return custom metadata associated with the logged API calls.Takes in the Requests request and response objects as arguments.We recommend that you implement a function thatreturns a dictionary containing your custom metadata. The dictionary must be a valid one that can be encoded into JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.SKIP_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Boolean     Optional.A function that takes a Requests request and response objects,and returns True if you want to skip this particular event.IDENTIFY_USER_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional, but highly recommended.A function that takes Requests request and response objects, and returns a string that represents the user ID used by your system.While Moesif tries to identify users automatically, different frameworks and your implementation might vary. So we highly recommend that you accurately provide a user ID using this function.IDENTIFY_COMPANY_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that represents the company ID for this event.GET_SESSION_TOKEN_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that corresponds to the session token for this event.Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.LOG_BODY_OUTGOING         Data type          Default              Boolean          True     Optional.Set to False to remove logging request and response body.ExamplesSee the example FastAPI app in the examples/ folder of this repository that uses this middleware.Here’s another sample FastAPI app:# identify user not using async modedef identify_user(request, response):    return &quot;12345&quot;# identify company not using async modedef identify_company(request, response):    return &quot;67890&quot;# get metadata not using async modedef get_metadata(request, response):    return {        &#39;datacenter&#39;: &#39;westus&#39;,        &#39;deployment_version&#39;: &#39;v1.2.3&#39;,    }# should skip check not using async modedef should_skip(request, response):    return &quot;health/probe&quot; in request.url._url# mask event not using async modedef mask_event(eventmodel):    # Your custom code to change or remove any sensitive fields    if &#39;password&#39; in eventmodel.response.body:        eventmodel.response.body[&#39;password&#39;] = None    return eventmodelmoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: False,    &#39;IDENTIFY_USER&#39;: identify_user,    &#39;IDENTIFY_COMPANY&#39;: identify_company,    &#39;GET_METADATA&#39;: get_metadata,    &#39;SKIP&#39;: should_skip,    &#39;MASK_EVENT_MODEL&#39;: mask_event,    &#39;CAPTURE_OUTGOING_REQUESTS&#39;: False,}app = FastAPI()app.add_middleware(MoesifMiddleware, settings=moesif_settings)You can use OAuth2 in your FastAPI app with this middleware. For more information, see OAuth2 with Password (and hashing), Bearer with JWT tokens.Tested versionsMoesif has validated this middleware against the following frameworks and framework versions:            Framework      Version                  fastapi      &amp;gt; 0.51.0              fastapi      &amp;gt; 0.78.0              fastapi      &amp;gt; 0.108.0              fastapi      &amp;gt; 0.115.5      Examples  View example app with FastAPI.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/python-asgi/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-django": {
      "title": "Server Integration Guide - Python (Django)",
      "content"	 : "Moesif Middleware for Python Djangoby Moesif, the API analytics and API monetization platform.Moesif middleware for Django automatically logs incoming and outgoing API callsand sends them to Moesif for API analytics and monitoring.This SDK uses the Requests library and works for Python versions 2.7 up to 3.10.4.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall with pip:pip install moesifdjangoConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseIn your Django settings file, add moesifdjango.middleware.moesif_middlewareto the MIDDLEWARE array:MIDDLEWARE = [    &#39;django.middleware.security.SecurityMiddleware&#39;,    &#39;django.contrib.sessions.middleware.SessionMiddleware&#39;,    &#39;django.middleware.common.CommonMiddleware&#39;,    &#39;django.middleware.csrf.CsrfViewMiddleware&#39;,    &#39;django.contrib.auth.middleware.AuthenticationMiddleware&#39;,    &#39;moesifdjango.middleware.moesif_middleware&#39;,    &#39;django.contrib.messages.middleware.MessageMiddleware&#39;,    &#39;django.middleware.clickjacking.XFrameOptionsMiddleware&#39;,]Because of middleware execution order, we highly recommend that you add moesif_middleweare after SessionMiddleware and AuthenticationMiddleware. These Django middleware add useful session data that enables deeper error analysis. On the other hand, if you have other middleware that modifies responses before going out, you may choose to place Moesif middleware before the middleware that modifies responses. This allows Moesif to see the modifications to the response data and see closer to what goes over the wire.Changes in Django 1.10Django middleware style and setup was refactored in version 1.10. You need need to import the correct version of Moesif middleware depending on your Django version:  For Django 1.10 or greater, use moesifdjango.middleware.moesif_middleware.  For Django 1.9 or older, you need to follow the legacy style for importing middleware and use moesifdjango.middleware_pre19.MoesifMiddlewarePre19 instead.To find your current Django version, you can execute the following command in your terminal:python -c &quot;import django; print(django.get_version())&quot;Django 1.10 or NewerDjango 1.10 renamed MIDDLEWARE_CLASSES to MIDDLEWARE. Therefore, for Django 1.10 or newer, you must activate your middleware by adding it to the MIDDLEWARE list:MIDDLEWARE = [    ...,    &#39;django.contrib.sessions.middleware.SessionMiddleware&#39;,    &#39;django.middleware.common.CommonMiddleware&#39;,    &#39;django.contrib.auth.middleware.AuthenticationMiddleware&#39;,    &#39;moesifdjango.middleware.moesif_middleware&#39;    ...]Then add a dictionary MOESIF_MIDDLEWARE to your Django settings file:MOESIF_MIDDLEWARE = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,}Django 1.9 or OlderActivate the middleware by adding it to the MIDDLEWARE_CLASSES list in your Django settings file:MIDDLEWARE_CLASSES = [    ...,    &#39;moesifdjango.middleware_pre19.MoesifMiddlewarePre19&#39;,    # other middlewares]Then add a dictionary MOESIF_MIDDLEWARE to your Django settings file:MOESIF_MIDDLEWARE = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,}The dictionary contains the configuration options forthe middleware, including your Moesif Application ID that you must specify.Optional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third party services through by setting the CAPTURE_OUTGOING_REQUESTS option.For configuration options specific to capturing outgoing API calls, see Options For Outgoing API Calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailSolve Timezone Issue with DockerWhen using Docker with Ubuntu-based image, events may not be captured if the image fails to find any timezone configuration. To solve this issue, add the following line to your Dockerfile:ENV TZ=UTCOtherwise, you can add RUN apt-get install tzdata in the Dockerfile.Repository Structure.├── BUILDING.md├── images/├── LICENSE├── MANIFEST.in├── moesifdjango/├── pull_request_template.md├── README.md├── requirements.txt├── setup.cfg├── setup.py└── tests/Configuration optionsThe following sections describe the available configuration options for this middleware. You have to set these options in a Python dictionary MOESIF_MIDDLEWARE. See the examples for better understanding.APPLICATION_ID (Required)         Data type              String     A string that identifies your application in Moesif.Options specific to Incoming API CallsThe following options document the configuration options to use for incoming API calls.Several options use request and response as input arguments. These correspond to Django’s request and response objects.SKIP         Data type          Parameters          Return type              Function          (request, response)          Boolean     Optional.This function takes Requests Request and Response objects and returns True if you want to skip this particular event.IDENTIFY_USER         Data type          Parameters          Return type              Function          (request, response)          String     Optional, but highly recommended.This function takes a request and a response and returns a string that representsthe user ID used by your system.Moesif tries to identify users automatically and fetch the username from django.http.HttpRequest.user. However, if implementation differs, we highly recommend that you accurately provide auser ID using this function.IDENTIFY_COMPANY         Data type          Parameters          Return type              Function          (request, response)          String     Optional.A function that takes a request and a response and returns a string that represents the company ID for this event.GET_SESSION_TOKEN         Data type          Parameters          Return type              Function          (request, response)          String     Optional.A function that takes a request and a response, and returns a string that represents the session token for this event.Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.GET_METADATA         Data type          Parameters          Return type              Function          (request, response)          Dictionary     Optional.A function that takes a request and a response and returns a Python dictionary.The dictionary must be such that it can be converted into valid JSON. This allows you to associate this event with custom metadata. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.LOG_BODY         Data type          Default              Boolean          True     Optional.Whether to log request and response body to Moesif.Set to False to remove the HTTP body before sending to Moesif.If you want more control over which fields the middleware includes or not, see the next option MASK_EVENT_MODEL.MASK_EVENT_MODEL         Data type          Parameters          Return type              Function          (EventModel)          EventModel     Optional.A function that takes the final Moesif event model and returns an EventModel object with desired data removed.Use this if you prefer to write your own mask function than uses the string based filter options:  REQUEST_BODY_MASKS  REQUEST_HEADER_MASKS  RESPONSE_BODY_MASKS  RESPONSE_HEADER_MASKSThe return value must be a valid EventModel required by Moesif data ingestion API. For more information about Moesif event model, see Moesif Python API documentation.BATCH_SIZE         Data type          Default              int          25     Optional.Specifies the maximum batch size when sending to Moesif.EVENT_QUEUE_SIZE         Data type          Default              int          1000_000     Optional.The maximum number of events to hold in queue before sending to Moesif.In case of network issues, the middleware may fail to connect or send event to Moesif. In those cases, the middleware skips adding new to event to queue to prevent memory overflow.AUTHORIZATION_HEADER_NAME         Data type          Default              String          authorization     Optional.A request header field name used to identify the User in Moesif. It also supports a comma separated string. Moesif checks headers in order like &quot;X-Api-Key,Authorization&quot;.AUTHORIZATION_USER_ID_FIELD         Data type          Default              String          sub     Optional.A field name used to parse the user from authorization header in Moesif.BASE_URI         Data type              String     Optional.A local proxy hostname when sending traffic through secure proxy. Remember to set this field when using secure proxy. For more information, see Secure Proxy documentation..Options For Outgoing API CallsThe following options apply to outgoing API calls. These are calls you initiate using the Python Requests library to third parties like Stripe or to your own services.Several options use request and response as input arguments. These correspond to the Requests library’s request or response objects.If you are not using Django, you can import moesifpythonrequest directly.CAPTURE_OUTGOING_REQUESTS         Data type          Default              Boolean          False     Set to True to capture all outgoing API calls.GET_METADATA_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Dictionary     Optional.A function that enables you to return custom metadata associated with the logged API calls.Takes in the Requests request and response objects as arguments.We recommend that you implement a function thatreturns a dictionary containing your custom metadata. The dictionary must be a valid one that can be encoded into JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.SKIP_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Boolean     Optional.A function that takes a Requests request and response objects,and returns True if you want to skip this particular event.IDENTIFY_USER_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional, but highly recommended.A function that takes Requests request and response objects, and returns a string that represents the user ID used by your system.While Moesif tries to identify users automatically, different frameworks and your implementation might vary. So we highly recommend that you accurately provide auser ID using this function.IDENTIFY_COMPANY_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects and returns a string that represents the company ID for this event.GET_SESSION_TOKEN_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that corresponds to the session token for this event.Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.General optionsLOG_BODY_OUTGOING         Data type          Default              Boolean          True     Optional.Set to False to remove logging request and response body.LOCAL_DEBUG         Data type              Boolean     Optional.Set to True to print internal log messages for debugging SDK integration issues.ExamplesSee the Moesif Django Example for a complete Django application that uses this middleware.The following shows a sample Django settings file with different configuration options.def identify_user(req, res):    # Your custom code that returns a user id string    if req.user and req.user.is_authenticated:        return req.user.username    else:        return Nonedef identify_company(req, res):    # Your custom code that returns a company id string    return &quot;67890&quot;def should_skip(req, res):    # Your custom code that returns true to skip logging    return &quot;health/probe&quot; in req.pathdef get_token(req, res):    # If you don&#39;t want to use the standard Django session token,    # add your custom code that returns a string for session/API token    return &quot;XXXXXXXXXXXXXX&quot;def mask_event(eventmodel):    # Your custom code to change or remove any sensitive fields    if &#39;password&#39; in eventmodel.response.body:        eventmodel.response.body[&#39;password&#39;] = None    return eventmodeldef get_metadata(req, res):    return {        &#39;datacenter&#39;: &#39;westus&#39;,        &#39;deployment_version&#39;: &#39;v1.2.3&#39;,    }MOESIF_MIDDLEWARE = {    &#39;APPLICATION_ID&#39;: &#39;Your application id&#39;,    &#39;LOCAL_DEBUG&#39;: False,    &#39;LOG_BODY&#39;: True,    &#39;IDENTIFY_USER&#39;: identify_user,    &#39;IDENTIFY_COMPANY&#39;: identify_company,    &#39;GET_SESSION_TOKEN&#39;: get_token,    &#39;SKIP&#39;: should_skip,    &#39;MASK_EVENT_MODEL&#39;: mask_event,    &#39;GET_METADATA&#39;: get_metadata,}The following examples demonstrate how to add and update customer information using the middleware.Update A Single UserTo create or update a user profile in Moesif, use the update_user() method.middleware = MoesifMiddleware(None)# Only user_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schema# metadata can be any custom objectuser = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_user = middleware.update_user(user)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field. This method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Update Users in BatchTo update a list of users in one batch, use the update_users_batch() method.middleware = MoesifMiddleware(None)userA = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}userB = {  &#39;user_id&#39;: &#39;54321&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;mary@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;Mary&#39;,    &#39;last_name&#39;: &#39;Jane&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 48000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_users = middleware.update_users_batch([userA, userB])The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field. This method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Update A Single CompanyTo update a single company, use the update_company() method.middleware = MoesifMiddleware(None)# Only company_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schema# metadata can be any custom objectcompany = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}update_company = middleware.update_company(company)The metadata field can contain any company demographic or other info you want to store. Moesif only requires the company_id field. This method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Update Companies in BatchTo update a list of companies in one batch, use the update_companies_batch() method.middleware = MoesifMiddleware(None)companyA = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}companyB = {  &#39;company_id&#39;: &#39;09876&#39;,  &#39;company_domain&#39;: &#39;contoso.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Contoso, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 48000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 53    },  }}update_companies = middleware.update_companies_batch([userA, userB])The metadata field can contain any company demographic or other info you want to store. Moesif only requires the company_id field. This method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Update SubscriptionUpdate A Single SubscriptionTo create or update a subscription in Moesif, use the update_subscription method.middleware = MoesifMiddleware(None)# Only subscription_id is required.# metadata can be any custom objectsubscription = {  &#39;subscription_id&#39;: &#39;sub_67890&#39;,  &#39;company_id&#39;: &#39;3456&#39;,  &#39;status&#39;: &#39;active&#39;  &#39;metadata&#39;: {    &#39;plan_name&#39;: &#39;Pro&#39;,    &#39;signup_date&#39;: &#39;2020-09-09&#39;,    &#39;expiration_date&#39;: &#39;2021-09-09&#39;,    &#39;payment_method&#39;: &#39;credit_card&#39;,    &#39;mrr&#39;: 12000,    &#39;currency&#39;: &#39;USD&#39;  }}update_subscription = middleware.update_subscription(subscription)The metadata field can store any subscription-related information. Moesif only requires the the following fields:  subscription_id  company_id  statusThis method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Update Subscriptions in BatchTo update a list of subscriptions in one batch, use the update_subscriptions_batch method.middleware = MoesifMiddleware(None)subscriptionA = {  &#39;subscription_id&#39;: &#39;sub_67890&#39;,  &#39;company_id&#39;: &#39;3456&#39;,  &#39;status&#39;: &#39;active&#39;  &#39;metadata&#39;: {    &#39;plan_name&#39;: &#39;Pro&#39;,    &#39;signup_date&#39;: &#39;2020-09-09&#39;,    &#39;expiration_date&#39;: &#39;2021-09-09&#39;,    &#39;payment_method&#39;: &#39;credit_card&#39;,    &#39;mrr&#39;: 12000,    &#39;currency&#39;: &#39;USD&#39;  }}subscriptionB = {  &#39;subscription_id&#39;: &#39;sub_54321&#39;,  &#39;company_id&#39;: &#39;6789&#39;,  &#39;status&#39;: &#39;active&#39;  &#39;metadata&#39;: {    &#39;plan_name&#39;: &#39;Enterprise&#39;,    &#39;signup_date&#39;: &#39;2020-10-01&#39;,    &#39;expiration_date&#39;: &#39;2021-10-01&#39;,    &#39;payment_method&#39;: &#39;paypal&#39;,    &#39;mrr&#39;: 24000,    &#39;currency&#39;: &#39;USD&#39;  }}update_subscriptions = middleware.update_subscriptions_batch([subscriptionA, subscriptionB])The metadata field can store any subscription-related information. Moesif only requires the the following fields:  subscription_id  company_id  statusThis method is a convenient helper that calls the Moesif API library.For more information, see Moesif Python API reference.Tested Python and Django VersionsMoesif has validated this middleware against the following combinations of Python and Django versions:            Python      Django                  Python 2.7      1.11.22              Python 2.7      1.11.22              Python 2.7      1.9              Python 3.4.5      1.11.22              Python 3.4.5      1.11.22              Python 3.4.5      1.9              Python 3.6.4      1.11.22              Python 3.6.4      1.11.22              Python 3.6.4      1.9              Python 3.10.4      3.2.13 LTS              Python 3.10.4      4.0.5      How to Test  Manually clone this repository.  From your terminal, navigate to the root directory of the middleware.  Run pip install Django and then run pip install moesifdjango.  Add your Moesif Application ID to tests/settings.py.      From terminal, navigate to the root directory of the middleware tests tests/.    a. Run python manage.py test if you are using Django 1.10 or newer.    b. Run python manage.py test middleware_pre19_tests if you are using Django 1.9 or older.  TroubleshootOn MacOS, with gunicorn, it is possible to encounter this error: “in progress in another thread when fork() was called”. Solution is to add --preload option when launching gunicorn like below.gunicorn myapp.wsgi:application --bind 127.0.0.1:8000 --preloadExplore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/django/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-pythonrequest": {
      "title": "Server Integration Guide - Python Requests",
      "content"	 : "Moesif for Python Requestsby Moesif, the API analytics and API monetization platform.It’s an interceptor for Python Requests library that captures outgoing API calls and sends to Moesif for API analytics and monitoring.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.  If you are using Moesif’s API monitoring SDKs like Moesif Django or Moesif WSGI to log incoming API calls, this library is already included.PrerequisitesBefore using Moesif for Python Requests, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.InstallInstall with pip:pip install moesifpythonrequestConfigureSee the available configuration options to learn how to configure moesifpythonrequest for your use case.How to UseImport the Moesif library and call the start_capture_outgoing method.Moesif will start logging all API calls made from the Requests library.from moesifpythonrequest.start_capture.start_capture import StartCaptureimport requestsmoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;}def main():    # Outgoing API call to third party like Github / Stripe or to your own dependencies    response = requests.get(&quot;http://httpbin.org/uuid&quot;)    print(response.json())StartCapture().start_capture_outgoing(moesif_settings)main()Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── images/├── LICENSE├── MANIFEST.in├── moesifpythonrequest/├── README.md├── register.py├── requirements.txt├── setup.cfg└── setup.pyConfiguration optionsThe following sections describe the available configuration options. You have to set these options in a Python dictionary and pass that as an argument as you call the start_capture_outgoing method. See the example for better understanding.APPLICATION_ID (Required)         Data type              String     A string that identifies your application in Moesif.GET_METADATA_OUTGOINGtable&amp;gt;       Data type          Parameters          Return type            Function          (req, res)          Dictionary     &amp;lt;/table&amp;gt;Optional.A function that enables you to return custom metadata associated with the logged API calls.Takes in the Requests request and response objects as arguments.We recommend that you implement a function thatreturns a dictionary containing your custom metadata. The dictionary must be a valid one that can be encoded into JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.IDENTIFY_USER_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional, but highly recommended.A function that takes Requests request and response objects, and returns a string that represents the user ID used by your system.While Moesif tries to identify users automatically, different frameworks and your implementation might vary. So we highly recommend that you accurately provide a user ID using this function.IDENTIFY_COMPANY_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects and returns a string that represents the company ID for this event.GET_SESSION_TOKEN_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that corresponds to the session token for this event.Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.LOG_BODY_OUTGOING         Data type          Default              Boolean          True     Optional.Set to False to remove logging request and response body.SKIP_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Boolean     Optional.A function that takes a Requests request and response objects,and returns True if you want to skip this particular event.MASK_EVENT_MODEL         Data type          Parameters          Return type              Function          (EventModel)          EventModel     Optional.A function that takes the final Moesif event model and returns an EventModel object with desired data removed.For more information about Moesif event model, see Moesif Python API documentation.ExamplesAn example Moesif integration is available on GitHub.How to Get HelpIf you face any issues, try the troubheshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/pythonrequest/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-tornado": {
      "title": "Server Integration Guide - Python Tornado",
      "content"	 : "Moesif Middleware for Python Tornado based FrameworksTornado middleware that automatically logs incoming API calls and sends to Moesif for API analytics and monitoring.Supports Python Frameworks built on Tornado.Source Code on GitHubHow to installpip install moesiftornadoHow to usefrom moesiftornado import MoesifMiddlewareimport tornado.webimport jsonclass MainHandler(tornado.web.RequestHandler):    def get(self):        self.write(json.dumps({ &quot;msg&quot;: &quot;Hello, world&quot; }))moesif_config = {    &#39;APPLICATION_ID&#39;: &#39;Your Moesif Application id&#39;,    &#39;LOG_BODY&#39;: True,    # ... For other options see below.}# Create a moesif middlewaremiddleware = MoesifMiddleware(moesif_config)# Set the log_function to middleware.log_event to log the events to Moesifapplication = tornado.web.Application([(r&quot;/&quot;, MainHandler)], log_function=middleware.log_event)Your Moesif Application Id can be found in the Moesif Portal.After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.You can always find your Moesif Application Id at any time by logging into the Moesif Portal, click on the top right menu,and then clicking API Keys.Configuration optionsAPPLICATION_ID(required), string, is obtained via your Moesif Account, this is required.SKIP(optional) (handler) =&amp;gt; boolean, a function that takes a Request handler,and returns true if you want to skip this particular event.IDENTIFY_USER(optional, but highly recommended) (handler) =&amp;gt; string, a function that takes a Request handler, and returns a string that is the user id used by your system. While Moesif tries to identify users automatically,but different frameworks and your implementation might be very different, it would be helpful and much more accurate to provide this function.IDENTIFY_COMPANY(optional) (handler) =&amp;gt; string, a function that takes a Request handler, and returns a string that is the company id for this event.GET_METADATA(optional) (handler) =&amp;gt; dictionary, a function that takes a Request handler, andreturns a dictionary (must be able to be encoded into JSON). This allows yourto associate this event with custom metadata. For example, you may want to save a VM instance_id, a trace_id, or a tenant_id with the request.GET_SESSION_TOKEN(optional) (handler) =&amp;gt; string, a function that takes a Request handler, and returns a string that is the session token for this event. Again, Moesif tries to get the session token automatically, but if you setup is very different from standard, this function will be very helpful for tying events together, and help you replay the events.MASK_EVENT_MODEL(optional) (EventModel) =&amp;gt; EventModel, a function that takes an EventModel and returns an EventModel with desired data removed. The return value must be a valid EventModel required by Moesif data ingestion API. For details regarding EventModel please see the Moesif Python API Documentation.DEBUG(optional) boolean, a flag to see debugging messages.LOG_BODY(optional) boolean, default True, Set to False to remove logging request and response body.BATCH_SIZE(optional) int, default 25, Maximum batch size when sending to Moesif.AUTHORIZATION_HEADER_NAME(optional) string, A request header field name used to identify the User in Moesif. Default value is authorization. Also, supports a comma separated string. We will check headers in order like &quot;X-Api-Key,Authorization&quot;.AUTHORIZATION_USER_ID_FIELD(optional) string, A field name used to parse the User from authorization header in Moesif. Default value is sub.BASE_URI(optional) string, A local proxy hostname when sending traffic via secure proxy. Please set this field when using secure proxy. For more details, refer secure proxy documentation.Example:from moesiftornado import MoesifMiddlewareimport tornado.webdef identify_user(handler):    # Your custom code that returns a user id string    return &quot;my_user_id&quot;def identify_company(handler):    # Your custom code that returns a company id string    return &quot;my_company_id&quot;def get_token(handler):    # Your custom code that returns a string for session/API token    return &quot;XXXXXXXXXXXXXX&quot;def should_skip(handler):    # Your custom code that returns true to skip logging    return &quot;health/probe&quot; in handler.request.full_url()def mask_event(event_model):    # Your custom code to change or remove any sensitive fields    if &#39;password&#39; in event_model.request.body:        event_model.request.body[&#39;password&#39;] = None    return event_modeldef get_metadata(handler):    return {        &#39;datacenter&#39;: &#39;westus&#39;,        &#39;deployment_version&#39;: &#39;v1.2.3&#39;,    }moesif_config = {    &#39;APPLICATION_ID&#39;: &#39;Your Moesif Application Id&#39;,    &#39;LOG_BODY&#39;: True,    &#39;DEBUG&#39;: False,    &#39;IDENTIFY_USER&#39;: identify_user,    &#39;IDENTIFY_COMPANY&#39;: identify_company,    &#39;GET_SESSION_TOKEN&#39;: get_token,    &#39;SKIP&#39;: should_skip,    &#39;MASK_EVENT_MODEL&#39;: mask_event,    &#39;GET_METADATA&#39;: get_metadata,}middleware = MoesifMiddleware(moesif_config)application = tornado.web.Application([(r&quot;/&quot;, MainHandler)], log_function=middleware.log_event)Update UserUpdate A Single UserCreate or update a user profile in Moesif.The metadata field can be any customer demographic or other info you want to store.Only the user_id field is required.For details, visit the Python API Reference.from moesiftornado import MoesifMiddlewaremiddleware = MoesifMiddleware(moesif_config)# Only user_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schema# metadata can be any custom objectuser_profile = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,     &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}middleware.update_user(user_profile)Update Users in BatchSimilar to update_user, but used to update a list of users in one batch. Only the user_id field is required.For details, visit the Python API Reference.from moesiftornado import MoesifMiddlewaremiddleware = MoesifMiddleware(moesif_config)userA = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}userB = {  &#39;user_id&#39;: &#39;54321&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;mary@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;Mary&#39;,    &#39;last_name&#39;: &#39;Jane&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 48000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}middleware.update_users_batch([userA, userB])Update CompanyUpdate A Single CompanyCreate or update a company profile in Moesif.The metadata field can be any company demographic or other info you want to store.Only the company_id field is required.For details, visit the Python API Reference.from moesiftornado import MoesifMiddlewaremiddleware = MoesifMiddleware(moesif_config)# Only company_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schema# metadata can be any custom objectcompany_profile = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info   &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,     &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}middleware.update_company(company_profile)Update Companies in BatchSimilar to update_company, but used to update a list of companies in one batch. Only the company_id field is required.For details, visit the Python API Reference.from moesiftornado import MoesifMiddlewaremiddleware = MoesifMiddleware(moesif_config)companyA = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info   &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}companyB = {  &#39;company_id&#39;: &#39;09876&#39;,  &#39;company_domain&#39;: &#39;contoso.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info   &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Contoso, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 48000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 53    },  }}middleware.update_companies_batch([companyA, companyB])Tested versionsMoesif has validated moesiftornado against the following combinations.            Python      Tornado                  Python 2.7      4.4.1      ExampleAn example Moesif integration based on quick start tutorial of Tornado:Moesif Tornado ExampleOther integrationsTo view more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /server-integration/tornado/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-python-wsgi": {
      "title": "Server Integration Guide - Python WSGI (Flask, Bottle, Pyramid)",
      "content"	 : "Moesif Middleware for Python WSGI-based Frameworksby Moesif, the API analytics and API monetization platform.With Moesif middleware for Python WSGI-based frameworks, you can automatically log API callsand send them to Moesif for API analytics and monitoring.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.OverviewThis middleware allows you to integrate Moesif’s API analytics andAPI monetization features with minimal configuration into APIs that are built on Python WSGI-based (Web Server Gateway Interface) frameworks.WSGI (Web Server Gateway Interface)is a standard (PEP 3333) that describeshow a web server communicates with web applications. Many Python Frameworksare build on top of WSGI, such as Flask,Bottle, and Pyramid.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall with pip using the following command:pip install moesifwsgiConfigure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to UseFlaskWrap your wsgi_app with the Moesif middleware.from moesifwsgi import MoesifMiddlewaremoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    # ... For other options see below.}app.wsgi_app = MoesifMiddleware(app.wsgi_app, moesif_settings)Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.For an example with Flask, see the /examples/flask folder of this repository.BottleWrap your Bottle application with the Moesif middleware:from moesifwsgi import MoesifMiddlewareapp = bottle.Bottle()moesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    # ... For other options see below.}bottle.run(app=MoesifMiddleware(app, moesif_settings))Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.For an example with Bottle, see the /examples/bottle folder of this repository.Pyramidfrom pyramid.config import Configuratorfrom moesifwsgi import MoesifMiddlewareif __name__ == &#39;__main__&#39;:    config = Configurator()    config.add_route(&#39;hello&#39;, &#39;/&#39;)    config.scan()    app = config.make_wsgi_app()    # configure your moesif settings    moesif_settings = {        &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,        &#39;LOG_BODY&#39;: True,        # ... For other options see below.    }    # Put middleware    app = MoesifMiddleware(app, moesif_settings)    server = make_server(&#39;0.0.0.0&#39;, 8080, app)    server.serve_forever()Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.Other WSGI FrameworksIf you are using a framework that is built on top of WSGI, it should work just by adding the Moesif middleware.Please read the documentation for your specific framework on how to add middlewares.Optional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third party services through by setting the CAPTURE_OUTGOING_REQUESTS option:from moesifwsgi import MoesifMiddlewarefrom flask import Flaskmoesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;LOG_BODY&#39;: True,    &#39;CAPTURE_OUTGOING_REQUESTS&#39;: False}app = Flask(__name__)app.wsgi_app = MoesifMiddleware(app.wsgi_app, moesif_settings)For configuration options specific to capturing outgoing API calls, see Options For Outgoing API Calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailThread Pool IssuesThis library manages a thread pool to send data to Moesif in the background without impacting your app’s latency.However, the preload feature of Gunicorn (or preload-app for Hypercorn) may interfere with the thread pool before the worker is forked. If you encounter issues, avoid setting preload to True.Solve Timezone Issue with DockerWhen using Docker with Ubuntu-based image, events may not be captured if the image fails to find any timezone configuration. To solve this issue, add the following line to your Dockerfile:ENV TZ=UTCOtherwise, you can add RUN apt-get install tzdata in the Dockerfile.Repository Structure.├── BUILDING.md├── examples/├── images/├── LICENSE├── MANIFEST.in├── moesifwsgi/├── README.md├── requirements.txt├── setup.cfg└── setup.pyConfiguration optionsThe following sections describe the available configuration options for this middleware. You can set these options in a Python dictionary and then pass that as a parameter when you create the middleware instance. See the examples/ folder for better understanding.Notice the following about the configuration options:  The app is the original WSGI app instance.  The environ is a WSGI environ.Moesif also adds the following keys to environ:      environ[&#39;moesif.request_body&#39;]: a JSON object or base64 encoded string if couldn’t parse the request body as JSON        environ[&quot;moesif.response_body_chunks&quot;]: a response body chunks        environ[&quot;moesif.response_headers&quot;]: a dictionary representing the response headers  APPLICATION_ID         Data type              String     A string that identifies your application in Moesif.SKIP         Data type          Parameters          Return type              Function          (app, environ)          Boolean     Optional.A function that takes a WSGI application and an environ object,and returns True if you want to skip this particular event.IDENTIFY_USER         Data type          Parameters          Return type              Function          (app, environ, response_headers)          String     Optional, but highly recommended.A function with the following arguments:  A WSGI application  An environ object  An optional parameter for response headersReturns returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.IDENTIFY_COMPANY         Data type          Parameters          Return type              Function          (app, environ, response_headers)          String     Optional.A function with the following arguments:  A WSGI application  An environ object  An optional parameter for response headersReturns a string that represents the company ID for this event.GET_METADATA         Data type          Parameters          Return type              Function          (app, environ)          Dictionary     Optional.A function that takes a WSGI application and an environ object, andreturns a dictionary.This function allows youto add custom metadata that Moesif can associate with the event. The metadata must be a simple Python dictionary that can be converted to JSON.For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.GET_SESSION_TOKEN         Data type          Parameters          Return type              Function          (app, environ)          String     Optional.A function that takes a WSGI application and an environ, and returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, provide this function to help identify sessions.MASK_EVENT_MODEL         Data type          Parameters          Return type              Function          (EventModel)          EventModel     Optional.A function that takes the final Moesif event model and returns an event model with desired data removed.The return value must be a valid eventt model required by Moesif data ingestion API. For more information about the EventModel object, see the Moesif Python API documentation.DEBUG         Data type              Boolean     Optional.Set to True to print debug logs if you’re having integration issues.LOG_BODY         Data type          Default              Boolean          True     Optional.Whether to log request and response body to Moesif.EVENT_QUEUE_SIZE         Data type          Default              int          1000_000     Optional.The maximum number of event objects queued in memory pending upload to Moesif. For a full queue, additional calls to MoesifMiddleware returns immediately without logging the event. Therefore, set this option based on the event size and memory capacity you expect.EVENT_WORKER_COUNT         Data type          Default              int          2     Optional.The number of worker threads to use for uploading events to Moesif.If you have a large number of events being logged, increasing this number can improve upload performance.BATCH_SIZE         Data type          Default              int          100     An optional field name that specifies the maximum batch size when sending to Moesif.EVENT_BATCH_TIMEOUT         Data type          Default              int          1     Optional.Maximum time in seconds to wait before sending a batch of events to Moesif when reading from the queue.AUTHORIZATION_HEADER_NAME         Data type          Default              String          authorization     Optional.A request header field name used to identify the User in Moesif. It also supports a comma separated string. Moesif checks headers in order like &quot;X-Api-Key,Authorization&quot;.AUTHORIZATION_USER_ID_FIELD         Data type          Default              String          sub     Optional.A field name used to parse the user from authorization header in Moesif.BASE_URI         Data type              String     Optional.A local proxy hostname when sending traffic through secure proxy. Remember to set this field when using secure proxy. For more information, see Secure Proxy documentation..Options For Outgoing API CallsThe following options apply to outgoing API calls. These are calls you initiate using the Python Requests library to third parties like Stripe or to your own services.Several options use request and response as input arguments. These correspond to the Requests library’s request or response objects.If you are not using WSGI, you can import moesifpythonrequest directly.CAPTURE_OUTGOING_REQUESTS         Data type          Default              Boolean          False     Set to True to capture all outgoing API calls.GET_METADATA_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Dictionary     Optional.A function that enables you to return custom metadata associated with the logged API calls.Takes in the Requests request and response objects as arguments.We recommend that you implement a function thatreturns a dictionary containing your custom metadata. The dictionary must be a valid one that can be encoded into JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a resource ID with the request.SKIP_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          Boolean     Optional.A function that takes a Requests request and response objects,and returns True if you want to skip this particular event.IDENTIFY_USER_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional, but highly recommended.A function that takes Requests request and response objects, and returns a string that represents the user ID used by your system.While Moesif tries to identify users automatically, different frameworks and your implementation might vary. So we highly recommend that you accurately provide auser ID using this function.IDENTIFY_COMPANY_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that represents the company ID for this event.GET_SESSION_TOKEN_OUTGOING         Data type          Parameters          Return type              Function          (req, res)          String     Optional.A function that takes Requests request and response objects, and returns a string that corresponds to the session token for this event.Similar to user IDs, Moesif tries to get the session token automatically. However, if you setup differs from the standard, this function can help tying up events together and help you replay the events.LOG_BODY_OUTGOING         Data type          Default              Boolean          True     Optional.Set to False to remove logging request and response body.ExamplesSee the examples/ directory for example applications using Flask, Falcon, and Bottle frameworks.Here’s a Flask example:def identify_user(app, environ, response_headers=dict()):    # Your custom code that returns a user id string    return &quot;12345&quot;def identify_company(app, environ, response_headers=dict()):    # Your custom code that returns a company id string    return &quot;67890&quot;def should_skip(app, environ):    # Your custom code that returns true to skip logging    return &quot;health/probe&quot; in environ.get(&#39;PATH_INFO&#39;, &#39;&#39;)def get_token(app, environ):    # If you don&#39;t want to use the standard WSGI session token,    # add your custom code that returns a string for session/API token    return &quot;XXXXXXXXXXXXXX&quot;def mask_event(eventmodel):    # Your custom code to change or remove any sensitive fields    if &#39;password&#39; in eventmodel.response.body:        eventmodel.response.body[&#39;password&#39;] = None    return eventmodeldef get_metadata(app, environ):    return {        &#39;datacenter&#39;: &#39;westus&#39;,        &#39;deployment_version&#39;: &#39;v1.2.3&#39;,    }moesif_settings = {    &#39;APPLICATION_ID&#39;: &#39;YOUR_MOESIF_APPLICATION_ID&#39;,    &#39;DEBUG&#39;: False,    &#39;LOG_BODY&#39;: True,    &#39;IDENTIFY_USER&#39;: identify_user,    &#39;IDENTIFY_COMPANY&#39;: identify_company,    &#39;GET_SESSION_TOKEN&#39;: get_token,    &#39;SKIP&#39;: should_skip,    &#39;MASK_EVENT_MODEL&#39;: mask_event,    &#39;GET_METADATA&#39;: get_metadata,    &#39;CAPTURE_OUTGOING_REQUESTS&#39;: False}app.wsgi_app = MoesifMiddleware(app.wsgi_app, moesif_settings)The following examples demonstrate how to add and update customer information.Update A Single UserTo create or update a user profile in Moesif, use the update_user() function.api_client = MoesifAPIClient(&quot;Your Moesif Application Id&quot;).api# Only user_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schema# metadata can be any custom objectuser = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_user = api_client.update_user(user)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif Python API Reference.Update Users in BatchTo update a list of users in one batch, use the update_users_batch() function.api_client = MoesifAPIClient(&quot;Your Moesif Application Id&quot;).apiuserA = {  &#39;user_id&#39;: &#39;12345&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;john@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;John&#39;,    &#39;last_name&#39;: &#39;Doe&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 24000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}userB = {  &#39;user_id&#39;: &#39;54321&#39;,  &#39;company_id&#39;: &#39;67890&#39;, # If set, associate user with a company object  &#39;metadata&#39;: {    &#39;email&#39;: &#39;mary@acmeinc.com&#39;,    &#39;first_name&#39;: &#39;Mary&#39;,    &#39;last_name&#39;: &#39;Jane&#39;,    &#39;title&#39;: &#39;Software Engineer&#39;,    &#39;sales_info&#39;: {        &#39;stage&#39;: &#39;Customer&#39;,        &#39;lifetime_value&#39;: 48000,        &#39;account_owner&#39;: &#39;mary@contoso.com&#39;    },  }}update_users = api_client.update_users_batch([userA, userB])The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif Python API Reference.Update A Single CompanyTo update a single company, use the update_company() function.api_client = MoesifAPIClient(&quot;Your Moesif Application Id&quot;).api# Only company_id is required.# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schema# metadata can be any custom objectcompany = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;campaign&#39;: {    &#39;utm_source&#39;: &#39;google&#39;,    &#39;utm_medium&#39;: &#39;cpc&#39;,    &#39;utm_campaign&#39;: &#39;adwords&#39;,    &#39;utm_term&#39;: &#39;api+tooling&#39;,    &#39;utm_content&#39;: &#39;landing&#39;  },  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}update_company = api_client.update_company(company)The metadata field can contain any company demographic or other information you want to store. Moesif only requires the company_id field. For more information, see the function documentation in Moesif Python API Reference.Update Companies in BatchTo update a list of companies in one batch, use the update_companies_batch() function.api_client = MoesifAPIClient(&quot;Your Moesif Application Id&quot;).apicompanyA = {  &#39;company_id&#39;: &#39;67890&#39;,  &#39;company_domain&#39;: &#39;acmeinc.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Acme, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 24000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 47    },  }}companyB = {  &#39;company_id&#39;: &#39;09876&#39;,  &#39;company_domain&#39;: &#39;contoso.com&#39;, # If domain is set, Moesif will enrich your profiles with publicly available info  &#39;metadata&#39;: {    &#39;org_name&#39;: &#39;Contoso, Inc&#39;,    &#39;plan_name&#39;: &#39;Free&#39;,    &#39;deal_stage&#39;: &#39;Lead&#39;,    &#39;mrr&#39;: 48000,    &#39;demographics&#39;: {        &#39;alexa_ranking&#39;: 500000,        &#39;employee_count&#39;: 53    },  }}update_companies = api_client.update_companies_batch([companyA, companyB])The metadata field can contain any company demographic or other information you want to store. Moesif only requires the company_id field. For more information, see the function documentation in Moesif Python API Reference.How to Get HelpIf you face any issues using this middleware, try the troubleshooting guidelines. For further assistance, reach out to our support team.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/python-wsgi/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-rack": {
      "title": "Server Integration Guide - Ruby (Rack, Rails)",
      "content"	 : "Moesif Middleware for Ruby on Rails and Rackby Moesif, the API analytics and API monetization platform.Moesif Rack Middleware automatically logs incoming and outgoing API calls and sends them to Moesif for API analytics and monitoring.This middleware allows you to integrate Moesif’s API analytics and API monetization features into your Ruby applications with minimal configuration. The middleware supports Ruby on Rails, Grape, and other Ruby frameworks built on Rack.  If you’re new to Moesif, see our Getting Started resources to quickly get up and running.PrerequisitesBefore using this middleware, make sure you have the following:  An active Moesif account  A Moesif Application IDGet Your Moesif Application IDAfter you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Install the MiddlewareInstall the Moesif gem:gem install moesif_rackIf you’re using Bundler, add the gem to your Gemfile:gem &#39;moesif_rack&#39;Then run bundle install.Configure the MiddlewareSee the available configuration options to learn how to configure the middleware for your use case.How to use1. Enter Moesif Application IDCreate a hash containing application_id and specify your Moesif Application ID as its value. This hash also contains other options you may want to specify.moesif_options = {  &#39;application_id&#39; =&amp;gt; &#39;YOUR_MOESIF_APPLICATION_ID&#39;}2. Add the MiddlewareFor Rails 5.0 or NewerUsing strings or symbols for middleware class names is deprecated for newer frameworks like Ruby 5.0. So we recommend that you pass the class directly:  class Application &amp;lt; Rails::Application    moesif_options = {      &#39;application_id&#39; =&amp;gt; &#39;YOUR_MOESIF_APPLICATION_ID&#39;    }    config.middleware.use MoesifRack::MoesifMiddleware, moesif_options  endFor Rails 4.0 and Other FrameworksFor most Rack-based frameworks including Rails 4.x or older, add the middleware MoesifRack::MoesifMiddleware within config/application.rb:  class Application &amp;lt; Rails::Application    moesif_options = {      &#39;application_id&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;    }    config.middleware.use &quot;MoesifRack::MoesifMiddleware&quot;, moesif_options  endFor Grape APIFor Grape APIs, you can add the middleware after any custom parsers or formatters.module Acme  class Ping &amp;lt; Grape::API    format :json    moesif_options = {      &#39;application_id&#39; =&amp;gt; &#39;Your Moesif Application Id&#39;    }    insert_after Grape::Middleware::Formatter, MoesifRack::MoesifMiddleware, moesif_options    get &#39;/ping&#39; do      { ping: &#39;pong&#39; }    end  endendOrder of MiddlewareSince Moesif Rack is a logging middleware, the ordering of middleware matters.The best place for MoesifRack::MoesifMidleware is near the top so it captures the data closest to the wire. But remember to put it after any body parsers or authentication  middleware.Typically, right above the default logger of Rails app Rails::Rack::Logger is a good spot.If you want to be as close as wire as possible, put it before ActionDispatch::Static.To insert the Moesif middleware before Rails::Rack::Logger, you can use the insert_before method instead of use:  class Application &amp;lt; Rails::Application    # snip    config.middleware.insert_before Rails::Rack::Logger, MoesifRack::MoesifMiddleware, moesif_options    # snip  endIf you are using Rack::Deflater or other compression middleware, make sure to put the Moesif middleware afterit so it can capture the uncompressed data.To see your current list of middleware, execute this command:  bin/rails middlewareOptional: Capturing Outgoing API CallsIn addition to your own APIs, you can also start capturing calls out to third party services through by setting the capture_outgoing_requests option.For configuration options specific to capturing outgoing API calls, see Options For Outgoing API Calls.TroubleshootFor a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.Other troubleshooting supports:  FAQ  Moesif support emailRepository Structure.├── BUILDING.md├── Gemfile├── images/├── lib/├── LICENSE├── moesif_capture_outgoing/├── moesif_rack.gemspec├── Rakefile├── README.md└── test/Configuration OptionsThe following sections describe the available configuration options for this middleware. You have to set these options in a Ruby hash as key-value pairs. See the examples for better understanding.application_id (Required)         Data type              String     A string that identifies your application in Moesif.api_version         Data type              String     Optional.Use to tag requests with the version of your API.identify_user         Data type          Return type              Proc          String     Optional, but highly recommended.A Proc that takes env, headers, and body as arguments.Returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, set this option to ensure user identification properly.moesif_options[&#39;identify_user&#39;] = Proc.new { |env, headers, body|  # Add your custom code that returns a string for user id  &#39;12345&#39;}identify_company         Data type          Return type              Proc          String     Optional.A Proc that takes env, headers, and body as arguments.Returns a string that represents the company ID for this event. This helps Moesif attribute requests to unique company.moesif_options[&#39;identify_company&#39;] = Proc.new { |env, headers, body|  # Add your custom code that returns a string for company id  &#39;67890&#39;}identify_session         Data type          Return type              Proc          String     Optional.A Proc that takes env, headers, and body as arguments.Returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, use this option to help identify sessions.moesif_options[&#39;identify_session&#39;] = Proc.new { |env, headers, body|    # Add your custom code that returns a string for session/API token    &#39;XXXXXXXXX&#39;}get_metadata         Data type          Return type              Proc          Hash     Optional.A Proc that takes env, headers, and body as arguments.Returns a Hash that represents a JSON object. This allows you to attach anymetadata to this event.moesif_options[&#39;get_metadata&#39;] = Proc.new { |env, headers, body|  # Add your custom code that returns a dictionary  value = {      &#39;datacenter&#39;  =&amp;gt; &#39;westus&#39;,      &#39;deployment_version&#39;  =&amp;gt; &#39;v1.2.3&#39;  }  value}mask_data         Data type          Return type              Proc          EventModel     Optional.A Proc that takes an EventModel as an argument and returns an EventModel.This option allows you to modify headers or body of an event before sending the event to Moesif.moesif_options[&#39;mask_data&#39;] = Proc.new { |event_model|  # Add your custom code that returns a event_model after modifying any fields  event_model.response.body.password = nil  event_model}For more information and the spec of Moesif’s event model, see the source code of Moesif API library for Ruby.skip         Data type          Return type              Proc          Boolean     Optional.A Proc that takes env, headers, and body as arguments.Returns a boolean. Return true if you want to skip a particular event.moesif_options[&#39;skip&#39;] = Proc.new { |env, headers, body|  # Add your custom code that returns true to skip logging the API call  if env.key?(&quot;REQUEST_URI&quot;)       # Skip probes to health page      env[&quot;REQUEST_URI&quot;].include? &quot;/health&quot;  else      false  end}debug         Data type          Default              Boolean          false     Optional.If true, the middleware prints out debug messages. In debug mode, the processing is not done in backend thread.log_body         Data type          Default              Boolean          true     Optional.If false, doesn’t log request and response body to Moesif.batch_size         Data type          Default              int          200     Optional.The maximum batch size when sending to Moesif.batch_max_time         Data type          Default              int          2     Optional.The maximum time in seconds to wait (approximately) before triggering flushing of the queue and sending to Moesif.event_queue_size         Data type          Default              int          1000000     Optional.The maximum number of events to hold in queue before sending to Moesif.In case of network issues, the middleware may fail to connect or send event to Moesif. In those cases, the middleware skips adding new to event to queue to prevent memory overflow.Options For Outgoing API CallsThe following options apply to outgoing API calls. These are calls you initiate using Net::HTTP package to third parties like Stripe or to your own services.Several options use request and response as input arguments. The request and response objects passed in are HTTPRequest request and HTTPResponse response objects.capture_outgoing_requests         Data type          Default              Boolean          false     Set to true to capture all outgoing API calls from your app.identify_user_outgoing         Data type          Return type              Proc          String     Optional, but highly recommended.A Proc that takes env, headers, and body as arguments.Returns a string that represents the user ID used by your system.Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, set this option to ensure user identification properly.moesif_options[&#39;identify_user_outgoing&#39;] = Proc.new { |request, response|  # Add your custom code that returns a string for user id  &#39;12345&#39;}identify_company_outgoing         Data type          Return type              Proc          String     Optional.A Proc that takes env, headers, and body as arguments.Returns a string that represents the company ID for this event. This helps Moesif attribute requests to unique company.moesif_options[&#39;identify_company_outgoing&#39;] = Proc.new { |request, response|  # Add your custom code that returns a string for company id  &#39;67890&#39;}get_metadata_outgoing         Data type          Return type              Proc          Hash     Optional.A Proc that takes env, headers, and body as arguments.Returns a Hash that represents a JSON object. This allows you to attach anymetadata to this event.moesif_options[&#39;get_metadata_outgoing&#39;] = Proc.new { |request, response|  # Add your custom code that returns a dictionary  value = {      &#39;datacenter&#39;  =&amp;gt; &#39;westus&#39;,      &#39;deployment_version&#39;  =&amp;gt; &#39;v1.2.3&#39;  }  value}identify_session_outgoing         Data type          Return type              Proc          String     Optional.A Proc that takes env, headers, and body as arguments.Returns a string that represents the session token for this event.Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn’t work for your service, use this option to help identify sessions.moesif_options[&#39;identify_session_outgoing&#39;] = Proc.new { |request, response|    # Add your custom code that returns a string for session/API token    &#39;XXXXXXXXX&#39;}skip_outgoing         Data type          Return type              Proc          Boolean     Optional.A Proc that takes env, headers, and body as arguments.Returns a boolean. Return true if you want to skip a particular event.moesif_options[&#39;skip_outgoing&#39;] = Proc.new{ |request, response|  # Add your custom code that returns true to skip logging the API call  false}mask_data_outgoing         Data type          Return type              Proc          EventModel     Optional.A Proc that takes an EventModel as an argument and returns an EventModel.This option allows you to modify headers or body of an event before sending the event to Moesif.moesif_options[&#39;mask_data_outgoing&#39;] = Proc.new { |event_model|  # Add your custom code that returns a event_model after modifying any fields  event_model.response.body.password = nil  event_model}log_body_outgoing         Data type          Default              Boolean          true     Optional.If false, doesn’t log request and response body to Moesif.Examples  Moesif Rails 5 Example: an example of Moesif with a Ruby on Rails 5 application  Moesif Rails 4 Example: an example of Moesif with a Ruby on Rails 4 application  Moesif Rack Example: an example of Moesif in a Rack applicationThe following examples demonstrate how to add and update customer information.Update a Single UserTo create or update a user profile in Moesif, use the update_user() method.metadata = {  :email =&amp;gt; &#39;john@acmeinc.com&#39;,  :first_name =&amp;gt; &#39;John&#39;,  :last_name =&amp;gt; &#39;Doe&#39;,  :title =&amp;gt; &#39;Software Engineer&#39;,  :salesInfo =&amp;gt; {      :stage =&amp;gt; &#39;Customer&#39;,      :lifetime_value =&amp;gt; 24000,      :accountOwner =&amp;gt; &#39;mary@contoso.com&#39;,  }}# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schemacampaign = MoesifApi::CampaignModel.new()campaign.utm_source = &quot;google&quot;campaign.utm_medium = &quot;cpc&quot;campaign.utm_campaign = &quot;adwords&quot;campaign.utm_term = &quot;api+tooling&quot;campaign.utm_content = &quot;landing&quot;# Only user_id is required.# metadata can be any custom objectuser = MoesifApi::UserModel.new()user.user_id = &quot;12345&quot;user.company_id = &quot;67890&quot; # If set, associate user with a company objectuser.campaign = campaignuser.metadata = metadataupdate_user = MoesifRack::MoesifMiddleware.new(@app, @options).update_user(user_model)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field.For more information, see the function documentation in Moesif Ruby API reference.Update Users in BatchTo update a list of users in one batch, use the update_users_batch() method.users = []metadata = {  :email =&amp;gt; &#39;john@acmeinc.com&#39;,  :first_name =&amp;gt; &#39;John&#39;,  :last_name =&amp;gt; &#39;Doe&#39;,  :title =&amp;gt; &#39;Software Engineer&#39;,  :salesInfo =&amp;gt; {      :stage =&amp;gt; &#39;Customer&#39;,      :lifetime_value =&amp;gt; 24000,      :accountOwner =&amp;gt; &#39;mary@contoso.com&#39;,  }}# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#users for campaign schemacampaign = MoesifApi::CampaignModel.new()campaign.utm_source = &quot;google&quot;campaign.utm_medium = &quot;cpc&quot;campaign.utm_campaign = &quot;adwords&quot;campaign.utm_term = &quot;api+tooling&quot;campaign.utm_content = &quot;landing&quot;# Only user_id is required.# metadata can be any custom objectuser = MoesifApi::UserModel.new()user.user_id = &quot;12345&quot;user.company_id = &quot;67890&quot; # If set, associate user with a company objectuser.campaign = campaignuser.metadata = metadatausers &amp;lt;&amp;lt; userresponse = MoesifRack::MoesifMiddleware.new(@app, @options).update_users_batch(users)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the user_id field. This method is a convenient helper that calls the Moesif API lib.For more information, see the function documentation in Moesif Ruby API reference.Update a Single CompanyTo update a single company, use the update_company() method.metadata = {  :org_name =&amp;gt; &#39;Acme, Inc&#39;,  :plan_name =&amp;gt; &#39;Free&#39;,  :deal_stage =&amp;gt; &#39;Lead&#39;,  :mrr =&amp;gt; 24000,  :demographics =&amp;gt; {      :alexa_ranking =&amp;gt; 500000,      :employee_count =&amp;gt; 47  }}# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign = MoesifApi::CampaignModel.new()campaign.utm_source = &quot;google&quot;campaign.utm_medium = &quot;cpc&quot;campaign.utm_campaign = &quot;adwords&quot;campaign.utm_term = &quot;api+tooling&quot;campaign.utm_content = &quot;landing&quot;# Only company_id is required.# metadata can be any custom objectcompany = MoesifApi::CompanyModel.new()company.company_id = &quot;67890&quot;company.company_domain = &quot;acmeinc.com&quot; # If domain is set, Moesif will enrich your profiles with publicly available info company.campaign = campaigncompany.metadata = metadataupdate_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the company_id field. This method is a convenient helper that calls the Moesif API lib.For more information, see the function documentation in Moesif Ruby API reference.Update Companies in BatchTo update a list of companies in one batch, use the update_companies_batch() method.companies = []metadata = {  :org_name =&amp;gt; &#39;Acme, Inc&#39;,  :plan_name =&amp;gt; &#39;Free&#39;,  :deal_stage =&amp;gt; &#39;Lead&#39;,  :mrr =&amp;gt; 24000,  :demographics =&amp;gt; {      :alexa_ranking =&amp;gt; 500000,      :employee_count =&amp;gt; 47  }}# Campaign object is optional, but useful if you want to track ROI of acquisition channels# See https://www.moesif.com/docs/api#update-a-company for campaign schemacampaign = MoesifApi::CampaignModel.new()campaign.utm_source = &quot;google&quot;campaign.utm_medium = &quot;cpc&quot;campaign.utm_campaign = &quot;adwords&quot;campaign.utm_term = &quot;api+tooling&quot;campaign.utm_content = &quot;landing&quot;# Only company_id is required.# metadata can be any custom objectcompany = MoesifApi::CompanyModel.new()company.company_id = &quot;67890&quot;company.company_domain = &quot;acmeinc.com&quot; # If domain is set, Moesif will enrich your profiles with publicly available info company.campaign = campaigncompany.metadata = metadatacompanies &amp;lt;&amp;lt; companyresponse = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_batch(companies)The metadata field can contain any customer demographic or other info you want to store. Moesif only requires the company_id field. This method is a convenient helper that calls the Moesif API lib.For more information, see the function documentation in Moesif Ruby API reference.How to Test  Manually clone this repository.  From your terminal, navigate to the root directory of the middleware.  Run gem install moesif_rack.  Add your Moesif Application ID to test/moesif_rack_test.rb.  Run ruby test/moesif_rack_test.rb.  Then run ruby -I test test/moesif_rack_test.rb -n test_capture_outgoing to test capturing outgoing API calls from your app to third parties like Stripe, Github or to your own dependencies.Explore Other IntegrationsExplore other integration options from Moesif:  Server integration options documentation  Client integration options documentation",
      "url": " /server-integration/rack/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-solo-gloo-gateway": {
      "title": "Server Integration Guide - Solo Gloo Gateway",
      "content"	 : "Moesif External Processing (ExtProc) Plugin for Solo.io Gloo GatewayThe Moesif Gloo Gateway ExtProc plugin captures API traffic from Solo.io Gloo Gateway and logs it to the Moesif API Analytics and Monetization platform. The implementation uses Envoy External Processing filters and has been tested with the Solo.io Gloo Gateway implementation of the filter.  Gloo Gateway is a powerful ingress controller and an advanced API and AI gateway, natively supporting the Kubernetes Gateway API.  Moesif is an API analytics and monetization platform.Source Code on GitHubHow to Install1. Follow Gloo Gateway Installation InstructionsThe most up-to-date steps to deploy Solo.io Gloo Gateway can be found on this documentation page. This guide also includes the installation of the HTTPBin demo application, which will be used later as an example.2. Deploy the Plugin and Configure Kubernetes SettingsReplace the placeholder API key with the one provided by Moesif to associate your Gloo Gateway instance. You can find this in your Moesif dashboard:export MOESIF_APP_ID=&amp;lt;API key from your Moesif dashboard&amp;gt;Apply the following Kubernetes manifest to deploy the filter, Kubernetes deployments, services, and upstream resources for the ExtProc filter. You may want to review the env: section of the deployment and adjust it according to Moesif’s recommendations:kubectl apply -f- &amp;lt;&amp;lt;EOFapiVersion: apps/v1kind: Deploymentmetadata:  name: moesif-extproc-plugin  namespace: gloo-systemspec:  selector:    matchLabels:      app: moesif-extproc-plugin  replicas: 1  template:    metadata:      labels:        app: moesif-extproc-plugin    spec:      containers:        - name: moesif-extproc-plugin          image: docker.io/moesif/moesif-gloo-extproc-plugin:latest          imagePullPolicy: Always          ports:            - containerPort: 50051          env:            - name: MOESIF_APPLICATION_ID              value: $MOESIF_APP_ID # &amp;lt;YOUR APPLICATION ID HERE&amp;gt;            - name: USER_ID_HEADER              value: &quot;X-User-Example-Header&quot;            - name: COMPANY_ID_HEADER              value: &quot;X-Company-Example-Header&quot;            - name: UPSTREAM              value: &quot;outbound|443||api.moesif.net&quot;            - name: DEBUG              value: &quot;false&quot;            - name: RUST_LOG              value: info---apiVersion: v1kind: Servicemetadata:  name: moesif-extproc-plugin  namespace: gloo-system  labels:    app: moesif-extproc-plugin  annotations:    gloo.solo.io/h2_service: &quot;true&quot;spec:  ports:  - port: 4445    targetPort: 50051    protocol: TCP  selector:    app: moesif-extproc-plugin---apiVersion: gloo.solo.io/v1kind: Upstreammetadata:  labels:    app: moesif-extproc-plugin    discovered_by: kubernetesplugin  name: moesif-extproc-plugin  namespace: gloo-systemspec:  discoveryMetadata: {}  useHttp2: true  kube:    selector:      app: moesif-extproc-plugin    serviceName: moesif-extproc-plugin    serviceNamespace: gloo-system    servicePort: 4445EOF3. Enable extProc in Gloo GatewayTo do that please apply the following parameters to Gloo Gateway settings.gloo.solo.io custom resource:kubectl patch settings default -n gloo-system --type=&#39;merge&#39; -p &#39;{  &quot;spec&quot;: {    &quot;extProc&quot;: {      &quot;allowModeOverride&quot;: false,      &quot;failureModeAllow&quot;: true,      &quot;filterStage&quot;: {        &quot;stage&quot;: &quot;AuthZStage&quot;      },      &quot;grpcService&quot;: {        &quot;extProcServerRef&quot;: {          &quot;name&quot;: &quot;moesif-extproc-plugin&quot;,          &quot;namespace&quot;: &quot;gloo-system&quot;        }      },      &quot;processingMode&quot;: {        &quot;requestHeaderMode&quot;: &quot;SEND&quot;,        &quot;responseHeaderMode&quot;: &quot;SEND&quot;,        &quot;requestBodyMode&quot;: &quot;STREAMED&quot;,        &quot;responseBodyMode&quot;: &quot;STREAMED&quot;      }    }  }}&#39;4. TestMake a few API calls that pass through the Gloo Gateway. These calls should now be logged to your Moesif account.How to UseCapturing API trafficThe Moesif plugin for Gloo Gateway captures API traffic and logs it to Moesif automatically when Gloo Gateway routes traffic through the plugin. Gloo Gateway traffic flow is defined via Kubernetes Gateway APIs that allows only required traffic to be accessible by the plugin.Identifying users and companiesThis plugin will automatically identify API users so you can associate API traffic to web traffic and create cross-platform funnel reports of your customer journey. The plugin currently supports reading request headers to identify users and companies automatically from events.  If the user_id_header or company_id_header configuration option is set, the named request header will be read from each request and its value will be included in the Moesif event model as the user_id or company_id field, respectively.  You can associate API users to companies for tracking account-level usage. This can be done either with the company header above or through the Moesif update user API to set a company_id for a user. Moesif will associate the API calls automatically.Configuration OptionsThese configuration options are specified as variables in the env: portion of the filter Kubernetes deployment.            Option      Type      Default      Description                  moesif_application_id      String      None      Required. Your Moesif Application Id. Can be found within the Moesif Portal.              user_id_header      String      None      Optional. The header key for User Id. If provided, the corresponding header value is used as the User Id in Moesif event models.              company_id_header      String      None      Optional. The header key for Company Id. If provided, the corresponding header value is used as the Company Id in Moesif event models.              batch_max_size      Integer      100      Optional. The maximum batch size of events to be sent to Moesif.              batch_max_wait      Integer      2000      Optional. The maximum wait time in milliseconds before a batch is sent to Moesif, regardless of the batch size.              upstream      String      “moesif_api”      Optional. The upstream cluster that points to Moesif’s API.      ExampleBased on Gloo Gateway External process documentation, this example shows how the traffic that is sent to the HTTPBin service gets monitored by the Moesif platform via the ExtProc HTTP filter.PrerequisitesYou’ll need access to a Kubernetes cluster into which to install the Moesif Istio WASM Plugin.  Kubernetes Cluster, cloud-based or hosted cluster installation should be very similar.  kubectl (v1.29 or later)Gloo Gateway installationFor ExtProc support, you will need the enterprise version of Gloo Gateway. If not deployed yet, after obtaining your license key, follow the instructions on this page.Note: Remember to select the Enterprise Edition tab.Deploy a sample applicationAt the same page you can find instructions on how to install the HTTPBin Kubernetes deployment and service in your Kubernetes cluster.Install Moesif ExtProc Plugin for Solo.io Gloo GatewayFollow steps from the installation instructions above.Example: Accessing HTTPBin Service via Gloo GatewayThis section shows how to interact with the HTTPBin service after completing the installation.1. Verify the Gloo Gateway AddressGet the Kubernetes Load Balancer address associated with the HTTPBin service:export INGRESS_GW_ADDRESS=$(kubectl get svc -n gloo-system gloo-proxy-http -o=jsonpath=&quot;{.status.loadBalancer.ingress[0][&#39;hostname&#39;,&#39;ip&#39;]}&quot;)echo $INGRESS_GW_ADDRESS2. Test the ServiceYou can now send a request to the HTTPBin service running inside the cluster from your console:curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H &quot;host: www.example.com:8080&quot;Expected ResponseThe expected response from the service should look like this:$ curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H &quot;host: www.example.com:8080&quot;HTTP/1.1 200 OKaccess-control-allow-credentials: trueaccess-control-allow-origin: *content-type: application/json; encoding=utf-8date: Wed, 04 Sep 2024 18:24:55 GMTcontent-length: 336x-envoy-upstream-service-time: 3server: envoy{  &quot;headers&quot;: {    &quot;Accept&quot;: [      &quot;*/*&quot;    ],    &quot;Host&quot;: [      &quot;www.example.com:8080&quot;    ],    &quot;User-Agent&quot;: [      &quot;curl/7.81.0&quot;    ],    &quot;X-Envoy-Expected-Rq-Timeout-Ms&quot;: [      &quot;15000&quot;    ],    &quot;X-Forwarded-Proto&quot;: [      &quot;http&quot;    ],    &quot;X-Request-Id&quot;: [      &quot;e6f63485-a519-4f33-a7ca-0721a0be187e&quot;    ]  }}3. Check Logs on MoesifAfter the configuration is applied, check your Moesif account to see the captured events and verify that the plugin is working as expected.Note: If request/response headers or body values are missing in Moesif, Gloo requires explicit configuration in order to send that information to the Moesif ExtProc integration.  See the processingMode field of the above example settings command and examples/extproc/extproc-gloo-settings.yamlAdditional IntegrationsFor more information on other integration options, refer to the Moesif Integration Options Documentation.",
      "url": " /server-integration/solo-gloo-gateway/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-strapi": {
      "title": "Server Integration Guide - Strapi",
      "content"	 : "StrapiStrapi is a headless CMS (content management system) based on Node.js. You can add Moesif API analytics and monitoring to your Strapi application using the Strapi Moesif plugin.Supported VersionsStrapi Moesif plugin versions 2.0.0 and later only support Strapi 4 and above. For Strapi 3, use the 1.0.5 and later versions of the plugin.PrerequisitesBefore using Strapi Moesif plugin, make sure you meet the following requirements:  A Strapi installation. For more information, see Strapi Setup and Deployment and Strapi Quick Start Guide.  An active Moesif account.Installation      Install the plugin with npm:     npm install --save strapi-plugin-moesif            Then enable the plugin n the plugins configuration file ./config/plugins.js:     module.exports = {   &#39;strapi-plugin-moesif&#39;: {     enabled: true,     config: {       moesif: {       //custom config passed to moesif middleware goes here       }     },   }, }            Add Moesif to your middleware list in the middlewares configuration file ./config/middleware.js:     module.exports = [   &#39;strapi::errors&#39;,   &#39;strapi::security&#39;,   &#39;strapi::cors&#39;,   &#39;strapi::poweredBy&#39;,   &#39;strapi::logger&#39;,   &#39;strapi::query&#39;,   &#39;strapi::body&#39;,   &#39;strapi::favicon&#39;,   &#39;strapi::public&#39;,   &#39;plugin::strapi-plugin-moesif.moesif&#39; ];            Add a MOESIF_APPLICATION_ID environment variable. To get your Application ID, follow these steps: a. Log into Moesif Portal.    b. Select the account icon to bring up the settings menu.    c. Select Installation or API Keys.    d. Copy your Moesif Application ID from the Collector Application ID field.        Run Strapi:    With npm:     npm run develop        With yarn:     yarn develop      To test, make a few API calls to your endpoint like this:curl http://localhost:1337HerokuFor Heroku, install Moesif as an add-on. Heroku automatically creates and manages the MOESIF_APPLICATION_ID environment variable.Configuration OptionsThis plugin uses moesif-nodejs under the hood. Therefore, you can use the configuration options for moesif-nodejs in Strapi Moesif plugin.identifyUserTo track Strapi users, define the identifyUser function:identifyUser: function (req, res) {  if (req.state &amp;amp;&amp;amp; req.state.user) {    return String(req.state.user.id);  }  return undefined;}skipYou can set up Moesif to track all traffic in and out of your application, but you may be interested in API metrics specifically. The default configuration of Strapi Moesif plugin skips all non-JSON communication to avoid having excessive amounts of file requests in your Moesif dashboard.To override the skip function, include one in your configuration, or set to send all communications:// return true if the data should be skippedskip: function (req, res) {  // don&#39;t log non JSON types  return (    res.headers &amp;amp;&amp;amp; !res.headers[&quot;Content-Type&quot;].includes(&quot;application/json&quot;)  );}//send all data regardless of typeskip: null",
      "url": " /server-integration/strapi/",
      "author": "Sakib",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-tyk-api-gateway": {
      "title": "Server Integration Guide - Tyk API Gateway",
      "content"	 : "Moesif Tyk API Gateway PluginThe Tyk plugin for Moesif captures API traffic from Tyk API Gateway andsends to Moesif. This is done via the Tyk Analytics Pump which is an open source component that handles sending API logs to Moesif in an asynchronous way.For an overview on how the plugin works and use cases, see Tyk + Moesif: the perfect pairing on Tyk’s blog.SetupMoesif recommends Tyk Pump v1.1.0 or later for enhanced user tracking and sampling features. The Moesif Tyk integration automatically maps a Tyk Token Alias to a user in Moesif.      Follow Tyk’ssetup instructions to get a Tyk Gateway instance running. You will also need to set up a Tyk Pump instance,if you haven’t already. Here is the guide for Ubuntu.        Create or update your pump.env to configure the Tyk Analytics Pump and add Moesif as a backend:  TYK_PMP_PUMPS_MOESIF_TYPE=moesifTYK_PMP_PUMPS_MOESIF_META_APPLICATIONID=your_moesif_application_idYou can find your Application Id from Moesif Dashboard -&amp;gt; Bottom Left Menu -&amp;gt; Installation -&amp;gt; Tyk API Gateway  Ensure analytics is enabledYou should ensure detailed analytics recording is enabled in your tyk.env file.TYK_GW_ENABLEANALYTICS=trueTYK_GW_ANALYTICSCONFIG_ENABLEDETAILEDRECORDING=trueOnce your config changes are done, you may need to reload your Tyk Pump and Tyk Gateway instances.Configuration optionsThe Tyk Pump for Moesif has a few configuration options:            Parameter      Required?      Description      Environment Variable Name                  application_id      required      Moesif Application Id. Multiple Tyk api_id’s will be logged under the same app id.      TYK_PMP_PUMPS_MOESIF_META_APPLICATIONID              request_header_masks      optional      Mask a specific request header field. Type: String Array [] string      TYK_PMP_PUMPS_MOESIF_META_REQUESTHEADERMASKS              request_body_masks      optional      Mask a specific - request body field. Type: String Array [] string      TYK_PMP_PUMPS_MOESIF_META_REQUESTBODYMASKS              response_header_masks      optional      Mask a specific response header field. Type: String Array [] string      TYK_PMP_PUMPS_MOESIF_META_RESPONSEHEADERMASKS              response_body_masks      optional      Mask a specific response body field. Type: String Array [] string      TYK_PMP_PUMPS_MOESIF_META_RESPONSEBODYMASKS              disable_capture_request_body      optional      Disable logging of request body. Type: Boolean. Default value is false.      TYK_PMP_PUMPS_MOESIF_META_DISABLECAPTUREREQUESTBODY              disable_capture_response_body      optional      Disable logging of response body. Type: Boolean. Default value is false.      TYK_PMP_PUMPS_MOESIF_META_DISABLECAPTURERESPONSEBODY              user_id_header      optional      Field name to identify User from a request or response header. Type: String.      TYK_PMP_PUMPS_MOESIF_META_USERIDHEADER              company_id_header      optional      Field name to identify Company (Account) from a request or response header. Type: String.      TYK_PMP_PUMPS_MOESIF_META_COMPANYIDHEADER              bulk_config      optional      JSON map containing the batch writing trigger configuration.                     bulk_config.api_endpoint      optional      API Endpoint for when setting up client-side encryption via Moesif Secure Proxy.      TYK_PMP_PUMPS_MOESIF_META_BULKCONFIG_APIENDPOINT              bulk_config.event_queue_size      optional      Specifies the maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new events to the queue to prevent memory overflow. Type: int. Default value is 10000.      TYK_PMP_PUMPS_MOESIF_META_BULKCONFIG_EVENTQUEUESIZE              bulk_config.batch_size      optional      Specifies the maximum batch size when sending to Moesif. Type: int. Default value is 200.      TYK_PMP_PUMPS_MOESIF_META_BULKCONFIG_BATCHSIZE              bulk_config.timer_wake_up_seconds      optional      Specifies a time (every n seconds) how often background thread runs to send events to Moesif.      TYK_PMP_PUMPS_MOESIF_META_BULKCONFIG_TIMERWAKEUPSECONDSs      ",
      "url": " /server-integration/tyk-api-gateway/",
      "author": "Derric",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-wso2-apim": {
      "title": "Server Integration Guide - WSO2 API Manager",
      "content"	 : "Integrate Moesif with WSO2 API ManagerThis document describes how to integrate Moesif with WSO2 API Manager.This integration allows you to collect and dispatch API analytics data to Moesif where you can leverage various API and customer analytics to gain insights into API usage, traffic trends, and error tracking.Supported VersionsMoesif integration is supported in the following WSO2 API Manager versions:  4.5.0 update level 11 and later 4.5.x versions  4.6.0 and later versionsSee Updating WSO2 API Manager to update your WSO2 API Manager to the required or latest version.Analytics Data FlowThe Moesif integration captures both successful and failed API invocations in WSO2 API Manager and makes them available in your Moesif dashboards in near real-time. This allows for powerful analytics and monitoring capabilities.The following steps cover the necessary steps to integrate Moesif with WSO2 API Manager.Step 1: Set Up Your Moesif Account1.1 Create an Account and Log InIf you haven’t already, sign up or log into your Moesif Web Portal.1.2 Create a New Application  Once logged in, create a new App from the “Get Started” page.  Follow the setup steps and select Next.  Moesif then shows you your Application ID. Copy this ID as since you will later use it to configure WSO2 API Manager.You can always obtain your Moesif Application ID by following these steps any time:  Log into Moesif Portal.  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Step 2 - Configure WSO2 API ManagerTo enable Moesif analytics in WSO2 APIM, update the deployment.toml configuration file.Step 2.1 - Configuring the deployment.toml file.Open the &amp;lt;APIM-HOME&amp;gt;/repository/conf directory. Then edit the deployment.toml file with the following configuration, replacing MOESIF_APPLICATION_ID with your Application ID that you obtained in step 1.2.For WSO2 API Manager 4.6.0 and later[apim.analytics]enable = truetype = &quot;moesif&quot;[apim.analytics.properties]moesifKey = &quot;MOESIF_APPLICATION_ID&quot;For WSO2 API Manager 4.5.0 Update Level 11 and Later 4.5.x Versions[apim.analytics]enable = truetype = &quot;moesif&quot;[apim.analytics.properties]moesifKey = &quot;MOESIF_APPLICATION_ID&quot;&quot;publisher.reporter.class&quot; = &quot;org.wso2.am.analytics.publisher.reporter.moesif.MoesifReporter&quot;Analytics Log EventsThis section describes the details that are available in analytics log events.Event apim_event_responseThe apim_event_response event triggers for each successful API invocation. When an API-associated backend returns an error response, the same event triggers and logs the event details.{  &quot;apiCreator&quot;:&quot;admin&quot;,  &quot;apiCreatorTenantDomain&quot;:&quot;carbon.super&quot;,  &quot;apiId&quot;:&quot;43d030dc-427f-4678-98e3-87b7d9882b5f&quot;,  &quot;apiMethod&quot;:&quot;GET&quot;,  &quot;apiName&quot;:&quot;SampleAPI&quot;,  &quot;apiResourceTemplate&quot;:&quot;/*&quot;,  &quot;apiType&quot;:&quot;HTTP&quot;,  &quot;apiVersion&quot;:&quot;1.0.0&quot;,  &quot;applicationId&quot;:&quot;2d6c54b0-7c7d-4b50-83dc-e6ae6f88962e&quot;,  &quot;applicationName&quot;:&quot;DefaultApplication&quot;,  &quot;applicationOwner&quot;:&quot;admin&quot;,  &quot;backendLatency&quot;:13,  &quot;correlationId&quot;:&quot;79ed20c3-55b1-434a-adf6-eea25e2d09c3&quot;,  &quot;destination&quot;:&quot;http://192.168.114.51:8281/services/sampleAPIBackend&quot;,  &quot;eventType&quot;:&quot;response&quot;,  &quot;gatewayType&quot;:&quot;SYNAPSE&quot;,  &quot;keyType&quot;:&quot;SANDBOX&quot;,  &quot;userName&quot;:&quot;admin@carbon.super&quot;,  &quot;proxyResponseCode&quot;:202,  &quot;regionId&quot;:&quot;default&quot;,  &quot;requestMediationLatency&quot;:54,  &quot;requestTimestamp&quot;:&quot;2022-01-20T03:34:36.451Z&quot;,  &quot;responseCacheHit&quot;:false,  &quot;responseLatency&quot;:73,  &quot;responseMediationLatency&quot;:6,  &quot;targetResponseCode&quot;:202,  &quot;userAgent&quot;:&quot;Chrome&quot;,  &quot;userIp&quot;:&quot;172.16.2.70&quot;,  &quot;properties&quot;:{    &quot;commonName&quot;:&quot;N/A&quot;,    &quot;responseContentType&quot;:&quot;application/json; charset=UTF-8&quot;,    &quot;subType&quot;:&quot;DEFAULT&quot;,    &quot;isEgress&quot;:false,    &quot;apiContext&quot;:&quot;/api1/2.0.0&quot;,    &quot;responseSize&quot;:133,    &quot;userName&quot;:&quot;admin@carbon.super&quot;  }}Event apim_event_faultyThe apim_event_faulty event triggers for each failed and throttled API invocation.{  &quot;apiCreator&quot;:&quot;admin&quot;,  &quot;apiCreatorTenantDomain&quot;:&quot;carbon.super&quot;,  &quot;apiId&quot;:&quot;43d030dc-427f-4678-98e3-87b7d9882b5f&quot;,  &quot;apiName&quot;:&quot;SampleAPI&quot;,  &quot;apiType&quot;:&quot;HTTP&quot;,  &quot;apiVersion&quot;:&quot;1.0.0&quot;,  &quot;apiMethod&quot;:&quot;GET&quot;,  &quot;apiResourceTemplate&quot;:&quot;/publish&quot;,  &quot;applicationId&quot;:&quot;0b5ccc91-30e2-4ee5-9355-d1698075c028&quot;,  &quot;applicationName&quot;:&quot;SampleApp3&quot;,  &quot;applicationOwner&quot;:&quot;admin&quot;,  &quot;correlationId&quot;:&quot;ccf2196f-9db8-429b-aaae-98f4c6edf6d7&quot;,  &quot;errorCode&quot;:900803,  &quot;errorMessage&quot;:&quot;APPLICATION_LEVEL_LIMIT_EXCEEDED&quot;,  &quot;errorType&quot;:&quot;THROTTLED&quot;,  &quot;eventType&quot;:&quot;fault&quot;,  &quot;gatewayType&quot;:&quot;SYNAPSE&quot;,  &quot;keyType&quot;:&quot;PRODUCTION&quot;,  &quot;proxyResponseCode&quot;:429,  &quot;regionId&quot;:&quot;default&quot;,  &quot;requestTimestamp&quot;:&quot;2022-02-01T04:18:48.023Z&quot;,  &quot;responseCacheHit&quot;:false,  &quot;targetResponseCode&quot;:-1,  &quot;properties&quot;:{    &quot;commonName&quot;:&quot;N/A&quot;,    &quot;responseContentType&quot;:&quot;application/json; charset=UTF-8&quot;,    &quot;subType&quot;:&quot;DEFAULT&quot;,    &quot;isEgress&quot;:false,    &quot;apiContext&quot;:&quot;/api1/2.0.0&quot;,    &quot;responseSize&quot;:133,    &quot;userName&quot;:&quot;admin@carbon.super&quot;  }}The following table describes the different entities in the analytics log events data:            Parameter      Type      Description                  apiCreator      string      The creator of the API.              apiCreatorTenantDomain      string      The tenant domain of the API creator.              apiId      string      Unique identifier of the API.              apiMethod      string      The HTTP method used by the API—for example, GET, POST.              apiName      string      The name of the API.              apiResourceTemplate      string      The template of the API resource accessed.              apiType      string      The type of the API, for example, HTTP, REST.              apiVersion      string      The version of the API.              applicationId      string      Unique identifier of the application that makes the API call.              applicationName      string      Name of the application that makes the API call.              applicationOwner      string      Owner of the application that makes the API call.              backendLatency      long      The time taken by the backend to process the request.              correlationId      string      Unique identifier for tracking API calls.              destination      string      The backend URL to which the API call was redirected.              eventType      string      The type of event.              gatewayType      string      The type of the API gateway.              keyType      string      Indicates whether the API key used was for SANDBOX or PRODUCTION.              platform      string      Operating system was used to access the API.              properties      object      Properties of the event.              apiContext      string      The context of the API call.              userName      string      The username of the individual who made the API call.              proxyResponseCode      int      The HTTP response code returned by the API gateway.              regionId      string      The region identifier for the API call.              requestMediationLatency      int      Time taken for request mediation.              requestTimestamp      long      Timestamp when the request was made.              responseCacheHit      bool      Indicates if the response was served from cache.              responseLatency      long      Total time taken to respond to the request.              responseMediationLatency      long      Time taken for response mediation.              targetResponseCode      int      The HTTP response code received from the backend target.              userAgent      string      The user agent of the client making the API call.              userIp      string      The IP address of the user making the API call.              errorCode      int      The error code generated in a fault.              errorMessage      string      The error message associated with the fault.              errorType      string      The type of error—for example,THROTTLED.      Learn More  Get started with Moesif.  Learn how to identify customers.  Learn about dashboards and workspaces.  Learn to set up real-time monitoring and alerts.  Invite team members to collaborate.",
      "url": " /server-integration/wso2-apim/",
      "author": "Sakib",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-wso2-kubernetes-gateway": {
      "title": "Server Integration Guide - WSO2 Kubernetes Gateway",
      "content"	 : "Integarte Moesif with WSO2 Kubernetes GatewayHow to Install  Also, see WSO2 docs for details installing Moesif.  Create a secret containing your Moesif Collector Application ID using the below command.kubectl create secret generic moesif-secret --from-literal=moesifToken=&#39;Your-Moesif-Application-id&#39; -n apk  Follow the instructions in Customize Configurations. These instructions will guide you through the process of acquiring the values.yaml file. Replace secret-name in the following configuration with the name of the secret you created in the previous step.analytics: enabled: true publishers: - enabled: true   type: &quot;moesif&quot;   secretName: &amp;lt;secret-name&amp;gt;  Open the values.yaml file, and add the above configuration to the gatewayRuntime section under dp. Your values.yaml file should have a structure as follows.    wso2:      ...      apk:        ...        dp:          ...          gatewayRuntime:            analytics:              enabled: true              publishers:              - enabled: true                type: &quot;moesif&quot;                secretName: &amp;lt;secret-name&amp;gt;  Then redeploy the helm chart with the changes in values.yaml.",
      "url": " /server-integration/wso2-kubernetes-gateway/",
      "author": "Matthew",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-wso2-bijira": {
      "title": "Server Integration Guide - WSO2 Bijira",
      "content"	 : "Integrate Moesif with WSO2 Bijira      Go to Bijira Console and sign in.        In the left navigation, click Admin and then click Settings.        In the header, click the Organization list. This will open the organization level settings page.        Click Moesif Dashboard.        Select the environment you want to publish data for.        Paste the Application Id you copied.        Click Add.  Wait about 5 minutes for the configuration to propagate and send your first test request to one of your endpoints. This data should be received in Moesif shortly. Once received, this confirms that your integration is working!For more info, please see detailed instructions on WSO2 website.",
      "url": " /server-integration/wso2-bijira/",
      "author": "Xing",
      "categories": "Integration, Server"
    }
    ,
  

    "server-integration-wso2-choreo": {
      "title": "Server Integration Guide - WSO2 Choreo",
      "content"	 : "Integrate Moesif with WSO2 ChoreoIn the Choreo console, choose the Organization you’d like to enable Moesif in by selecting it from the Organization dropdown in the top left of the screen.Once selected, click the Settings menu option near the bottom in the left-side menu.On the Settings screen, choose API Management in the available tabs across the top. From API Management, select the Moesif Dashboard tab.Under Moesif Settings &amp;gt; Application Id, copy and paste your Moesif Application Id.Your Moesif Application Id can be found in the Moesif Portal. After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps when selecting WSO2 Choreo.  You can also find your Moesif Application Id at any time by logging into the Moesif Portal, clicking on the Settings menu (your name) in the bottom-left of the screen, and selecting Installation.Once your Moesif Application Id is added, click the Add button at the end of the textbox.Wait about 5 minutes for the configuration to propagate and send your first test request to one of your endpoints. This data should be received in Moesif shortly. Once received, this confirms that your integration is working!",
      "url": " /server-integration/wso2-choreo/",
      "author": "Matthew",
      "categories": "Integration, Server"
    }
    ,
  

    "ingest-action-events-collector-api": {
      "title": "Ingest Custom Actions - Collector API",
      "content"	 : "You can directly send custom events to Moesif’s Track Actions API.Actions have an action name (like “Sent Message” or “Finished Job”) which represents the raw event. You can also include arbitrary metadata.Any metadata fields you set can be used to create billable metrics (such as for usage-based billing), quotas, reports, alerts, and more. For more info, see docs on actions.LimitationsEnforcing quotas and governance rules will not work without a server integration. You can always install a server integration later if this capability is required.Send an ActionThe action can be sent to the Collector API like below. The metadata field should contain any attributes you would like associated with this action and can be any JSON object. Moesif is designed for high-dimensions, high-cardinality event data, so it’s ok to include a lot of relevant fields even if you don’t require them today.curl -X POST   https://api.moesif.net/v1/actions   -H &#39;Content-Type: application/json&#39;   -H &#39;X-Moesif-Application-Id: Your_Moesif_Application_Id&#39;   -d &#39;{    &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,    &quot;request&quot;: {      &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;    },    &quot;company_id&quot;: &quot;12345&quot;,    &quot;metadata&quot;: {      &quot;total_rows&quot;: 1024,      &quot;found_rows&quot;: 999,      &quot;consumed_input_tokens&quot;: 54322,      &quot;time_seconds&quot;: 66.3    }  }&#39;You’ll want to set a few fields like below:  action_name is a string and should include name of the event such as “Finished Data Processing Job”.  company_id is the customer identifier (see companies).  transaction_id should be a random UUID for this event which Moesif uses for deduplication (docs on Moesif idempotency).  request.time represents the transaction time as an ISO formatted string.  metadata is an object which includes any custom properties for this event. By setting metadata, you can bill on arbitrary metrics, create metrics on them, etc. For example, if the action name is “Finished Data Processing Job”, you can include an amount and the currency to bill on the total amount.For full schema and available fields, see Actions API Reference.In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Send a Batch of ActionsYou can also send a batch of actions which can be more efficient in high throughput streams (such as from your Logstash or AWS Firehose).The batch API follows the same schema, but as a JSON array.curl -X POST   https://api.moesif.net/v1/actions/batch   -H &#39;Content-Type: application/json&#39;   -H &#39;X-Moesif-Application-Id: Your_Moesif_Application_Id&#39;   -d &#39;[{    &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,    &quot;request&quot;: {      &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;    },    &quot;company_id&quot;: &quot;12345&quot;,    &quot;metadata&quot;: {      &quot;total_rows&quot;: 1024,      &quot;found_rows&quot;: 999,      &quot;consumed_input_tokens&quot;: 54322,      &quot;time_seconds&quot;: 66.3    }  },  {    &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,    &quot;request&quot;: {      &quot;time&quot;: &quot;2025-01-28T04:46:42.914&quot;    },    &quot;company_id&quot;: &quot;67890&quot;,    &quot;metadata&quot;: {      &quot;total_rows&quot;: 25,      &quot;found_rows&quot;: 25,      &quot;consumed_input_tokens&quot;: 123,      &quot;time_seconds&quot;: 5.2    }  }]&#39;Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.",
      "url": " /ingest-action-events/collector-api/",
      "author": "Derric",
      "categories": "Ingest Actions"
    }
    ,
  

    "ingest-action-events-aws-firehose": {
      "title": "Ingest Custom Actions - AWS Data Firehose",
      "content"	 : "Moesif can directly ingest your API logs or custom actions from an AWS firehose instance.What are actions?Actions are custom usage events that you directly send to Moesif. Actions have an action name (like “Signed Up” or “Finished Job”) which represents the raw event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more. For more info, see docs on actions.How it worksThe AWS Firehose integration works by using the AWS HTTP Endpoint for the Firehose destination. Then your applications can insert your custom actions into the firehose which will be sent to Moesif. For example, below shows an API Gateway which sends events to the firehose.LimitationsEnforcing quotas and governance rules will not work without a server integration. You can always install a server integration later if this capability is required.How to install (actions)Create a Kinesis Data FirehoseClick the below Launch Stack button to open CloudFormation which will automatically create a new Data Firehose configured with Moesif Actions API as the destination.Ensure you checkbox I acknowledge that AWS CloudFormation might create IAM resources as shown below. Then click Create Stack.  If you experience errors or want to create the Firehose manually, follow these instructions.After the stack is created, search for “Firehose” in the AWS Console search bar and select Kinesis Data Firehose.Insert an actionNow that your firehose is created, save an example action into your firehose. The firehose message must match the schema for an action which is available here.You’ll want to set a few fields like below:  action_name is a string and should include name of the event such as “Finished Data Processing Job”.  company_id is the customer identifier (see companies).  transaction_id should be a random UUID for this event which Moesif uses for deduplication (docs on Moesif idempotency).  request.time represents the transaction time as an ISO formatted string.  metadata is an object which includes any custom properties for this event. By setting metadata, you can bill on arbitrary metrics, create metrics on them, etc. For example, if the action name is “Finished Data Processing Job”, you can include an amount and the currency to bill on the total amount.For full schema and available fields, see Actions API Reference.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;company_id&quot;: &quot;12345&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.Manual Firehose CreationIf you cannot use the CloudFormation template or having issues, you can manually create and configure a Kinesis Data Firehose usingthe HTTP destination.Go to Amazon Kinesis within the AWS Console and select Create Delivery Stream.  For the source, select Direct PUT or other sources.  For the destination, select HTTP Endpoint and enter the following:  For HTTP endpoint URL, enter https://api.moesif.net/v1/partners/aws/kinesis/actions  For Access key, enter your Moesif Application Id.  For Buffer interval, enter 60 seconds.  Enable GZIP compression.",
      "url": " /ingest-action-events/aws-firehose/",
      "author": "Derric",
      "categories": "Ingest Actions"
    }
    ,
  

    "ingest-action-events-fluent-bit": {
      "title": "Ingest Custom Actions - Fluent Bit",
      "content"	 : "Moesif can directly ingest your API logs or custom actions from a Fluent Bit instance.What are actions?Actions are custom usage events that you directly send to Moesif. Actions have an action name (like “Signed Up” or “Finished Job”) which represents the raw event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more. For more info, see docs on actions.How it worksThe integration with Fluent Bit works by using the HTTP Output Plugin for the destination. Then your applications can insert your custom actions into the firehose which will be sent to Moesif.LimitationsEnforcing quotas and governance rules will not work without a server integration. You can always install a server integration later if this capability is required.How to install (actions)Add HTTP output pluginAdd an HTTP output plugin to your Fluent Bit configuration.The HTTP output should send the actions to https://api.moesif.net/v1/actions/batch. Ensure you have compression and SSL enabled as a best practice for security and performance.You’ll want to define a few fields like below:  action_name is a string and should include name of the event such as “Finished Data Processing Job”.  company_id is the customer identifier (see companies).  transaction_id should be a random UUID for this event which Moesif uses for deduplication (docs on Moesif idempotency).  request.time represents the transaction time as an ISO formatted string.  metadata is an object which includes any custom properties for this event. By setting metadata, you can bill on arbitrary metrics, create metrics on them, etc. For example, if the action name is “Finished Data Processing Job”, you can include an amount and the currency to bill on the total amount.For full schema and available fields, see Actions API Reference.[FILTER]    Name    modify    Match   *    Add     action_name       ${record[&#39;action_name&#39;]}    Add     company_id           ${record[&#39;company_id&#39;]}    Add     transaction_id    ${record[&#39;transaction_id&#39;]}    Add     request.time      ${record[&#39;timestamp&#39;]}    Add     metadata          ${record.to_json}[OUTPUT]    Name   http    Match  *    host   api.moesif.net    port   443    uri    /v1/actions/batch    method POST    header Content-Type application/json    header Authorization Your_Moesif_Application_Id    format json    compress gzip     json_date_key false    workers 4    tls trueInsert an actionNow that your firehose is created, save an example action into your firehose. The firehose message must match the schema for an action which is available here.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;user_id&quot;: &quot;12345&quot;,  &quot;company_id&quot;: &quot;67890&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.",
      "url": " /ingest-action-events/fluent-bit/",
      "author": "Derric",
      "categories": "Ingest Actions"
    }
    ,
  

    "ingest-action-events-fluentd": {
      "title": "Ingest Custom Actions - FluentD",
      "content"	 : "Moesif can directly ingest your API logs or custom actions from a FluentD instance.What are actions?Actions are custom usage events that you directly send to Moesif. Actions have an action name (like “Signed Up” or “Finished Job”) which represents the raw event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more. For more info, see docs on actions.How it worksThe integration with FluentD works by using the out_http plugin for the destination. Then your applications can insert your custom actions into the firehose which will be sent to Moesif.LimitationsEnforcing quotas and governance rules will not work without a server integration. You can always install a server integration later if this capability is required.How to install (actions)Add HTTP output pluginAdd an HTTP output plugin to your FluentD configuration.The HTTP output should send the actions to https://api.moesif.net/v1/actions/batch. Ensure you have compression and SSL enabled as a best practice for security and performance.You’ll want to define a few fields like below:  action_name is a string and should include name of the event such as “Finished Data Processing Job”.  company_id is the customer identifier (see companies).  transaction_id should be a random UUID for this event which Moesif uses for deduplication (docs on Moesif idempotency).  request.time represents the transaction time as an ISO formatted string.  metadata is an object which includes any custom properties for this event. By setting metadata, you can bill on arbitrary metrics, create metrics on them, etc. For example, if the action name is “Finished Data Processing Job”, you can include an amount and the currency to bill on the total amount.For full schema and available fields, see Actions API Reference.&amp;lt;match moesif_events&amp;gt;  @type copy  &amp;lt;store&amp;gt;    @type http    endpoint_url &quot;https://api.moesif.net/v1/actions/batch&quot;    http_method post    headers {&quot;Content-Type&quot;:&quot;application/json&quot;,&quot;Authorization&quot;:&quot;Your_Moesif_Application_Id&quot;}    json_array true    &amp;lt;buffer&amp;gt;      @type memory      flush_interval 1s      flush_mode interval      flush_thread_count 4      chunk_limit_size 10m      retry_forever true      compress gzip    &amp;lt;/buffer&amp;gt;    &amp;lt;format&amp;gt;      @type json    &amp;lt;/format&amp;gt;    &amp;lt;inject&amp;gt;      action_name &quot;${record[&#39;action_name&#39;]}&quot;      company_id &quot;${record[&#39;company_id&#39;]}&quot;      request {        &quot;time&quot;: &quot;${record[&#39;timestamp&#39;]}&quot;      }      transaction_id &quot;${record[&#39;transaction_id&#39;]}&quot;      metadata &quot;${record.to_json}&quot;    &amp;lt;/inject&amp;gt;  &amp;lt;/store&amp;gt;&amp;lt;/match&amp;gt;Insert an actionNow that your firehose is created, save an example action into your firehose. The firehose message must match the schema for an action which is available here.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;user_id&quot;: &quot;12345&quot;,  &quot;company_id&quot;: &quot;67890&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.",
      "url": " /ingest-action-events/fluentd/",
      "author": "Derric",
      "categories": "Ingest Actions"
    }
    ,
  

    "ingest-action-events-logstash": {
      "title": "Ingest Custom Actions - Logstash",
      "content"	 : "Moesif can directly ingest your API logs or custom actions from a Logstash instance.What are actions?Actions are custom usage events that you directly send to Moesif. Actions have an action name (like “Signed Up” or “Finished Job”) which represents the raw event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more. For more info, see docs on actions.How it worksThe integration with Logstash works by using the HTTP Output Plugin for the destination. Then your applications can insert your custom actions into the firehose which will be sent to Moesif.LimitationsEnforcing quotas and governance rules will not work without a server integration. You can always install a server integration later if this capability is required.How to install (actions)Add HTTP output pluginAdd an HTTP output plugin to your Logstash configuration.The HTTP output should sent the actions to https://api.moesif.net/v1/actions/batch. Ensure you have compression and json_batch enabled as a best practice for performance.You’ll want to define a few fields like below:  action_name is a string and should include name of the event such as “Finished Data Processing Job”.  company_id is the customer identifier (see companies).  transaction_id should be a random UUID for this event which Moesif uses for deduplication (docs on Moesif idempotency).  request.time represents the transaction time as an ISO formatted string.  metadata is an object which includes any custom properties for this event. By setting metadata, you can bill on arbitrary metrics, create metrics on them, etc. For example, if the action name is “Finished Data Processing Job”, you can include an amount and the currency to bill on the total amount.For full schema and available fields, see Actions API Reference.output {  http {    url =&amp;gt; &quot;https://api.moesif.net/v1/actions/batch&quot;    http_method =&amp;gt; &quot;post&quot;    http_compressioned =&amp;gt; true        headers =&amp;gt; {      &quot;Content-Type&quot; =&amp;gt; &quot;application/json&quot;      &quot;Authorization&quot; =&amp;gt; &quot;Your_Moesif_Application_Id&quot;    }    format =&amp;gt; &quot;json_batch&quot;    codec =&amp;gt; &quot;json&quot;    connect_timeout =&amp;gt; 10    request_timeout =&amp;gt; 15    retry_failed =&amp;gt; true    retry_limit =&amp;gt; 3    retry_interval =&amp;gt; 2    automatic_retries =&amp;gt; 3    verify_cert =&amp;gt; true    message =&amp;gt; &#39;[      {        &quot;action_name&quot;: &quot;%{[action_name]}&quot;,        &quot;company_id&quot;: &quot;%{[company_id]}&quot;,        &quot;request&quot;: {          &quot;time&quot;: &quot;%{@timestamp}&quot;,         },        &quot;transaction_id&quot;: &quot;%{[transaction_id]}&quot;,        &quot;metadata&quot;: &quot;%{[metadata]}&quot;,      }    ]&#39;  }}Insert an actionNow that your firehose is created, save an example action into your firehose. The firehose message must match the schema for an action which is available here.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;user_id&quot;: &quot;12345&quot;,  &quot;company_id&quot;: &quot;67890&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.",
      "url": " /ingest-action-events/logstash/",
      "author": "Derric",
      "categories": "Ingest Actions"
    }
    ,
  

    "ingest-action-events": {
      "title": "Ingest Action Events",
      "content"	 : "If you have custom events that you want to bill on, or have observability on, you can ingest your raw events directly through the Track Action API. This can be done from an event stream such as AWS Firehose and Logstash. Select an integration option below.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            API                                                                                                                                                                                                  AWS Firehose                                                                                                                                                                                                  Fluent Bit                                                                                                                                                                                                  FluentD                                                                                                                                                                                                  Logstash                                                                                                                                                                                                                                                                              Segment Plugin                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Actions have an action name (like “Signed Up” or “Finished Data Processing Job”) which represents the name of the raw event. You can also include arbitrary metadata with an action which enables you to create billable metrics, usage reporting, and more. For more info, see docs on actions.An example action is below:{  &quot;action_name&quot;: &quot;Finished Data Processing Job&quot;,  &quot;request&quot;: {    &quot;time&quot;: &quot;2025-01-28T04:45:42.914&quot;  },  &quot;company_id&quot;: &quot;12345&quot;,  &quot;metadata&quot;: {    &quot;total_rows&quot;: 1024,    &quot;found_rows&quot;: 999,    &quot;consumed_input_tokens&quot;: 54322,    &quot;time_seconds&quot;: 66.3  }}In the above example, the action is created whenever abackend data job finishes. There are also two metrics we are tracking as part of the action (the amount of the payment and how long the job took). You can create billable metrics and usage reports from these attributes.Moesif recommends setting the optional field transaction_id to a random 36 character UUID such as 123e4567-e89b-12d3-a456-426614174000. Moesif uses the transaction_id for ensuring duplicate events are not created.Event-based billingMoesif is designed to ingest your raw events at very high volume. Because of this, we strongly recommend not pre-aggregating the events. Otherwise, you lose fidelity and resolution of your usage data. For example, Moesif can trace exactly which events are part of which billing period or invoice. Do note, Moesif has a hard limit of 1MB per event.",
      "url": " /ingest-action-events/",
      "author": "Derric",
      "categories": "Integration"
    }
    ,
  

    "client-integration": {
      "title": "Client Integration",
      "content"	 : "Client IntegrationClient integrations enables you to track customer activity within traditional web apps such as a React app log the custom actions to Moesif. This can be done using a Moesif client SDK like moesif-browser-js or a customer data platforms like Segment and Google Tag Manager. You can also import customer data directly via CSV import.Choose a Client Integration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Javascript                                                       Browser                                                                                                                                                  Docusaurus                                                                                                                                                                                                        Google Tag Manager                                                                                                                                                                                                        Segment Plugin                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            You can also connect Moesif to your billing provider to sync subscription data to Moesif. This enables you to easily charge for usage such as on API calls or custom actions tracked by Moesif.The below Diagram shows how you can store user and company data in Moesif to better segment customers and understand customer usage.With a client integration, you can track two things on your web app:  Identify users and store metadata like first name and email  Identify companies and store metadata like company name and subscription info  Track their actions such as “Signed Up” or “Purchased Plan”More info on the Moesif data model is hereYou can decide to track only users, only companies, or both based on your business and requirements. Usually B2B companies should track both, whereas API provided only to internal teams or B2C companies may find themselves sufficient with users only.Client-side integrations automatically collect context from the customer’s session such marketing attribution and UTM tracking, their browser version, etc.",
      "url": " /client-integration/",
      "author": "Derric",
      "categories": "Integration, Other"
    }
    ,
  

    "client-integration-browser-js": {
      "title": "Server Integration Guide - Javascript (Browser)",
      "content"	 : "Moesif JavaScript Browser SDKThe Moesif browser SDK enables you to identify users and track their website behavior to understand user journeys across your website and APIs together. This SDK also captures device context like geo location, browser version, marketing channel attribution, and UTM parameters.  You can use this client SDK alongside a Moesif server integration to monitor server-side API traffic. This enables you to track your end-to-end customer journey and build cross-platform funnel reports like your initial sign up to first API call conversion rate.The SDK automatically collects useful context from a user’s device including any marketing attribution, device type, and location information and stores in the user and/or company profile in Moesif. You can add additional customer properties such as user email and company domain via the identifyUser() and identifyCompany() methods.If you want to automatically log AJAX API calls, you can also call the start() method. API logging has native support for RESTful, GraphQL, Ethereum Web3, JSON-RPC, and other APIsSource Code on GitHubHow to install  This SDK is designed to run in a browser. To monitor Node.js APIs, use moesif-nodejs.Installation via script tag&amp;lt;script src=&quot;//unpkg.com/moesif-browser-js@v1/moesif.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;  // Initialize the SDK. Must be called before any other methods  moesif.init({    applicationId: &quot;Your Publishable Moesif Application Id&quot;,    // add other option here  });  // Identify the user with Moesif such as when user logs in  moesif.identifyUser(&quot;12345&quot;);  // Log user actions like clicked sign up. You can also pass in custom metadata.  moesif.track(&quot;clicked_sign_up&quot;, {    button_label: &quot;Get Started&quot;,  });&amp;lt;/script&amp;gt;Put the above script tags in between the &amp;lt;head&amp;gt; tags of your HTML page.It will attach a global moesif object. You can access it either via moesif or window.moesif.Alternative installation via NPMThe SDK is also available on NPM which can be used if you’re usinga front-end packager like Browserify or Webpack:npm install --save moesif-browser-jsYou can then require the lib like a standard NPM module:var moesif = require(&quot;moesif-browser-js&quot;);// or using the import syntax// import moesif from &quot;moesif-browser-js&quot;;// Initialize the SDK. Must be called before any other methodsmoesif.init({  applicationId: &quot;Your Publishable Moesif Application Id&quot;,  // add other option here});// Identify the user with Moesif such as when user logs inmoesif.identifyUser(&quot;12345&quot;);// Log UI actions like clicked sign upmoesif.track(&quot;clicked_sign_up&quot;, {  button_label: &quot;Get Started&quot;,});With the require method, the moesif object is not attached to any global scope, but you can attach to the global window object easily:window.moesif = moesif;Your Publishable Moesif Application Id will be displayed during the onboarding steps when signing up for Moesif when you select Browser JS. You can always find your Publishable Moesif Application Id at any time by logginginto the Moesif Portal, go to the main menu,and then clicking Installation.  You should only use your publishable application id in untrusted apps like client-side javascript. This can be found by logging into Moesif and clicking API Keys from the bottom left menu.How to useTrack user actionsActions are something that a user (or company) performed on your website such as “Clicked Sign Up”, “Viewed Documentation”, or “Purchased a Plan”.Besides the action name, you can also save related metadata properties such as the “Sign Up Method” or “Button Label”.// The first argument is required and contains the action name as a string.// The second argument is optional and contains custom event metadata such as button label.moesif.track(&#39;Clicked Sign Up&#39;, {  button_label: &#39;Get Started&#39;,  sign_up_method: &#39;Google SSO&#39;});Moesif recommends starting with the following actions: “Viewed Landing”, “Viewed Docs”, “Account Created”, “Signed Up”, “Signed In”, “Invite Sent”, “Started Onboarding”, “Finished Onboarding”, “Trial Started”, and “Trial Ended”.Identifying usersWhen you know the user’s id such as after sign in, call identifyUser.This tells Moesif who the current user is so their actions can be linked to a user profile.Besides the userId, you can also save related properties such as user demographics and subscription information.moesif.identifyUser(&quot;12345&quot;, {  email: &quot;john@acmeinc.com&quot;,  firstName: &quot;John&quot;,  lastName: &quot;Doe&quot;,  title: &quot;Software Engineer&quot;,  salesInfo: {    stage: &quot;Customer&quot;,    lifetimeValue: 24000,    accountOwner: &quot;mary@contoso.com&quot;,  },});Moesif recommends against calling identifyUser for anonymous users. Moesif will track these users automatically.The recommended place to call identifyUser is after the user logs in and you know their real user id.Identifying companiesIn addition to identifying users, you can also identify the company for account level tracking. Besides the companyId, you can also save related properties such as company demographics and website domain.// Only the first argument is a string containing the company id. This is the only required field.// The second argument is a object used to store a company info like plan, MRR, and company demographics.// The third argument is a string containing company website or email domain. If set, Moesif will enrich your profiles with publicly available info.metadata = {  orgName: &quot;Acme, Inc&quot;,  planName: &quot;Free Plan&quot;,  dealStage: &quot;Lead&quot;,  mrr: 24000,  demographics: {    alexaRanking: 500000,    employeeCount: 47,  },};moesif.identifyCompany(&quot;67890&quot;, metadata, &quot;acmeinc.com&quot;);  If you call both identifyUser() and identifyCompany() in the same session, then Moesif will automatically associate the user with the company.Track AJAX callsIf you want to automatically log AJAX API calls, you can do so via the start function.// Start capturing AJAX API Calls.moesif.start();Anonymous IdsWhen moesif-browser-js is initialized, an anonymousId is generated and stored for each new visitor.This enables you to create funnel reports of anonymous visitors even before they have signed inOnce a user signs into your app, you should call identifyUser.Moesif will automatically merge any previous user activity to the real userId, even if it’s a new device.  You should call moesif.reset() when a user logs out of your application to ensure a new anonymousId is generated. Otherwise, new activity may get associated with an old user session.You should only call identifyUser once a user logs into your app. Do not call identifyUser for anonymous visitors.By default, Moesif uses both local storage and cookies for redundancy, but you can modify this behavior with the persistence optionsCross-Domain TrackingBy default, anonymous user sessions are scoped to a single domain (including sub-domains). If your product spans multiple domains (e.g., example.com and hello.world.dev), each domain gets its own independent anonymousId, making it impossible to stitch together the full user journey.Cross-Domain Tracking (CDT) is an opt-in feature that passes the anonymousId between domains via a URL query parameter. When a user navigates from one domain to another, the SDK appends the current anonymousId to outgoing links. Upon arrival at the destination site, the SDK reads the parameter, persists the ID, and removes the parameter from the address bar to keep URLs clean.  For CDT to work end-to-end, both the origin domain and the destination domain must have enableCrossDomainTracking: true configured in their moesif.init() call.Basic setupmoesif.init({  applicationId: &quot;Your Publishable Moesif Application Id&quot;,  enableCrossDomainTracking: true,  crossDomainTargets: null,             // null = decorate all cross-domain links  // crossDomainTargets: [&quot;site1.com&quot;, &quot;site2.com&quot;],  // or restrict to specific domains  // crossDomainTrackingParameterName: &#39;__mt&#39;,        // optional: customise the query param name (default: __mt)});  Important: If crossDomainTargets is omitted entirely (i.e. not set), no cross-domain links will be decorated. You must explicitly set it to null (all domains) or an array of target domains to activate URL decoration. This is intentional — it prevents unexpected behavior from silent defaults.Configuration options            Option      Type      Default      Description                  enableCrossDomainTracking      boolean      false      Enables or disables Cross-Domain Tracking.              crossDomainTargets      null | string[]      (unset — no decoration)      null decorates all cross-domain links. An array restricts decoration to only those domains. If the option is not set, no links are decorated.              crossDomainTrackingParameterName      string      __mt      The URL query parameter name used to carry the anonymousId.      Automatically intercepted navigationsWhen CDT is enabled, the SDK automatically decorates outgoing URLs for the following navigation methods:  Anchor tags (&amp;lt;a href=&quot;...&quot;&amp;gt;) — standard clicks, middle-clicks, touch events, and “Copy Link Address” via the context menu.  Form submissions — GET method only. POST form actions are not decorated.Manual URL decorationSome navigation methods cannot be intercepted automatically (e.g., window.location.href, window.location.assign(), window.location.replace(), window.open(), and the Navigation API). For these cases, the SDK exposes a helper:moesif.cdtUrlDecorator(targetURL, overrideCDTTargets = false)This function appends the current anonymousId and the configured parameter name to the given URL. If the URL is already decorated, the existing parameter value is updated. If the target domain is not in crossDomainTargets, the URL is returned unchanged — unless overrideCDTTargets is set to true.Example usage:// Anchor tags are handled automatically. For JS-based redirects, wrap the URL manually:// window.location.hrefwindow.location.href = moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;);// window.location.assignwindow.location.assign(moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;));// window.location.replacewindow.location.replace(moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;));// window.openwindow.open(moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;));// Navigation APInavigation.navigate(moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;));// Force-decorate a URL regardless of crossDomainTargetsconst url = moesif.cdtUrlDecorator(&#39;https://other-domain.com/page&#39;, true);A convenience wrapper pattern if moesif may not yet be initialised:function decorateMoesifCdtUrl(url) {  if (moesif) {    return moesif.cdtUrlDecorator(url);  }  return url;}How it works  User visits site-a.com — the SDK generates and stores an anonymousId.  User clicks a link to site-b.com — the SDK appends ?__mt=&amp;lt;anonymousId&amp;gt; to the URL.  User lands on site-b.com — the SDK reads __mt, persists the same anonymousId, and removes the parameter from the address bar.  Both sites now share the same anonymousId, so all actions across both domains are stitched into one continuous user journey in Moesif.  Same-domain links are never decorated — URL decoration only occurs when the destination is a different domain than the current page.Consent ManagementThe Moesif SDK provides flexible consent management options to help you comply with privacy regulations like GDPR and CCPA. The SDK distinguishes between consent to store data locally and consent to publish data to Moesif servers.Important: Cookies Created on Init⚠️ Cookies and localStorage may be created as soon as the SDK is initialized (init()), regardless of the user’s consent status.If your compliance requirements mandate that no cookies or storage are created before consent is obtained, you must:  Defer SDK initialization until after the user grants consent  Call moesif.init() only after consent is grantedThis is the recommended approach for strict “consent-first” implementations where no tracking data can be stored locally before user consent.Consent for Publishing (requirePublishingConsent)If you want to track user actions locally without sending data to Moesif until consent is granted, use the requirePublishingConsent option. This approach allows you to:  Track all user actions and API calls without any loss of data  Store tracked events locally in a queue (persisted to localStorage only, NOT cookies)  Automatically flush the queue to Moesif when consent is granted  Continue tracking seamlessly across page refreshes (when using default localStorage persistence mode)This is ideal when you want zero data loss while still respecting user privacy - all events are tracked locally and sent to Moesif only after the user explicitly consents.How It WorksWhen requirePublishingConsent: true is set:  Before Consent:          All track() calls, identifyUser(), identifyCompany(), and API events are queued locally      Queue is persisted to localStorage only (not on cookies) and survives page refreshes      Note: If persistence: &#39;cookie&#39; mode is used, the queue will NOT persist across page refreshes (in-memory only)      Cross-domain tracking links are NOT decorated (no anonymousId in URLs)      Queue follows FIFO (First-In-First-Out) - oldest events dropped when limit reached        After grantPublishingConsent() is called:          All queued events are immediately sent to Moesif      Local queue is cleared after successful delivery      Future events are sent to Moesif immediately      Cross-domain tracking links are decorated with anonymousId        After revokePublishingConsent() is called:          Consent state is revoked      Any queued events are cleared      New events start queuing locally again        Recording Control with start() and stop():          These methods work the same way as described in their respective documentation, the only difference is when consent is not granted, events are queued up locally instead of being sent immediately to Moesif.      See start() and stop() for full detailsRefer API Methods for details on each methods.      State Management: Developer Responsibility⚠️ Important: The SDK does NOT persist the following states:  Whether init() has been called  Whether consent has been granted via grantPublishingConsent()You (the developer) are responsible for:  Managing initialization state - Track whether you’ve called init()  Managing consent state - Store the user’s consent decision in your own storage  Restoring state on page load - Check your stored consent state and call grantPublishingConsent() if neededExample: State Management Implementation// On page loaddocument.addEventListener(&#39;DOMContentLoaded&#39;, function() {  // Initialize SDK (this creates cookies/localStorage)  moesif.init({    applicationId: &#39;Your Publishable Moesif Application Id&#39;,    requirePublishingConsent: true  });  // Check your stored consent state (example using localStorage)  const hasConsented = localStorage.getItem(&#39;user_tracking_consent&#39;) === &#39;granted&#39;;  if (hasConsented) {    // User previously granted consent, restore it    moesif.grantPublishingConsent();  }  // Start tracking API calls and user actions  moesif.start();});// When user grants consentfunction handleConsentAccepted() {  // Store consent decision in YOUR storage  localStorage.setItem(&#39;user_tracking_consent&#39;, &#39;granted&#39;);  // Grant consent in Moesif SDK  moesif.grantPublishingConsent();}// When user revokes consentfunction handleConsentRevoked() {  // Update consent decision in YOUR storage  localStorage.setItem(&#39;user_tracking_consent&#39;, &#39;revoked&#39;);  // Revoke consent in Moesif SDK  moesif.revokePublishingConsent();}Example: Complete Consent Flow// 1. Initialize with consent requiredmoesif.init({  applicationId: &#39;Your Publishable Moesif Application Id&#39;,  requirePublishingConsent: true,  maxQueueSize: 1000});// 2. Start recording (events will be queued, not sent)moesif.start();// 3. Track events (queued locally)moesif.track(&#39;viewed_homepage&#39;);moesif.identifyUser(&#39;user_123&#39;);// 4. When user grants consentmoesif.grantPublishingConsent();// Now all queued events are sent to Moesif// 5. Continue tracking (sent immediately)moesif.track(&#39;clicked_cta&#39;);// 6. If user later revokes consentmoesif.revokePublishingConsent();// Future events will be queued again (not sent)Strict Compliance Mode: Defer Init Until ConsentFor strict compliance where no cookies or storage can be created before consent:// Wait for user consent before initializingdocument.addEventListener(&#39;DOMContentLoaded&#39;, function() {  // Check if user has already granted consent  const hasConsented = localStorage.getItem(&#39;user_tracking_consent&#39;) === &#39;granted&#39;;  if (hasConsented) {    // User previously consented, safe to initialize    initializeMoesif();  } else {    // Show consent banner    showConsentBanner();  }});function initializeMoesif() {  moesif.init({    applicationId: &#39;Your Publishable Moesif Application Id&#39;  });  moesif.start();  // Track events immediately (they go to Moesif right away)  moesif.track(&#39;session_started&#39;);}function handleConsentAccepted() {  localStorage.setItem(&#39;user_tracking_consent&#39;, &#39;granted&#39;);  initializeMoesif(); // Initialize only after consent  hideConsentBanner();}List of Methods on the moesif Objectinit, (obj) =&amp;gt; nullInitialize the SDK with your Publishable Application Id and any other options.On initialization, the SDK will capture user context like device and marketing attribution.This method must be called before any other methods like start() or identifyUser.var options = {  applicationId: &#39;Your Publishable Moesif Application Id&#39;};moesif.init(options);identifyUser, (string, object) =&amp;gt; nullWhen a user logs into your website and you have their actual user id, identify the user with your userId.You can also add custom metadata containing fields like the customer’s name and email as the second argument.Note: You shouldn’t call identifyUser for anonymous visitors to your website.Moesif automatically assigns them an anonymousId, so just calling track works just fine without identify.When you call identifyUser, Moesif automatically merges the anonymousId with your real userId.moesif.identifyUser(&quot;12345&quot;, metadata);identifyCompany, (string, object, string) =&amp;gt; nullSimilar to identifyUser, but for tracking companies (accounts) which is recommended for B2B companies.You can use both identifyUser and identifyCompany or just one. If you call both identifyUser() and identifyCompany() in the same session, then Moesif will automatically associate the user with the company.Only the first argument is a string containing the company id. This is the only required field.The second argument is a object used to store a company info like plan, MRR, and company demographics.The third argument is a string containing company website or email domain. If set, Moesif will enrich your profiles with publicly available info.moesif.identifyCompany(&quot;67890&quot;, metadata, &quot;acmeinc.com&quot;);track, (string, object) =&amp;gt; nullTrack user actions such as “clicked sign up” or “made a purchase”. By tracking user actions in addition to API usage via one of the Moesif server SDKs, you’ll be able to understand the entire customer journey from initial sign up to first API call. First argument is an action name as a string, which is required. Second parameter is an optional metadata object related to this action event. See API Referencemoesif.track(&#39;clicked_sign_up&#39;, {  button_label: &#39;Get Started&#39;});identifySession, (string) =&amp;gt; nullThe Moesif SDK tracks browser sessions automatically and saves in a Cookie. You can override with a specific session token.The new session token will continue to be used until identifySession is called again.moesif.identifySession(&quot;d23xdefc3ijhcv93hf4h38f90h43f&quot;);reset, () =&amp;gt; nullClears any saved userId, companyId, and any other device context like anonymousId.You must call reset() when a user logs out of your web app which will force the SDK to generate a new anonymousId.This ensures a new anonymous id is generated and ensuring different sessions are not mixed up.This is especially important for testing if you are logging into multiple accounts from the same device.moesif.reset()start, () =&amp;gt; nullIn addition to tracking user actions, the SDK can also log outgoing API calls.When you call start(), the SDK will log AJAX API calls, including:  Your own APIs (such as an API powering your Single Page App)  3rd party APIs (such as to Stripe and Twilio)  Decentralized APIs such as DApps communicating with Ethereum Web3/interactions with smart contractsmoesif.start()stop, () =&amp;gt; nullStops logging AJAX API calls. It is not required to call this, since recording will stop automatically when the browser tab is closed.However, you can call stop directly if you want more control. Call start again to restart API logging.moesif.stop()cdtUrlDecorator, (string, boolean) =&amp;gt; stringManually decorates a URL with the current anonymousId for use with navigation methods that cannot be intercepted automatically (e.g., window.location.href, window.open()). Requires enableCrossDomainTracking: true in init().The second argument overrideCDTTargets (default false) forces decoration even if the target domain is not in crossDomainTargets.Returns the decorated URL as a string. If the target domain is not allowed and overrideCDTTargets is false, the original URL is returned unchanged.const decoratedUrl = moesif.cdtUrlDecorator(&#39;https://console.bijira.dev/signup&#39;);window.location.href = decoratedUrl;useWeb3, (web3) =&amp;gt; booleanSets the web3 JSON-RPC to use the web3 object passed in. If no argument is passedin, it will try to restart capturing using the global web3 object. Return true if successful.moesif.useWeb3(myWeb3Object);grantPublishingConsent, () =&amp;gt; voidCall this method when the user grants consent to send data to Moesif. This will:  Flush all queued events to Moesif servers  Clear the local queue after successful delivery  Allow future events to be sent immediately// When user clicks &quot;Accept Cookies&quot; or &quot;Accept Tracking&quot;moesif.grantPublishingConsent();Refer Consent Management more details.revokePublishingConsent, () =&amp;gt; voidCall this method when the user revokes consent. This will:  Stop sending new events to Moesif  Clear any queued events  Start queuing new events locally again (if recording is active)// When user clicks &quot;Revoke Consent&quot; or &quot;Opt Out&quot;moesif.revokePublishingConsent();Refer Consent Management more details.isPublishingConsentGranted, () =&amp;gt; booleanReturns true if consent to publish has been granted, false otherwise.if (moesif.isPublishingConsentGranted()) {  console.log(&#39;User has granted consent to publish data&#39;);} else {  console.log(&#39;User has not granted consent yet&#39;);}Refer Consent Management more details.Configuration optionsThe options is an object that is passed into the SDK’s init method.applicationId - string, requiredThis is the collector API key that is obtained from your Moesif account. You should only use your publishable application id in untrusted apps like client-side javascript. Publishable Collector Application Id’s are write-only keys and can be safely used on the client side.enableCrossDomainTracking, boolean, optional, default falseEnables Cross-Domain Tracking (CDT). When true, the SDK will automatically decorate outgoing cross-domain anchor links and GET form submissions with the current anonymousId. Use cdtUrlDecorator() for JS-based navigations that cannot be intercepted automatically.Both the origin and destination sites must have this option enabled for tracking to be stitched together correctly.crossDomainTargets, null | string[], optional, default: unset (no decoration)Controls which destination domains will have their URLs decorated with the anonymousId.  null — decorate all outgoing cross-domain links.  [&quot;domain-a.com&quot;, &quot;domain-b.com&quot;] — only decorate links pointing to the listed domains.  Unset (not provided) — no cross-domain links are decorated. You must explicitly set this option to null or a non-empty array to activate URL decoration.crossDomainTrackingParameterName, string, optional, default __mtThe URL query parameter name used to carry the anonymousId between domains. Override this if __mt conflicts with an existing parameter in your application.batchEnabled, boolean, optional, default false.Will start batching the tracking of API Events and User Actions to sent to Moesif. The identifyUser and identifyCompanies are not batched.batchSize, number, optional, default 25Even if set, the batchSize is used on a best effort basis. If the payloads sizes get too big, the batchSize maybe auto adjusted.batchMaxTime, number in milliseconds, optional, default 2500The maximum interval to flush the queue when the batch size have not been reached.eagerBodyLogging, boolean, optional, default falseSome complex frameworks like Angular monkey patch to intercept the response body. If you are an Angular user or find that the response is not being captured, turn this option on to eagerly capture the response info.persistence, string, optional, default localStorageThe allowed values are localStorage, cookie, and none.Moesif saves session info like anonymous ids and identified ids to a device’s storage to accurately track returning visitors even if they haven’t signed in.      When set to localStorage (the default setting), will write session info to localStorage and then replicate to a cookie for redundancy.This ensures that if the user clears local storage or visits a different subdomain (like from docs.acmeinc.com to acmeinc.com), there is stilla cookie to fall back to and the user can be accurately attributed. This setting is recommended for most applications.        When set to cookie, session info and anonymous ids is persisted to cookies only. No local storage is used.Note: If you’re using the requirePublishingConsent feature, the pending events queue will NOT persist across page refreshes in this mode (stored in-memory only).        When set to none, nothing will be persisted. Not recommended except for advanced use cases or testing. Refreshing the browser tab will create a new user session.Note: The pending events queue (when using requirePublishingConsent) will also not persist across page refreshes in this mode.  Keep in mind if a user clears both their cookies and their local storage, then a new anonymousId will be generated,As long as you called identifyUser before the data was cleared, Moesif will still merge the two sessions.crossSiteCookie, boolean, optional, default false,This enables cross-site requests by adding SameSite=None; Secure to the cookie.This is used for special situation such as if your application is embedded in an iframe.  When enabled, secureCookie is forced to true due to modern browser requirements.crossSubdomainCookie, boolean, optional, default true,When true, the cookie domain will also allow all subdomains of your hostname. This is usually recommended to track anonymous users across multipleproperties like https://www.acmeinc.com vs https://docs.acmeinc.com.cookieExpiration, number, optional, default 365Set the cookie expiration in days. By default this is 365 days.secureCookie, boolean, optional, default false,If set to true, the cookie can only be read on https:// websites.cookieDomain, string, optional, default ‘’To override the domain of the cookie, you can set this such as to *.acmeinc.compersistenceKeyPrefix, string, optional, default moesif_The keys used for saving into local storage and cookies start with moesif_. You can override the prefix such as if you’re running multiple instances of moesif-browser-js.disableFetch, boolean, optional, default false.Starting from version 1.4.0, this SDK also instruments fetch API if it is not polyfilled.Some browsers may use fetch under XmlHTTPRequest, then it is possible events get duplicated. In this case, disable fetch will fix the issue.skip, (event) =&amp;gt; boolean, optionalA function hook that will skip logging the event to Moesif if returns true.The parameter passed in is an event model. See event model.High volume APIs can reduce cost tremendously by leveraging dynamic sampling to set ruleswithout any code change or restarts. Moesif will still extrapolate original metrics so your reporting is accurate.maskContent, (event) =&amp;gt; event, optionalA function hook that enables you to mask any sensitive data in the event model. Your custom code must return the sameevent, after applying any masking.For super sensitive data, Moesif recommends leveraging zero-knowledge security with on-premises client-side encryption and bring your own keys (BYOK).getMetadata, (event) =&amp;gt; object, optionalFunction that allow you to append arbitrary JSON metadata to API calls before being logged to Moesif.host, string, optionaldefaults to api.moesif.net. If you are using a proxy to send data to Moesif, please set the the host to proxy.yourcompany.com.full options example:var options = {  applicationId: &quot;Your Publishable Moesif Application Id&quot;,  skip: function (event) {    if (event.request.uri.includes(&quot;google&quot;)) {      return true;    }    return false;  },  maskContent: function (event) {    if (event.request.headers[&quot;secret&quot;]) {      event.request.headers[&quot;secret&quot;] = &quot;&quot;;    }    return event;  },  getMetadata: function (event) {    if (event.request.uri.includes(&quot;stripe&quot;)) {      return {        type: &quot;payment&quot;,      };    }  },  host: &#39;proxy.acmeinc.com&#39;};moesif.init(options);requirePublishingConsent, boolean, optional, default falseWhen set to true, the SDK will queue all tracking events locally instead of sending them to Moesif. Events remain queued until grantPublishingConsent() is called.moesif.init({  applicationId: &#39;Your Publishable Moesif Application Id&#39;,  requirePublishingConsent: true, // Queue events locally until consent is granted  maxQueueSize: 1000 // Optional: Set queue size limit});maxQueueSize, number, optional, default 1000The maximum number of events that can be queued locally before consent is granted. When the queue reaches this limit:  The oldest event is dropped (FIFO queue)  The newest event is added to the queueThis prevents unbounded memory growth if a user never grants consent.moesif.init({  applicationId: &#39;Your Publishable Moesif Application Id&#39;,  requirePublishingConsent: true,  maxQueueSize: 500 // Limit queue to 500 events});Ethereum DApp supportDApps (Decentralized Apps) are frontend apps which interact with blockchains such as Ethereum over an API like any other Single Page App. For Ethereum, this API layer uses JSON-RPC and is called the Ethereum Web3 API which Moesif supports natively.Moesif will capture interactions with the Ethereum blockchain just like any other API to understand usage and monitor for any issues affecting your Dapp. Because this data is binary, there are additional set up steps needed to convert these API interactions into something human readable. Checkout Moesif’s Ethereum Web3 documentation for more info.There is also a tutorial available on Building an Ethereum DApp with Integrated Web3 Monitoring.Web3 objectMany Dapp clients such as the Metamask extension and Mist Browser, will inject a web3 object directly in the browser’s global scope.The default moesif-browser-js config will automatically instrument the injected web3 object and capture outgoing API transactions to the Ethereum network.For advanced scenarios where your code uses a different web3 object than the default one, you can call moesif.useWeb3(myWeb3) to ensure the correct web3 instance is instrumented.The web3 object can change if you let users modify the selected web3 provider or change their network. An example is below:if (typeof web3 !== &quot;undefined&quot;) {  myWeb3 = new Web3(web3.currentProvider);  // No action needed by Moesif} else {  // set the custom provider you want from Web3.providers  myWeb3 = new Web3(new Web3.providers.HttpProvider(&quot;http://localhost:8545&quot;));  moesif.useWeb3(myWeb3);}TroubleshootingResponse not being loggedCertain frameworks like Angular monkey patch the XMLHttpRequest heavily. In these cases, enable the eagerBodyLogging option to eagerly capture the response info.Incorrect user trackingIf you see inaccuracies with your customer funnel such as user actions being associated to the wrong user, ensure you are calling moesif.reset() when a user logs out of your application. Without this step, Moesif has no knowledge that the user logged out and will continue to associate activity to the old user even if a new user logs into the same device/browser.Duplicate API eventsBy default, moesif-browser-js captures both outgoing API calls from XMLHttpRequest and the web3 object.This way you can see both blockchain related transactions along with other 3rd party APIs like Twilio or Stripe.If the Web3 provider is also using the XMLHttpRequest (such as the HttpProvider), it’s possible that the same API call is captured twice.This is expected.moesif-browser-js adds metadata depending on the captured source. For events that are captured via web3, we add additional event metadata for the web3 provider used.As an example:{  &quot;_web3&quot;: {    &quot;via_web3_provider&quot;: true,    &quot;is_metamask&quot;: true  }}Cross-domain tracking not working  Confirm enableCrossDomainTracking: true is set in moesif.init() on both the origin and destination domains.  Confirm crossDomainTargets is explicitly set to null (all domains) or an array containing the destination domain. If the option is omitted, no URL decoration will occur.  For JS-based navigations (window.location.href, window.open(), etc.), ensure you are wrapping the target URL with moesif.cdtUrlDecorator() before navigating. These methods cannot be intercepted automatically.  POST form submissions are not decorated. Use a GET form or a JS-based redirect with cdtUrlDecorator() instead.  Check whether a privacy-focused browser extension is stripping the __mt query parameter. You can customise the parameter name via crossDomainTrackingParameterName to avoid conflicts with known filter lists.Examples  Several examples for how to import this library are in the example folder of this repo, moesif-min folder have more examples usage.  Example setup for react-boilerplate. For React apps, if you set up server-side rendering, please ensure that this library is only initiated on the client-side.  Example setup for an Etherum Dapp.Credits for moesif-browser-jsSome of the build scripts, utilities, and directory structure is based on Mixpanel’s Javascript Client Library,which is under Apache 2.0 license.Some utilities are based on underscore.To modify and build this library, please see instructions in Build.mdNote, this library has ZERO external dependencies (only have dev dependencies or dependencies for some of the examples).Other integrationsTo view more more documentation on integration options, please visit the Integration Options Documentation.",
      "url": " /client-integration/browser-js/",
      "author": "Derric",
      "categories": "Integration, Client"
    }
    ,
  

    "client-integration-docusaurus": {
      "title": "Server Integration Guide - Docusaurus",
      "content"	 : "Moesif Docusaurus PluginA Docusaurus plugin for Moesif API Analytics built using moesif-browser-js.For full documentation and configuration, see moesif-browser-js docsThe SDK automatically collects useful context from a user’s device including any marketing attribution, device type, and location information and stores in the user and/or company profile in Moesif. You can add additional customer properties such as user email and company domain via the identifyUser() and identifyCompany() methods.  The below Diagram shows how both docusaurus-plugin-moesif and a Moesif server integration to track both web and API traffic made by a customer.How to install      Install docusaurus-plugin-moesif    npm install --save docusaurus-plugin-moesif        Add plugin to docusaurus.config.js     module.exports = {   plugins: [&#39;docusaurus-plugin-moesif&#39;],   themeConfig: {     moesif: {       applicationId: &#39;Your Moesif Application Id&#39;,       // Add other Moesif options here.     },   }, };            Test it works    Because the plugin is disabled when NODE_ENV is set to development, you’ll want to create a production build:     npm run build npm run serve      How to useAny of the Moesif browser APIs are accessible via window.moesif.The plugin tracks page views automatically but we also recommend identifying the user like so:window.moesif.identifyUser(&quot;12345&quot;, {  email: &quot;john@acmeinc.com&quot;,  firstName: &quot;John&quot;,  lastName: &quot;Doe&quot;,  title: &quot;Software Engineer&quot;,  salesInfo: {    stage: &quot;Customer&quot;,    lifetimeValue: 24000,    accountOwner: &quot;mary@contoso.com&quot;,  },});Configuration OptionsFor full list of configuration options, see this page.",
      "url": " /client-integration/docusaurus/",
      "author": "Derric",
      "categories": "Integration, Client"
    }
    ,
  

    "client-integration-google-tag-manager": {
      "title": "Server Integration Guide - Google Tag Manager",
      "content"	 : "Moesif plugin for Google Tag Manager      Moesif is an API analytics service. This tag enables you to track user behavior within your web app. You can also install the Moesif server agent to understand the customer journey across both your website and APIs together.        Google Tag Manager account is a free application which enables marketing and product teams to quickly add script tags for analytics, attribution tracking, and more without code changes.    You can use this plugin alongside a Moesif server integration to monitor server-side API traffic. This enables you to track your end-to-end customer journey and build cross-platform funnel reports like your initial sign up to first API call conversion rate.How to installMoesif has a GTM tag in the Google Tag Manager template gallery.This installs the moesif-browser-js script without any code changes.1. Add TagLog into your Google Tag Manager account and select Tags from the left menu.Then, click New from the top right like in the below picture.Select the Community Template Gallery blue banner and search for “Moesif API Analytics”.Then, click the blue Add to Workspace button.2. Set Moesif Application IdIn the Tag configuration, add your Moesif application Id. Your Moesif Application Id will be displayed during the onboarding steps when signing up for Moesif.By default, the Action Name is set to “Page View”. We recommend setting a descriptive name based on your chosen trigger in next step. For example, if the tag is fired on your Sign In Page, then set Action Name to “Sign In”3. Choose a TriggerChoose a trigger that will cause the tag should be fired such as “All Pages”.For more info on how to create custom triggers, see Google’s documentation.How to useWhen the tag is fired, the tag will log a user action to Moesif.Event metadataThe Tag also supports event metadata which is a table of key/value pairs. The tag also supports dynamic variables.You can access any of the moesif-browser-js APIs via window.moesif including identifyUser(). This can be useful since Google Tag Manager doesn’t support tracking user ids directly.Identifying usersWhen you know the user’s id such as after sign in, call identifyUser.This tells Moesif who the current user is so their actions can be linked to a user profile.Besides the userId, you can also save related properties such as user demographics and subscription information.window.moesif.identifyUser(&quot;12345&quot;, {  email: &quot;john@acmeinc.com&quot;,  firstName: &quot;John&quot;,  lastName: &quot;Doe&quot;,  title: &quot;Software Engineer&quot;,  salesInfo: {    stage: &quot;Customer&quot;,    lifetimeValue: 24000,    accountOwner: &quot;mary@contoso.com&quot;,  },});The recommended place to call identifyUser is after the user logs in and you know their real user id.  Do not call identifyUser for anonymous users. Moesif will track these users automatically.Identifying companiesIn addition to identifying users, you can also identify the company for account-level tracking. Besides the companyId, you can also save related properties such as company demographics and website domain.// Only the first argument is a string containing the company id. This is the only required field.// The second argument is a object used to store a company info like plan, MRR, and company demographics.// The third argument is a string containing company website or email domain. If set, Moesif will enrich your profiles with publicly available info.metadata = {  orgName: &quot;Acme, Inc&quot;,  planName: &quot;Free Plan&quot;,  dealStage: &quot;Lead&quot;,  mrr: 24000,  demographics: {    alexaRanking: 500000,    employeeCount: 47,  },};window.moesif.identifyCompany(&quot;67890&quot;, metadata, &quot;acmeinc.com&quot;);  If you call both identifyUser() and identifyCompany() in the same session, then Moesif will automatically associate the user with the company.Tracking actions directlySince you have the entire moesif-browser-js API available through window.moesif, you can track actions directly using the track() function:window.moesif.track(&#39;clicked_sign_up&#39;, {  button_label: &#39;Get Started&#39;});",
      "url": " /client-integration/google-tag-manager/",
      "author": "Derric",
      "categories": "Integration, Client"
    }
    ,
  

    "client-integration-segment": {
      "title": "Moesif&apos;s Segment Plugin",
      "content"	 : "Moesif Segment PluginThe Segment integration is installed simply by connecting your Moesif account to your Segment account and doesn’t require any code changes.  The integration can be used both as a Segment destination and a source.Segment destinationAs a Segment destination, Segment will sync user traits and tracked events to Moesif. Moesif also associates your web activity toAPI traffic so you can analyze the end to end customer journey and funnel metrics.Use the Moesif API Analytics Destination if you want to:  Enrich users in Moesif to understand API usage by acquisition channels and customer demographics.  Correlate API calls in Moesif with events tracked by Segment  Track funnel metrics like Time to First Hello World (TTFHW) and conversion rateThe below Diagram shows how both Segment and a Moesif server integration to track both web and API traffic made by a customer.For more info, see Moesif Segment Destination.Segment sourceAs a Segment source, Moesif will sync Moesif user profiles and their API metrics to Segment.Use the Moesif API Analytics Source if you want to:  Track API usage in tools like Amplitude and Mixpanel.  Trigger email sequences in tools like HubSpot like when customers approach rate limits.  See trial or pilot usage in your CRM to prioritize customer outreach.Segment is not required to view Moesif data in your sales and marketing tools. Moesif has a variety of extensions for tools like Salesforce and HubSpot.For more info, see Moesif Segment Source.How to installSegment destination  From your Segment UI’s Destinations page click on “Add Destination”.  Search for “Moesif” within the Destinations Catalog and confirm the Source you’d like to connect to.  Enter the Moesif “API Key” into the destinations settings in the Segment App. You can find these by going to your Moesif account account and navigating to the extensions settings.  Once integrated, Segment data shows up in Moesif in a few seconds.  If not done already, associate API calls to a user id by implementing the identifyUser() hook for your respective server integration. This should be the same id you use when calling Segment’s identify() method.Segment source  From your Segment UI’s Sources page click on “Add Source”.  Select Moesif API Analytics within the Source Catalog and confirm adding the source.  Give the Source a nickname and follow the setup flow to “Add Source”.  Copy the Write Key from the added source. You’ll need this later in Moesif.  Log into your Moesif account, go to the Settings menu and click Extensions.  Select the Segment Extension within the extensions gallery and add your write key under Add Partner Key.How it worksSegment destinationThe Segment destination can be used instead of moesif-browser-js directly to track web activity and supports both identify and track to Moesif.IdentifySegment sends identify() calls to Moesif as user updates. If you set traits.company.id on the user, Moesif also associates it with a company. The integration maps user fields as follows:            Segment Field      Moesif Field              userId      user_id              traits      metadata              traits.company.id      company_id      The integration handles Segment reserved traits like email and firstName. It also maps automatically-collected fields like campaign information and IP address.TrackSegment sends track() calls to Moesif as tracked custom actions which you can see in the Events section in Moesif. As an example, you can use Segment’s analytics.js to track when the login button is clicked:analytics.track(&#39;Login Button Clicked&#39;)The integration maps event fields as follows:            Segment Field      Moesif Field              event      action_name              properties      metadata      Both Segment and Moesif support automatic anonymous user tracking. You should only call identify with an actual user id.Segment sourceThe segment source will periodically sync user profiles in Moesif to Segment as user traits viaa identify() message.Because API calls contain a very large number of fields and values, they cannot be ingested in a UI event tracking tool like Segment or Amplitude directly as they’re not designed for API data. Instead, Moesif rolls up API usage metrics and adds to the user as a user trait called last24HourAggResults.Identify Message            Field      Type      Description                  userId      String      Unique identifier for the user in Moesif              context      Object      User context like IP address and location.              traits      Object      Custom traits of the user (See Traits Object)      Traits ObjectThe integration maps user metadata in Moesif to the Segment trait called metadata.If the user was linked to a company in Moesif, the integration will map the associated company to a Segment trait called company.            Field      Type      Description                  id      String      User Id (Same as userId in parent object)              createdAt      Date      Time when user was created in Moesif              modifiedTime      Date      Time when user was last modified              firstSeenTime      Date      Time user was first seen on the API              lastSeenTime      Date      Time user was last seen on the API              name      String      User’s Full Name              email      String      User’s email              username      String      Username such as a Twitter handle              company      Object      Company in Moesif (See Company Object)              campaign      Object      Marketing campaign attribution like UTM parameters              enrichment      Object      Auto-enrichment lookup results for the user              company      Object      Associated company in Moesif (See Company Object)              last24HourAggResults      Object      Rollup of user’s API activity from last 24 hours              metadata      Object      Your user metadata              userAgent      Object      Last user agent details      Company ObjectInfo for the associated company. Any company metadata set in Moesif is mapped to the Segment trait company.metadata            Field      Type      Description                  id      String      Unique identifier for the company in Moesif              created      Date      Time when company was created in Moesif              modifiedTime      Date      Time when company was last modified              firstSeenTime      Date      Time user was first seen on the API              lastSeenTime      Date      Time user was last seen on the API              ipAddress      String      Company’s last IP address              companyDomain      String      Company’s website domain              ttfhw_s      Integer      Time to First Hello World in seconds              metadata      Object      Your company metadata      ",
      "url": " /client-integration/segment/",
      "author": "Derric",
      "categories": "Integration, Client, Ingest Actions"
    }
    ,
  

    "api-dashboards": {
      "title": "Introduction to Team Dashboards",
      "content"	 : "Team dashboards allow you to save and track against key metrics that are important to you.You can create as many dashboards as you want. You can also organize dashboardsby different criteria, like project and department.Moesif organizes dashboards in a tree-like structure, visible in the navigation menu. Each dashboard acts like a file directory that contains an arbitrary number of workspaces—charts containing analysis. A dashboard can also contain other dashboards.Definitions  Workspace  A single chart or tile on a dashboard that represents a specific metric.  Dashboard  A collection of workspaces. A dashboard can also hold other dashboards like a file directory.Prebuilt dashboardsTo help you get started faster, your Moesif account has several prebuilt dashboards, one for each of the following departments:  Product  Customer Success  Engineering  Security  Sales  MarketingEach of these prebuilt dashboards contains metrics based on what we’ve seen work best. These can provide a good starting point for you to customize and build on. You can start with a blank slate and create a new dashboard that perfectly suits your needs.Types of workspacesThe following four types of workspaces are supported:  Private  Team  PublicWhen you first save a workspace, you can set the type by selecting a type from the Sharing dropdown menu:You can always change the type later anytime by following these steps:  Open the workspace.  Select Share and then choose a type.  Select Save.Private workspacesOnly the person creating a private workspace can view it. Other team members with access to Moesif can’t view this chart. This holds true even if they have access to the dashboard that you’ve added the chart to. These workspaces are effectively hidden from discovery.Team workspacesAnyone can discover team workspaces who has access to your Moesif organization. With team-level sharing, it’s easy to collaborate on KPIs and reports and share with other internal stakeholders.  To see the list of members of your Moesif organizations, select your account icon to bring up the settings menu bar. Then select Apps and Team. For more information, see the documentation on Apps and Team.Public workspacesAnyone with the public link can access the chart. Unlike Private or Team sharing, a person can view a public workspace even if they haven’t signed up for Moesif. Public workspaces also belong to a dashboard, but most users leverage public links to share a single chart with a customer or partner.You can also use public links to embed the chart in markup directly using the &amp;lt;iframe&amp;gt; HTML element.After saving your workspace, select  Share.Then select Save and Generate Public Link to generate public links to your chart. You can choose how you want to share from the Secure Link, iFrame, and Passcode tabs.Restricting data accessBecause public links are intended to be shared with external parties, the data will be sandboxed by your chosen filters.For example, if you filter by a specific user ID, then anyone with the public link can only access API data made by that specific user ID. Keep in mind not all filters support data sandboxing, but Moesif will show you which filters will be used before saving the link.Hiding Headers in Public LinksBy default, public links include a small header containing filter dropdowns and chart name. If you want to hide all elements besides the chart itself, set this to true. Because the filters are hidden, you’ll need to ensure any filters are added when you initially create the template.To accomplish this, add &amp;amp;hide_headers=true to the generated URL after &amp;amp;embed=true.Embedded TemplatesEmbedded templates are a special type of sharing that enables you to build powerful charts and embed them in customer-facing portals. Dynamic fields don’t need to be set until the chart is actually rendered.Unlike public links which are static, Embedded templates enable the filter criteria to be set dynamically. For example, you may want to dynamically set the user ID to the customer who logged into your web app.  Generally, you will want to use an embedded template to show data to an authenticated user. The data displayed can then be tailored to that users based on, for example, the users ID.",
      "url": " /api-dashboards/",
      "author": "Derric",
      "categories": "Dashboards"
    }
    ,
  

    "api-dashboards-creating-a-dashboard": {
      "title": "Creating a Dashboard",
      "content"	 : "  This guide assumes you are familiar with Dashboards already. If not, please review our high-level docs on API Dashboards.Moesif does not have any limits on the number of dashboards you can create. Each dashboard can contain an unlimited number of workspaces within it.Creating a dashboardTo create a dashboard, you have the following two options:      Select + Create New. In the modal that appears, select Dashboard.            Select + Add New Dashboards beside the Saved Dashboards menu item.      Saving a workspace to a dashboard  You can save almost every chart you see in Moesif to a dashboard. This includes live event logs, time series, bar chart, heatmap, and funnels. To get started, navigate to the Users or Companies screen to start a new analysis. Within the chart view, set up the filters, group by, and time range options for your chart.Once you have created a new analysis or chart and are ready to add it to a dashboard, click the orange Save button.The Save Workspace modal then appears, allowing you to save the workspace.In the modal, you must choose a name for your workspace and select a dashboard to save it to. Use the Select Dashboard dropdown menu to add it to an existing dashboard or create a new one for the workspace.  You can also set your workspace type in Save Workspace. For more information, see Types of workspaces.  If the date range is relative, such as Last 7 Days, then the chart will always be up to date for latest data. However, if you select an absolute time range, like May 1, 2021 to May 31, 2021, then the chart data will not be refreshed (unless the date range is in the future).Edit workspace filter or metricsIn order to change an actual metric, click on the chart name in the tile to bring up the full view of the chart, log, or analysis.From here, the filter criteria can be changed.Once you made your changes, click Save in the top right.",
      "url": " /api-dashboards/creating-a-dashboard/",
      "author": "Derric",
      "categories": "Dashboards"
    }
    ,
  

    "api-dashboards-viewing-dashboards": {
      "title": "Viewing Dashboards",
      "content"	 : "This page describes how to view, configure and use dashboards.Both Full-Access Team Members and Dashboard Viewers seats can access and use dashboards.Open workspacesYou can open a workspace by selecting its name in the workspace tile of the dashboard. You can also open a worksapce from the navigation menu by expanding a dashboard dropdown and selecting the workspace name.Refresh intervalBy default, dashboards do not reload or refresh to reflect the latest data that has come in. However, you can select a time interval for when you want the dashboard to refresh. This can prove useful in real-time scenarios, for example, if a TV in the office features the dashboard and you want it to always stay up-to-date.Override date RangeYou can quickly override the date range of all workspaces within a dashboard by selecting Override Date Range. By default, each chart uses the date range associated with the chart.The date range you apply here applies to all workspaces in a dashboard, regardless of whether a dashboard currently has a date range in its filter.Overriding date range makes it easy to toggle the same dashboard between different ranges.By default, the dashboard uses the Default Date Ranges date range. These are default ranges specified for the metrics in each individual workspace in the dashboard.The following predefined date ranges are available:  Last 15 minutes  Last hour  Last 24 hours  Last 7 days  Last week  Last 28 days  Last month  Last 4 weeks  Last 12 weeks  Last yearBy selecting Custom, you can specify a particular relative date range not available in the preceding date ranges. If you want more precise time control, choose an absolute date range from  Absolute Date Range.Last Month refers to the first day of the previous month and ends at the current date. To specify previous calendar month, do one of the following:  Specify either a custom date range with the previous number of days and now.  Use an absolute date range with the two dates.Apply Additional FiltersYou can add filters to the dashboard by selecting Apply Filters. This filter aplies to all workspaces of the dashboard.Before you apply a global filter in a dashboard, make sure a workspace doesn’t already have the same filter applied to avoid conflicts.A common use case for the filter override is to easily filter for a specific product or customer ID while having a common dashboard containing all KPIs (key performance indicators). With this feature, you don’t have to manually create a dashboard for each customer.Moesif also has profile dashboards that have been designed specifically for customer-facing teams to have a one spot to see a customer’s usage metrics, profile, and billing information.When you add a filter to a dashboard, a blue filter funnel icon appears in the workspace tiles of that dashboard.Workspace tile optionsYou hover over a workspace tile in a dashboard for additional options:  View Expanded  Open the workspace in detailed view in the current browser tab.  Show Detailed Info  View information like workspace owner, workspace type for sharing, and the analysis time period.  Open in New Tab  Open the workspace in a new browser tab.  Delete  Delete the workspace.",
      "url": " /api-dashboards/viewing-dashboards/",
      "author": "Sakib",
      "categories": "Dashboards"
    }
    ,
  

    "api-dashboards-managing-dashboards": {
      "title": "Managing Dashboards",
      "content"	 : "This page describes how you can manage your dashboards.Moving dashboards and workspacesEach dashboard consists of workspace tiles. Workspace tiles can be moved within a dashboard via drag-n-drop. Simply click-and-hold on the Workspace tile you’d like to move and place it as desired within the grid.You can move workspace tiles into other dashboards by clicking and holding a tile, dragging them into the desired dashboard hierarchy in the left nav and releasing the item. This will then result in the moved dashboard appearing in the destination dashboard.Dashboards can be nested under other dashboards by also dragging them under the desired dashboard within the left nav.We highly recommend that you organize your dashboards by team or product. The prebuilt dashboards Moesif provides can give you an idea about how to organize.Dashboard actionsEach dashboard allows you to perform a set of actions.The following actions are available:  Save a dashboard.  Delete a dashboard.  Make a copy of a dashboard.  Set the refresh interval for a dashboard.  Set the time period for a dashboard.  Apply filters globally for event based workspaces in a dashboard.Saving dashboardsAfte you’ve made a change to a dashboard, for example, applied a global filter, select Save to save your changes.Deleting dashboardsTo delete a dashboard, select Delete.Before you delete a dashboard, carefully examine any charts and other dashboards that a particular dashboard holds. Delete them first or copy them to another dashboard if necessary. This ensures that you don’t accidentally incur any data loss by deleting a parent dashboard.Copying dashboardsYou can duplicate any dashboard by selecting Copy in Dashboard Actions.This action copies all the charts within the dashboard. If you edit a copied dashboard, it doesn’t impact the original dashboard.Duplicating dashboards can prove useful when you want a template dashboard that already contains all the metrics you want for all new projects or apps.",
      "url": " /api-dashboards/managing-dashboards/",
      "author": "Sakib",
      "categories": "Dashboards"
    }
    ,
  

    "api-dashboards-profile-dashboards": {
      "title": "Profile Dashboards",
      "content"	 : "  Profile Dashboards share much of their functionality with Dashboards. This guide assumes you are familiar with Dashboards already. If not, please review our high-level docs on API Dashboards as well as our docs on Creating Dashboards.Profile Dashboards enable you to see key API metrics for specific users and companies. They provide individualized account metrics across your entire customer base. This is accomplished by providing a customizable template that is applied to each user’s or company’s profile page. Profile Dashboards are located at the bottom of any user or company profile page.There are two pre-configured Profile Dashboard templates provided initially. A template for user profiles and another for company profiles. Additional templates can be created, configured, and quickly switched between.Viewing Profile Dashboard templatesYou can access profile dashboard templates in two ways:      Select the Profile Dashboards dropdown under  Saved Dashboards and select either User Profile or Company Profile.            From a user or company profile page, select the  vertical elipsis beside Company Profile Dashboard or User Profile Dashboard and then select Edit Template.      After that, you can start configuring the template.Editing existing Profile Dashboard templates  You can save almost every chart you see in Moesif to a profile dashboard. This includes live event logs, time series, bar chart, heatmap, and funnels. To get started, navigate to the Users or Companies screen to start a new analysis. Within the chart view, set up the filters, group by, and time range options for your chart.You can use only event-type workspaces in user profile dashboards.Once you create a new analysis or chart and are ready to add it to a profile dashboard, select  Save.The Save Workspace modal then appears. Select Profile Dashboards from the Select Dashboard menu and select the profile dashboard you want to save the workspace to.Then enter your workspace name and then select Save to add the workspace to the profile dashboard you want, Company Profile or User Profile.To navigate back to the profile dashboard you have been editing, select the Profile Dashboards dropdown and select either User Profile or Company Profile.You can see the new workspace appear in your profile dashboard template. You can access this workspace immediately when viewing the respective user or company profile dashboard.Creating new Profile Dashboard templatesYou can create additional profile dashboards to provide more versatility for your team and gain additional insights into your customers without cluttering up a single dashboard.To create a new profile dashboard template, select + Add sub-Dashboard beside the Profile Dashboards dropdown.Give your new sub-dashboard a name and select the Add.Your new sub-dashboard then appears under Profile Dashboards.You can populate this new sub-dashboard by following the instructions in Editing Existing Profile Dashboard Templates.Switching between Profile Dashboard templatesYou can leverage multiple profile dashboard templates and quickly switch between them to capture greater insights into your customer base.To specify which template your profile dashboards use, do one of the following:      Navigate to the profile dashboard template you want to apply from Profile Dashboards. Select the  vertical elipsis and then select either Display In User Profiles or  Display In Company Profiles.        A modal then appears requesting confirmation of the change. Based on your prior selection, select  Replace in User Profiles or Replace in Company Profiles.        A confirmation message then lets you know the change has been accepted and applied to the profile.        When viewing a profile dashboard on a Users or Companies profile page, select the  vertical elipsis and then select  Switch Template.        A modal then appears asking which dashboard you want to use as a replacement. Make your selection and then click Replace In User Profiles or Replace In Company Profiles.        A dialog appears confirming the selected replacement dashboard change which is immediately viewable within the Profile Dashboard section.      ",
      "url": " /api-dashboards/profile-dashboards/",
      "author": "Dylan",
      "categories": "Dashboards, Profile Dashboards"
    }
    ,
  

    "api-analytics": {
      "title": "Introduction to Event Analytics and Logging",
      "content"	 : "  If you’re not already familiar with API analytics, see Moesif’s e-book API Analytics: The Ultimate Guide to Grow Your Platform Business.Moesif’s API Analytics suite allows you to get user-centric insights into API usage and user behaviors. Moesif’s platform leverages high-cardinality, high-dimension analytics. This means you can filter and aggregate billions of API calls and custom actions on pretty much any field even for a high-cardinality field like a session token or user ID.A high-cardinality field contains a large number of distinct values. For example, a field like user ID, that uniquely identifies each user.Moesif’s API Analytics suite supports the following metric types for different requirements and use cases:  Live Event Log  Time Series  Segmentation  Geo Heatmap  Trace ExplorerThis document gives a general overview of and explains some of the common features available in all metric types and analysis.API CallsThe API Calls event type in Moesif represents any event that involves calling an API. Using a Moesif server integration, Moesif can log API calls for popular API gateways and API frameworks.To display only API calls in a time-series chart, specify Event Type.is.API Call as the filter.ActionsThe Actions event type in Moesif represents custom actions that occur in the UI of your product. For example, a user signing in, a new user signing up, or a user viewing the product documentation. You can track these custom events with a Moesif client integration.To display only Actions in a time-series chart, specify Event Type.is.Actions as the filter.FiltersMoesif offers a vast array of filters that can provide deeper insights into your API analytics data. These filters allow you to construct powerful and complex queries for different metric types and build intuitive visualizations.For a reference documentation for the filters, see Reference: Analytics Filters.API protocol supportMoesif supports a variety of API protocols including REST, GraphQL, and Ethereum Web3 (JSON-RPC) APIs.For more information, see GraphQL Support and JSON-RPC Support.Share WorkspacesMoesif allows you to select specific data to share with your partners or customers without exposing all your API data. You can securely share your metrics and visualizations in different ways that suit your requirements.For more information, see Sharing Workspaces.Bookmarkable URLsMoesif persists any active search criteria to the browser’s address bar. You can pass the URL in your browser’s address bar to a teammate and they see the same data with the filters you’ve already applied. Therefore, your teammates don’t have to apply those filters again. This makes sharing and saving your favorite searches fast and easy.AI ExplainAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about analytics data. AI Explain greatly improves the accessibility of Moesif’s analytics for users who have minimal experience and knowledge about analytics tools and related concepts.AI Explain is available for Live Event Log, Time Series, and Segmentation metric types. To use AI Explain, you must have a paid Moesif plan in Growth or Enterprise. For more information, see Moesif Pricing.Usage of Open AI and Large Language Model (LLM)Moesif AI Explain uses Azure Open AI to process your questions and generate responses. To power AI Explain, Moesif sends the following event data to Azure OpenAI:  Event properties such as event IDs  Request and response data for API calls such as body, status, and IP addressesYour Data and InformationApart from the event data mentioned, Moesif also sends conversational history inlcuding previous questions and responses to the OpenAI API. However, OpenAI doesn’t store or train on your prompts, responses, and Moesif data nor share them with others.",
      "url": " /api-analytics/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-event-stream": {
      "title": "Live Event Log",
      "content"	 : "This document explains how to use Live Event Log metrics in the Moesif’s API Analytics suite.OverviewLive Event Log shows a real-time continuous record of all the API events and actions that take place within your application or services. The Live Event Log allows you to filter on specific attributes within the API Calls and Actions event types Moesif receives. The Live Event Log gives you an easy-to-navigate way to explore user-centric insights into API usage and user behaviors on your platform.Use CasesSearching and filtering in traditional logs can pose significant difficulty to get past. Moesif supports extremely simple or complex queries with ease. Moesif allows you to build queries based on the data that exists in the logs. This replaces approximations and assumptions with precise calculation and statistical insights that give you immediate value and utility. For example, if you filter on an endpoint, Moesif automatically populates the filter list with the endpoints that exist in the current data.Moesif also supports performing analytics on HTTP body and header, meaning you can have a Moesif filter based on a specific body field and its contents. This level of granularity is one of the reasons Moesif stands apart from other API and product analytics platforms.The following sections discuss some example use cases and applications of Live Event Log.Real-time MonitoringLive Event Log gives you real-time visibility into different types of events going on in your website or application. With this real-time data, you can do the following:  Monitor inbound and outbound events.  Track user activity.  Identify network issues.  Understand traffic growth.Debug and Troubleshoot API IssuesMoesif’s Live Event Log helps you instantly diagnose API issues. Instead of manually digging through logs or waiting for batch analytics, you can watch live API calls, inspect headers, and analyze payloads as they flow through the system.For example, if you observe failed API requests, with Live Event Log, you can start investigating:  Filter API traffic by status codes like 4xx client errors and 5xx server errors to find error patterns.  Inspect request bodies and headers to identify missing parameters or auth issues.  Compare responses between successful and failing requests to pinpoint inconsistencies.Create Live Event LogTo create a new Live Event Log, select + Create New in the navigation menu and then select Live Event Log from the API Observability section.This creates a new Live Event Log workspace for you.FiltersYou can refine the events Live Event Log shows you using filters. To access the filters, select the Select field list in the Filters pane.For more information about the available filters in Live Event Log, see Reference: Analytics Filters.You can chain multiple filters together by selecting Where and OR.Filter By CohortsYou can further refine your event log by selecting a user or company cohort from the Performed By list:This allows you to observe events for specific customer cohorts—for example, new users that have been encountering errors or events for enterprise customers. For example, the following displays API calls for customers exceeding a specific input token amount:Inline CohortsUse inline cohorts to define a cohort criteria directly in your Live Event Log workspace. This allows you to instantly refine your analysis when you don’t already have an existing cohort to filter by.To define an inline cohort, select Performed By and then select + Inline User Cohort or + Inline Company Cohort. It opens up a new dialog where you can define a cohort criteria using customer and event filters.Analytics and Filtering on HTTP PayloadMoesif allows you to define filters on and analyze HTTP bodies, even for deeply nested structures. For example, here we observe events with large context size in an AI API product:You can also select a specific body field key or value and choose to define filters directly from there. For example, here we’re interested in the image resolution data in the request body for an API call in an image generation API. If we select one of the filtering options, Moesif includes or excludes API calls that have requested to generate 768x768 resolution images.For more information about interacting with event data fields this way, see Event Data Field Options.Named Variables for FiltersYou can define named variables that hold filter values and then use it across filters.To add filter variables, select Variables. Then select Add Variables to define a variable. After defining your variables, select Save.To use a variable, enter the variable name enclosed in double curly braces in a filter value. For example:You must manually enter the variable name this way to use it. You can quickly check defined variables by hovering over Variables—the tooltip shows the defined variables and their values.This feature allows you to avoid manually updating filter values in complex and dynamic filtering scenarios.View Events for New Users and Companies OnlyTo see events for only new users and companies in Live Event Log, enable the New Users Only and New Companies Only filters respectively. These two filters allow you to see events for users or companies who’ve made their first API call within the time period you specify.Event Data ViewsYou can change how Live Event Log displays event data. The following options are available:  Stream view  Table view  Traces viewStream ViewThe stream view shows each API Call or Action as an interactive element that you can expand for further details about the event. By default, each element displays the following information about an event:  The HTTP response status code  Elapsed duration of the HTTP request  The HTTP request method  The endpoint  Any identified user or company associated with the event  The time of the requestTo turn on this view, select Stream. Expanding an element shows more details about the event.If you’ve instrumented your API with OpenTelemetry and set up the Moesif-OpenTelemetry server integration, the detailed view also displays the associated trace and log data like trace ID and span ID.Add Custom Fields to DisplayTo display more data fields in the stream view, select Select Columns and specify the fields. For example, you can select Request.Geo IP.Country as your custom field. Now in the default stream view for each event, the country where the request originates from appears.Event Log ActionsWhen you select one or more events by selecting the checkboxes, the following additional actions become available in Act On Selected Events dropdown menu:  Viewing Waterfall chart  Downloading event details  Running API calls in Postman  Exporting cURLs  Comparing two events  Sharing events with teams  View Waterfall chart  Select the Show Waterfall to generate a waterfall chart for the selected events. While the waterfall chart remains in display, you can keep selecting or clearing the event checkboxes and the chart changes accordingly.  Download event details  Select Download Events to export details of the selected events as a JSON file.  Run API calls in Postman  Live Event Log allows you to generate and export a Postman collection containing the API calls for selected events. This can help tremendously in API testing and debugging. To do so, select Run in Postman and then select Download Postman Collection.    For more information, see Replaying API Calls in Postman.    Export cURL commands in a bash script  Select Export CURL to export the cURL commands for the selected events as a bash script. This allows you to query the event data from your terminal or use the commands in tools like Postman.  Compare two events  Live Event Log allows you to compare the request and response of two different API calls. This comes in handy in scenarios such as debugging issues within an API call. Then you can check the difference between a successful call and the one causing an error. To do so, select two different events and then select Diff 2 Events.    Moesif marks the additions and subtractions in green and red background colors. Moesif finds differences in the entire HTTP request and response cycle. This includes HTTP headers and any JSON body to aid in debugging.    Share events with team  To quickly share selected events with your team members, select Events Link. Then copy the link.Table ViewThe table view shows the event data in a tabular format, similar to a spreadsheet. By default, the table contains the following information for each event:  The event ID  The time of the request  Elapsed duration of the HTTP request  The HTTP response status code  The endpoint  The HTTP request method  The identified user ID or company ID  Creation date for the user or companyTo turn on this view, select Table.Specify the Columns to DisplayTo specify the fields you want to display in the table view, select Select Columns and specify the fields from the Add a data field list. Then select Save. You can also remove a field from view by selecting X beside the field name.Add Custom Columns to DisplayYou can also add a custom column containing calculated data from the table by selecting Add equation.You must specify the operator for the calculation and the operands. For the operands, you can choose one or more fields from the list or specify constants.Timestamp ValuesIn table view, Moesif parses the timestamp for each event into human-readable format in your timezone. To display the raw timestamp values in ISO 8601 format instead, select Original Raw Values.Traces ViewThe Traces View shows you traces and log data Moesif captures if you have integrated OpenTelemetry.For more information, see Trace Explorer.Event Data Field OptionsYou can interact with individual event data fields and field values in your Live Event Log workspace:In the dropdown, you can view more detailed information about the data element and perform further actions on that specific data. For example, you can filter and sort, plot the data as a metric in a different chart, and so on.Save and ShareMoesif gives you several options to share a Live Event Log workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.AI Explain : Use AI to Get Insights About Event MetricsAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about event analytics data.In a Live Event Log workspace, select Ask AI to open up the interface. By default, Moesif selects the first 30 events as target events for the AIto analyze and answer your questions about. You can also select a custom number of events and then select Ask AI. You can select a maximum of 30 events at a time.                    Video: Using AI Explain in Live Event Log.   To get started, you can choose from three sample prompts. Otherwise, type in your query and press Enter.",
      "url": " /api-analytics/event-stream/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-time-series-analysis": {
      "title": "Time Series Reports",
      "content"	 : "This document explains how to use Time Series metrics in the Moesif’s API Analytics suite.OverviewA time-series visualizes how data changes over time. In the context of API and product analytics, a time-series analysis allows you to view aggregated trends for the API traffic over a certain time period. It provides a way of visualizing a data set that measures some quantity over regular time intervals.In time-series graphs, time always takes the horizontal axis.Use Cases and BenefitsApplications and use cases of time-series charts are endless. For example, disciplines such as statistics, signal processing, econometrics, and mathematical modeling extensively use time-series analysis.Time-series reports provide many benefits in understanding API usage. Time-series data is easy to collect and track over time. Moesif’s Time Series metrics offer a great way to visually identify trends and easily compare historical data. Time-series analysis can also help companies to identify possible trends in the future as well by allowing them to visually predict where trends may be going.In the context of APIs and product analytics, time-series charts work as an accessible medium to communicate data visualization to less technical audiences. Unlike other types of reports that may take some technical knowledge to decipher, the visual nature of a time-series report makes it easily digestible. This allows companies and teams to collaborate more widely and effectively in important business decision making processes.You can create a time-series chart in Moesif for different time periods such as hourly, daily, weekly, monthly, or yearly. This allows you to compare usage over different time periods. For example, if the analysis shows an upward trend, it means your product is getting more users and traffic. This can help your developers to proactively start planning and optimizing the API for future traffic.This information can also help improve API design, optimize performance, and troubleshoot issues. Additionally, you can use time-series to track customer satisfaction or monitor SLAs (service-level agreements).Create Time Series ChartTo create a time-series chart, select + Create New in the navigation menu and then select Time Series from the API Observability section.This creates a new Time Series workspace for you.FiltersYou can refine a time-series chart using filters. To access the filters, select the Select field list in the Filters pane.For more information about the available filters, see Reference: Analytics Filters.You can chain multiple filters together by selecting Where and OR.Filter By CohortsYou can further refine your time series by selecting a user or company cohort from the Performed By list:This allows you to perform time series analysis on specific customer cohorts—for example, new users that have been encountering errors or events for enterprise customers. For example, selecting the cohort NonEnterprise customers will only consider non-enterprise customers in the time series analysis.Inline CohortsUse inline cohorts to define a cohort criteria directly in your Time Series workspace. This allows you to instantly refine your analysis when you don’t already have an existing cohort to filter by.To define an inline cohort, select Performed By and then select + Inline User Cohort or + Inline Company Cohort. It opens up a new dialog where you can define a cohort criteria using customer and event filters.Named Variables for FiltersYou can define named variables that hold filter values and then use it across filters.To add filter variables, select Variables. Then select Add Variables to define a variable. After defining your variables, select Save.To use a variable, enter the variable name enclosed in double curly braces in a filter value. For example:You must manually enter the variable name this way to use it. You can quickly check defined variables by hovering over Variables—the tooltip shows the defined variables and their values.This feature allows you to avoid manually updating filter values in complex and dynamic filtering scenarios.Include Data of New Users and Companies OnlyTo take only new users and companies into consideration for a time-series chart, enable the New Users Only and New Companies Only filters respectively. These two filters allow you to perform the time-series analysis only for users or companies who’ve made their first API call within the time you specify.You can choose between the following options regarding how Moesif considers the first seen time for new users and companies:      First seen time    How it works    Example use cases        In Entire Range    Moesif looks at the entire time period you&#39;ve selected for your Time Series analysis and identifies the absolute first time each user or company was ever seen within that full analysis period.                  Analyzing the long-term engagement of users who joined within a marketing campaign&#39;s timeframe.        Tracking the overall adoption of your product by new companies over a quarter.                  In Each Interval    Moesif considers the first seen time within each individual interval of your Time Series analysis. For example, if your graph has a daily interval, Moesif determines if a user or company was first seen on each specific day.                  Monitoring the daily or weekly signup rate of new users.        Identifying spikes in new company registrations on specific days.        Observing if a marketing campaign has had a large immediate effect on new user signups.            For example, let’s consider you’re using a time series analysis for a week, from Jan 1 to Jan 7, with a daily interval. Moesif identifies a customer first seen on Jan 5. Here’s how Moesif performs the analysis and plots the graph depending on the first seen time option.  In Each Interval  Moesif considers the customer new only on Jan 5. Moesif doesn’t consider them new before or after that date.  In Entire Range  Moesif considers the customer new throughout the entire range of the analysis period.Group DataMoesif Time Series charts support grouping data by categories. Use the Group By option to group data by a specific criteria. You can group by HTTP response status code, company domain, or user ID. For example, the following time-series chart groups by Response.StatusCode for HTTP POST requests. This can help identify trends in specific responses and solve potential problems if the trends become negative—for example, a high occurrence of error status codes.You can choose the number of data points the chart uses to plot the graph by selecting a number for Top Terms.Segment DataIf you want to use your own criteria to segment data by custom groups, use the Segment By option.For example, to segment by country, select + Segment and then select Request.GeoIP.Country from the Select Field list.After selecting + Segment, Moesif generates a unique name for the segment that you can change—for example, segmentcd635fbb. You can reference this name when you define a custom metric formula.Calculation Method of Time IntervalsMoesif aligns the intervals to the top and bottom of the interval. So if you select a daily interval, then each metric equals the time from 12:00 AM to 11:59 PM per day in your specified timezone.Since Moesif always aligns to the calendar interval, the very last one may not be fully complete. For example, if the current time is 5:55 PM and you select a daily interval, then the last interval only contains partial data from 12:00 AM to 5:55 PM.By default, Moesif uses the browser time as the time zone. To change your global time zone, configure the timezone in your Apps and Teams settings.Configure Metrics and ChartMoesif Time Series offers different ways to specify, configure, and visualize metrics.Select the Metrics to PlotBy default, Time Series plots only the Event Count metric. You can always plot more than one metric in the same chart by selecting + Add Metric.The following predefined metrics are available:  Event count  Event accumulation  Unique users  Unique companies  Unique sessions or API keys  Average latency  Maximum latency  P90 latency  Request body count  Response body count  Maximum available balance for subscriptions  Maximum pending activity for subscriptionsYou can also add custom metrics by selecting a new event field or specifying a custom formula that references other metrics.Create Custom MetricYou can create custom metrics in two ways:  Add another event field and specify how to compute the metric from the field.  Add a custom formula that computes a metric from other metrics.Add Another Event Field  Select + Add Metric and then select { } Select Field.    Select an event field from the Select a field list—for example, Duration (Milliseconds). Alternatively, write a script that computes the event field.      Select a computation method for the values of the event field. For example, if you’ve selected Duration (Milliseconds), you can select avg to display the average elapsed duration of API calls over time.    The computation methods available depend on the data type of the event field. For example, numeric types have the following computation methods available:          sum      avg      min      max      accumulate      percentile      distinct      sum of count avg of count, min of count, max of count (in case of arrays in request or response body, count is number of elements in the array).      sum of key count, etc. (in case of object in request or response body, key count is number of keys in the object).        Optionally, configure the rolling and transformation function for your custom metric.Add a Scripted FieldIf a field does not exist in your request or response, you can compute the field using a script. The script retroactively creates a custom field from other fields, using formulas, arithmetic, and conditional expressions. A scripted field has the following capabilities and limitations:  Only numbers, booleans, and datetime data types (treated as a number, milliseconds since epoch) are supported.  [field.path.field_name] references a field.  If field value does not exist, for numbers it defaults to 0, and for dates it defaults to the epoch. You can use [field.path.field_name|50] to set the default value.  Most mathematical functions are supported. Conditional expressions using if, else, then, and end operators are supported.  Only expressions are supported. No other variables or statements are supported.Scripted fields with body fields may take several minutes to query.To add a scripted field, follow these steps:  Select + Add Metric and then select { } Select Field.    Select &amp;lt;&amp;gt; Scripted Field.    Write the script and then select Set. The field list following the script text box contains all the existing fields so that you can easily reference them in your script.  Add a Custom FormulaMoesif allows you to create a custom arithmetic formula to use the values from other metrics or segments that you’ve defined. Moesif assigns a unique letter to each metric you plot. You can then reference those letters to build an arithmetic expression that computes a custom metric. You can also refer to segments in the custom formula as well by using the segment name.The following example defines the custom metric formula a/b where a corresponds to an Event Count metric and b corresponds to a Unique Users metric.To use segments as part of your formula, use the syntax SEGMENT_NAME.METRIC_LETTER.For example, if you have two segments API and All, and a metric a, you can define the formula (API.a/All.a)*100.To add a custom formula and plot its metric, follow these steps:  Select + Add Metric and then select Enter Formula.    Enter your formula. The following operators are supported for a formula:          Addition (+)      Subtraction (-)      Division (/)      Multiplication (*)      Exponentiation (^)      Square root (sqrt)      Natural logarithm (ln, log)      Base-10 or common logarithm (log10)      Base-2 or binary logarithm (log2)      Apply Rolling and Transformation FunctionsMoesif Time Series supports several rolling and transformation functions that you can apply to your plots.The following sections discuss the different types of functions available:Growth RateComputes the growth rate as a percentage across time.The most basic growth rate calculation follows the formula (Current Period - Previous Period) / Previous Period. Moesif also supports compounded monthly growth rates (CMGR). Use compound growth rates to get smoother and longer-term growth rates. Compound growth rates for 3 months or 6 months are common metrics for SaaS products.Rolling WindowAllows you to specify a rolling window size for the metrics plot. For example, a 7-day rolling window of unique users, showing you the number of unique users each week over a specific time period.Rolling SumCalculates the sum of the values for each overlapping window.Rolling MaxReturns the rolling maximum value of the metric for each overlapping window.Rolling MinReturns the rolling minimum value of the metric for each overlapping window.DiffCalculates the difference between two consecutive periods.Rolling Unweighted AverageReturns the rolling average for each overlapping window. For example, to see how your customers’ API usage is trending against their trend line, you can plot customers’ daily event count and their 7-day rolling average. Then use a formula to subtract the two to see how their usage is trending.Rolling Weighted AverageContains the following weighted average rolling functions:  Linear  Returns the weighted average for each overlapping window where older data points contribute a linearly less amount to the total average. For example, you can use this function to reduce lag that typically occurs from a rolling average. This allows you to observe rapid changes that occur to a metric in real time as older data points contribute less to the mean.  Exponential  Returns the single exponential rolling average for each overlapping window where older data points become exponentially less important.  Double exponential  Returns the double exponential rolling average for each overlapping window where older data points become exponentially less important. For example, this function allows you to better track an underlying linear trend in a metric that you may not appear in a single exponential rolling average. This is partially true for usage metrics like Event Count that may go up linearly over time.Maximum ThroughputCalculates maximum value per smaller time unit within each interval.Minimum ThroughputCalculates minimum value per smaller time unit within each interval.Average ThroughputCalculates average value of smaller time unit within each interval.Lag PlotReturns the metric value from a specific number of time intervals ago. You can use a lag plot to check for randomness in data in a time series. You can also use lag plots in formulas to create comparisons between current and past data—for example, percentage of change compared to yesterday.Rolling Standard DeviationReturns the standard deviation of a rolling average for each overlapping window. The averaging function can be either the unweighted average or the linear related average.Shift Rolling WindowAfter you select a rolling window function, you have the option to shift your window by an amount:  To shift your window positively by one mark, select Shift + 1.  To shift your window positively by two marks, select Shift + 2.  To specify a custom shift, specify a positive or negative number in the Custom Shift field and select Apply. A positive number shifts the window forward and a negative number shifts the window backward.Change Chart StyleYou can change how Moesif plots the time-series charts and toggle from one style to another. This allows you to view the metrics in multiple ways.The following styles are available in Time Series:  Bar chart  Line chart  TableIf you want to combine bar and line charts, use combo charts.Line ChartA line chart plots your metrics by connecting the data points with lines. Each data point represents a value of the metric at a specific time period. Line charts help you visualize and understand how metrics change over time.Bar ChartA bar chart represents data with rectangular bars. The height of each bar corresponds to a quantity of the data and each bar belongs to a category. In Moesif Time Series, the category is time and each bar represents a fixed time interval. For example, if you plot the Event Count metric in a line chart for the past 12 weeks with an interval of 7 days, each bar represents data for a 7-day interval. The height of each bar changes in proportion to the number of events during a 7-day period.TableThe table view shows the metrics data in a tabular format, similar to a spreadsheet.Save and shareMoesif gives you several options to share a Time Series workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.Metric Configuration and Shortcuts MenuFor each metric in the Metrics pane, select … Configuration and Shortcuts to further customize your chart.Custom NameSelect the Custom Name checkbox to set a custom name for the metric.Sampling WeightsSelect the Weighted checkbox to enable sampling weights for the metric.This option is enabled by default and Moesif extrapolates the metric using any sampling rules you have defined in Dyanamic Sampling. If you don’t have any dynamic sampling enabled, weighted and unweighted have no difference.Combo ChartsA combo chart combines line and bar charts. Combo charts allow you to represent multiple time series metric in the same chart for better visualization and comparison.To create a combo chart, open the … Configuration and Shortcuts menu and then select Combo Chart.Customize Vertical AxisWhen you have more than one metric in a chart, you may want to use independent Y-axes for each. Metrics on separate Y-axes can vertically scale independently of one another within the same chart. This proves useful in scenarios such as comparing values at very different scales.To use a different Y-axis for your metric, open the … Configuration and Shortcuts menu and then select Assign to Y-Axis. The following Y-axis types are available:  Y-Axis A  The default Y-axis.    It’s always on the left side of the chart. If you select a different Y-axis for a metric, the Y-axis appears on the right side. When you select the Log Scale option, it only affects  this default Y-axis.    Y-Axis B  Expresses a metric with a decimal ratio as a whole number percentage—for example, 0.5 as 50%. This axis multiplies the values by 100 and adds a percentage sign to the chart units.  Y-Axis C  Adds a new Y-axis on the right side of the chart based on the metric values.  Y-Axis D  Adds a new Y-axis on the right side of the chart based on the metric values.Duplicate a MetricSelect Duplicate to duplicate the corresponding metric in the same chart.Add ComparisonThis option offsets the corresponding metric by a time interval and adds the metric in the same chart.After selecting Add Comparison, select one of the default time intervals. Then you can further customize the metric name, time interval, and the comparison formula.Under the hood, comparison metrics use lag plot. Moesif supports only one rolling or transformation function for each workspace. Therefore, to create a new comparison, remove any existing functions from the workspace.FoldingYou can fold your time series chart to understand cyclic trends like hour per day or day of week.Folding is enabled for these specific chart intervals only:  1 Minute  1 Hour  1 Day  1 WeekSave and ShareMoesif gives you several options to share a Time Series workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.AI Explain : Use AI to Get Insights About Time Series MetricsAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about event analytics data.In a Time Series workspace, select Ask AI to open up the interface.To get started, you can choose from the sample prompts. Otherwise, type in your query and press Enter.Download Chart DataYou can download your Time Series chart data in CSV format for further processing in tools like Microsoft Excel:  Select Export.  Select Download Chart - Current View or Download Chart - All Terms.",
      "url": " /api-analytics/time-series-analysis/",
      "author": "Xing",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-segmentation": {
      "title": "Segmentation Reports",
      "content"	 : "This document explains how to use Segmentation metrics in the Moesif’s API Analytics suite.OverviewSegmentation allows you to analyze your API data and divide it into segments. Each segment contains similar data based on specific criteria. This is similar to the SQL GROUP BY statement.Use Cases and BenefitsMoesif’s Segmentation offers you a powerful way to find meaningful and useful categories in your API data. Being able to group and categorize your product usage based on different criteria helps identify different kinds of customers and usage patterns. This allows your teams to tailor communication, outreach, and customer support strategies to different audiences. For example, say you roll out a new version of your API. You can keep an eye on the usage of different versions to better strategize deprecating the older version.Create Segmentation ChartTo create a Segmentation chart, select + Create New in the navigation menu and then select Segmentation from the API Observability section.This creates a new Segmentation workspace for you.FiltersYou can refine a Segmentation chart using filters. To access the filters, select the Select field list in the Filters pane.For more information about the available filters, see Reference: Analytics Filters.You can chain multiple filters together by selecting Where and OR.Filter By CohortsYou can further refine your segmentation analysis by selecting a user or company cohort from the Performed By list:This allows you to perform segmentation analysis on specific customer cohorts—for example, new users that have been encountering errors or events for enterprise customers. For example, selecting the cohort NonEnterprise customers will only consider non-enterprise customers in the Segmentation analysis.Inline CohortsUse inline cohorts to define a cohort criteria directly in your Segmentation workspace. This allows you to instantly refine your analysis when you don’t already have an existing cohort to filter by.To define an inline cohort, select Performed By and then select + Inline User Cohort or + Inline Company Cohort. It opens up a new dialog where you can define a cohort criteria using customer and event filters.Named Variables for FiltersYou can define named variables that hold filter values and then use it across filters.To add filter variables, select Variables. Then select Add Variables to define a variable. After defining your variables, select Save.To use a variable, enter the variable name enclosed in double curly braces in a filter value. For example:You must manually enter the variable name this way to use it. You can quickly check defined variables by hovering over Variables—the tooltip shows the defined variables and their values.This feature allows you to avoid manually updating filter values in complex and dynamic filtering scenarios.Include Data of New Users and Companies OnlyTo take only new users and companies into consideration, enable the New Users Only and New Companies Only filters respectively. These two filters allow you to perform segmentation analysis only for users or companies who’ve made their first API call within the time period you specify.Group DataMoesif Segmentation charts support grouping data by categories. Use the Group By option to group data by a specific criteria. You can group by HTTP response status code, company domain, or user ID. For example, the following Segmentation chart groups by request URI route and company domain. It defines a custom metric to get a breakdown of top users for different endpoints.Segment DataIf you want to use your own criteria to segment data by custom groups, use the Segmentation option.For example, to segment by country, select + Segment and then select Request.GeoIP.Country from the Select Field list.After selecting + Segment, Moesif generates a unique name for the segment that you can change—for example, segmentcd635fbb. You can reference this name when you define a custom metric formula.Configure Metrics and ChartMoesif Segmentation offers different ways to specify, configure, and visualize metrics.Select the Metrics to PlotBy default, Segmentation plots only the Event Count metric. You can always plot more than one metric in the same chart by selecting + Add Metric.The following predefined metrics are available:  Event count  Event accumulation  Unique users  Unique companies  Unique sessions or API keys  Average latency  Maximum latency  P90 latency  Request body count  Response body count  Maximum available balance for subscriptions  Maximum pending activity for subscriptionsYou can also add custom metrics by selecting a new event field or specifying a custom formula that references other metrics.Create Custom MetricYou can create custom metrics in two ways:  Add another event field and specify how to compute the metric from the field.  Add a custom formula that computes a metric from other metrics.Add Another Event Field  Select + Add Metric and then select { } Select Field.    Select an event field from the Select a field list—for example, Duration (Milliseconds). Alternatively, write a script that computes the event field.      Select a computation method for the values of the event field. For example, if you’ve selected Duration (Milliseconds), you can select avg to display the average elapsed duration of API requests over time.    The computation methods available depend on the data type of the event field. For example, numeric types have the following computation methods available:          sum      avg      min      max      accumulate      percentile      distinct      sum of count avg of count, min of count, max of count (in case of arrays in request or response body, count is number of elements in the array).      sum of key count, etc. (in case of object in request or response body, key count is number of keys in the object).      Add a Scripted FieldIf a field does not exist in your request or response, you can compute the field using a script. The script retroactively creates a custom field from other fields, using formulas, arithmetic, and conditional expressions. A scripted field has the following capabilities and limitations:  Only numbers, booleans, and datetime data types (treated as a number, milliseconds since epoch) are supported.  [field.path.field_name] references a field.  If field value does not exist, for numbers it defaults to 0, and for dates it defaults to the epoch. You can use [field.path.field_name|50] to set the default value.  Most mathematical functions are supported. Conditional expressions using if, else, then, and end operators are supported.  Only expressions are supported. No other variables or statements are supported.Scripted fields with body fields may take several minutes to query.To add a scripted field, follow these steps:  Select + Add Metric and then select { } Select Field.    Select &amp;lt;&amp;gt; Scripted Field.    Write the script and then select Set. The field list following the script text box contains all the existing fields so that you can easily reference them in your script.  Add a Custom FormulaMoesif allows you to create a custom arithmetic formula to use the values from other metrics or segments that you’ve defined. Moesif assigns a unique letter to each metric you plot. You can then reference those letters to build an arithmetic expression that computes a custom metric. You can also refer to segments in the custom formula as well by using the segment name.The following example defines the custom metric formula a/b where a corresponds to an Event Count metric and b corresponds to a Unique Users metric.To use segments as part of your formula, use the syntax SEGMENT_NAME.METRIC_LETTER.For example, if you have two segments API and All, and a metric a, you can define the formula (API.a/All.a)*100.To add a custom formula and plot its metric, follow these steps:  Select + Add Metric and then select Enter Formula.    Enter your formula. The following operators are supported for a formula:          Addition (+)      Subtraction (-)      Division (/)      Multiplication (*)      Exponentiation (^)      Square root (sqrt)      Natural logarithm (ln, log)      Base-10 or common logarithm (log10)      Base-2 or binary logarithm (log2)      Change Chart StyleYou can change how Moesif plots segmentation charts and toggle from one style to another. This allows you to view the metrics in multiple ways.The following styles are available:  Bar chart  Line chart  Pie chart  TableBar ChartA bar chart represents data with rectangular bars. The height of each bar corresponds to a quantity of the metric data and each bar belongs to a category. The categories come from the grouping you specify and each bar represents a single category. For example, if you plot the Event Count metric in a bar chart for the past 12 weeks and group the data by URI routes , each bar represents data for a URI route. The height of each bar changes in proportion to the number of events associated with a URI route.Line ChartA line chart plots your metrics by connecting the data points with lines. Each data point represents a value of the metric at a specific time period. Line charts help you visualize and understand how metrics change over time.Pie ChartPie chart uses a circular graph to represent how a total amount of your data is divided into categories. Each radial portion of the chart corresponds to the amount that belongs to a category. Pie charts help you visualize how each category or group contributes to the entirety of your data. For example, a pie chart can help you visualize how your customers are using your products across different countries and regions.TableThe table view shows the metrics data in a tabular format, similar to a spreadsheet.Metric Configuration and Shortcuts MenuFor each metric in the Metrics pane, select … Configuration and Shortcuts to further customize your chart.Custom NameSelect the Custom Name checkbox to set a custom name for the metric.Sampling WeightsSelect the Weighted checkbox to enable sampling weights for the metric.This option is enabled by default and Moesif extrapolates the metric using any sampling rules you have defined in Dyanamic Sampling. If you don’t have any dynamic sampling enabled, weighted and unweighted have no difference.Combo ChartsA combo chart combines line and bar charts. Combo charts allow you to represent multiple metrics in the same chart for better visualization and comparison.To create a combo chart, open the … Configuration and Shortcuts menu and then select Combo Chart.Customize Vertical AxisWhen you have more than one metric in a chart, you may want to use independent Y-axes for each. Metrics on separate Y-axes can vertically scale independently of one another within the same chart. This proves useful in scenarios such as comparing values at very different scales.To use a different Y-axis for your metric, open the … Configuration and Shortcuts menu and then select Assign to Y-Axis. The following Y-axis types are available:  Y-Axis A  The default Y-axis.    It’s always on the left side of the chart. If you select a different Y-axis for a metric, the Y-axis appears on the right side. When you select the Log Scale option, it only affects  this default Y-axis.    Y-Axis B  Expresses a metric with a decimal ratio as a whole number percentage—for example, 0.5 as 50%. This axis multiplies the values by 100 and adds a percentage sign to the chart units.  Y-Axis C  Adds a new Y-axis on the right side of the chart based on the metric values.  Y-Axis D  Adds a new Y-axis on the right side of the chart based on the metric values.Duplicate a MetricSelect Duplicate to duplicate the corresponding metric in the same chart.Save and ShareMoesif gives you several options to share a Segmentation workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.AI Explain : Use AI to Get Insights About Segmentation MetricsAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about event analytics data.In a Segmentation workspace, select Ask AI to open up the interface.To get started, you can choose from the sample prompts. Otherwise, type in your query and press Enter.Download Chart DataYou can download your Segmentation chart data in CSV format for further processing in tools like Microsoft Excel:  Select Export.  Select Download Chart - Current View or Download Chart - All Terms.",
      "url": " /api-analytics/segmentation/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-heatmaps": {
      "title": "Heatmap Reports",
      "content"	 : "This document explains how to use Geo Heatmap in the Moesif’s API Analytics suite.OverviewA heatmap visualizes frequency of data at geographic locations using a range of different colors. Heatmaps are a great way to understand your product, its users, and how both correlate when geographic location is an important part of your analytics requirements.Moesif’s Geo Heatmap supports supports GeoJSON and the full range of filters available in other metric types such as Live Event Log, Time Series, and Segmentation.Use Cases and BenefitsIf your product has a large customer base spread across different regions, Moesif’s Geo Heatmap can help you quickly pinpoint regional issues.For example, the following heatmap filters by the number of declined transactions globally.The heatmap shows a large portion of 401 Unauthorized response status codes coming from the Eastern US. The aggregate stats get updated as you apply more filters. In this case, the majority of 401 Unauthorized status codes come from the /availabilities endpoint.Heatmaps use color coding to illustrate the intensity profile of data. The use of different colors to communicate metrics makes heatmaps easier to consume. Use of colors also helps distinguish between different states rather than raw numbers. The simple but powerfully multifaceted nature of heatmaps makes them a potent analysis tool in various situations..Create a Geo HeatmapTo create a geo heatmapt, select + Create New in the navigation menu and then select Geo Heatmap from the API Observability section.FiltersYou can refine a heatmap using filters. To access the filters, select the Select field list in the Filters pane.For more information about the available filters, see Reference: Analytics Filters.You can chain multiple filters together by selecting Where and OR.Filter By CohortsYou can further refine your heatmaps by selecting a user or company cohort from the Performed By list:This allows you to create heatmaps based on specific customer cohorts—for example, new users that have been encountering errors or events for enterprise customers. For example, the following filters out enterprise customers and displays API calls for non-enterprise customers only:Inline CohortsUse inline cohorts to define a cohort criteria directly in your heatmaps. This allows you to instantly refine your analysis when you don’t already have an existing cohort to filter by.To define an inline cohort, select Performed By and then select + Inline User Cohort or + Inline Company Cohort. It opens up a new dialog where you can define a cohort criteria using customer and event filters.Named Variables for FiltersYou can define named variables that hold filter values and then use it across filters.To add filter variables, select Variables. Then select Add Variables to define a variable. After defining your variables, select Save.To use a variable, enter the variable name enclosed in double curly braces in a filter value. For example:You must manually enter the variable name this way to use it. You can quickly check defined variables by hovering over Variables—the tooltip shows the defined variables and their values.This feature allows you to avoid manually updating filter values in complex and dynamic filtering scenarios.Include Data of New Users and Companies OnlyTo take only new users and companies into consideration, enable the New Users Only and New Companies Only filters respectively. These two filters allow you to plot heatmaps only for users or companies who’ve made their first API call within the time period you specify.Use GeoJSONGeoJSON is available to Moesif Enterprise plan users.Instead of using IP addresses to plot heatmaps, you can use GeoJSON-formatted shapes from API body fields or request query parameters. Select Select a GeoJSON Field to get started.How it WorksYou can include GeoJSON-formatted shapes in your request or response payloads or query parameters. Moesif automatically detects the GeoJSON data in the API traffic. Then you can specify the data field from Select Geo Field:This example selects the Location field from the request payload’s geo_ip field. Moesif only plots the shape defined in the Location field rather than IP addresses in the resulting metric heatmap.Configure Metrics and ChartMoesif Geo Heatmap offers different ways to specify, configure, and visualize heatmaps.Location PinsSelect Show Pins to enable inverted-drop-shaped location markers on the map. Selecting each pin allows you to see the specific metric value in that location.Heatmap TypesMoesif supports the following heatmap types:  Density heatmap  Metric heatmapDensity HeatmapDensity heatmaps helps visualize geographic concentration of data points for your metric. A density heatmap creates smooth, continuous color gradients that highlight areas with a cluster of activity, also known as hotspots. Areas with intense, warmer colors, like red or orange, indicate higher concentration of data points. The color fades out smoothly in areas with fewer data points, for example blue or green.Example Use Cases of Density Heatmaps  Identify areas with highest concentration of API calls to evaluate API usage.  Visualize geographic source of failed login attempts or malicious requests.  Map out where API errors or high API latency are most frequently occurring.  Track the geographic spread and concentration of users who are adopting a new API featureMetric HeatmapA metric heatmap plots each individual data point of the metric as a separate square on the map. The color of each square represents the value of a specific metric associated with that data point. Darker colors like red indicate higher values and lighter colors like blue indicate lower values. Combining with location pins, metric heatmaps allow you to visualize properties of individual events or find outliers that might get lost in an aggregated view like density heatmaps.Example Use Cases of Metric Heatmaps  See the latency or processing time for every single API request on a map.  Identify specific user transactions or events with unusually high or low values.  Observe the journey of a specific company, with a metric that computes the time the company has spent on your product’s website pages.Select the Metrics to PlotBy default, Geo Heatmap plots only the Event Count metric. A heatmap can contain only one metric at a time.The following predefined metrics are available:  Event count  Event accumulation  Unique users  Unique companies  Unique sessions or API keys  Average latency  Maximum latency  P90 latency  Request body count  Response body count  Maximum available balance for subscriptions  Maximum pending activity for subscriptionsYou can also add custom metrics by selecting a new event field.Create Custom MetricTo create a custom metric for the heatmap, follow these steps:  Select + Event Count and then select { } Select Field.    Select an event field from the Select a field list—for example, Duration (Milliseconds). Alternatively, write a script that computes the event field.      Select a computation method for the values of the event field. For example, if you’ve selected Duration (Milliseconds), you can select avg to display the average elapsed duration of API requests over time.    The computation methods available depend on the data type of the event field. For example, numeric types have the following computation methods available:          sum      avg      min      max      accumulate      percentile      distinct      Add a Scripted FieldIf a field does not exist in your request or response, you can compute the field using a script. The script retroactively creates a custom field from other fields, using formulas, arithmetic, and conditional expressions. A scripted field has the following capabilities and limitations:  Only numbers, booleans, and datetime data types (treated as a number, milliseconds since epoch) are supported.  [field.path.field_name] references a field.  If field value does not exist, for numbers it defaults to 0, and for dates it defaults to the epoch. You can use [field.path.field_name|50] to set the default value.  Most mathematical functions are supported. Conditional expressions using if, else, then, and end operators are supported.  Only expressions are supported. No other variables or statements are supported.Scripted fields with body fields may take several minutes to query.To add a scripted field, follow these steps:  Select + Event Count and then select { } Select Field.    Select &amp;lt;&amp;gt; Scripted Field.    Write the script and then select Set. The field list following the script text box contains all the existing fields so that you can easily reference them in your script.  Metric Configuration and Shortcuts MenuFor each metric in the Metrics pane, select … Configuration and Shortcuts to further customize your chart.Custom NameSelect the Custom Name checkbox to set a custom name for the metric.Save and ShareMoesif gives you several options to share a Geo Heatmaps workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.",
      "url": " /api-analytics/heatmaps/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-run-in-postman": {
      "title": "Replay API Calls in Postman",
      "content"	 : "Live Event Log allows you to generate and export a Postman Collection containing the API calls for selected events. This allows you to perform different tasks and routines on your API to make it more robust. For example:  Debugging any problematic API calls or even sequences of API calls.  Creating robust test suites in Postman from your actual API data in Moesif.Replaying API calls in Postman requires two simple steps:  Export the data from Moesif as a Postman Collection.  Import the collection in Postman.You must have a Postman account to use Postman Collections.For more information about importing and exporting data in Postman, see Data import and export in Postman.Export API Calls in MoesifFollow these steps to export API calls into a Postman Collection:  Open your Live Event Log workspace. You can access all the dashboards and the workspaces under those dashboards in Saved Dashboards of the navigation menu.  Select the API calls you want to export.  Select Run In Postman.  Select Download Postman Collection to confirm.The export includes everything you need to recreate an API call, including the body, headers, and other parameters in a JSON file.Import Collection Into PostmanAfter exporting API calls into a Postman Collection, follow these steps to import the collection into Postman:  Open Postman and select Import in the sidebar.    Select the JSON file you have exported from Moesif.  The Import Complete dialog appears. Postman automatically opens the new collection you’ve imported. Otherwise, select Go to Collection in the dialog to open the collection.The new collection now appears under Collections in your current workspace sidebar.For more information, see Import Data into Postman.Replay and Debug API CallsAfter importing your collection in Postman, you can now start replaying the API calls. Each request contains all the details including the query parameters, headers, body, and so on. Select a request and then select Send to send an exact copy of the API request to your endpoint.Alternatively, you can run your Postman collections instead of manually selecting requests and replaying them.",
      "url": " /api-analytics/run-in-postman/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-bulk-export": {
      "title": "Bulk Export",
      "content"	 : "Bulk Export is an enterprise feature that provides direct access to your data stored in Moesif. It allows you to efficiently retrieve hundreds of millions of event, user, and company data from Moesif and quickly load them into data warehouses like Snowflake, Redshift, and BigQuery.You can use Bulk Export both from Moesif UI in the browser and Moesif Management API. Using the Management API, you can set up recurring bulk exports for different use cases—for example, a data pipeline that feeds your data in Moesif into a data warehouse like BigQuery.Bulk Export is designed to move large amounts of your raw events for archival and data warehousing purposes. If you want to import a chart’s dataset into tools like Microsoft Excel and Google Sheets, download the chart instead for your Time Series and Segmentation metric types.Supported EntitiesMoesif supports bulk export on three types of entities:  Events  Exporting API calls and custom actions in Moesif with their associated fields like HTTP headers.  Users  Exporting users stored in Moesif and their associated metadata.  Companies  Exporting companies stored in Moesif and their associated metadata.Supported Export File TypesMoesif supports the following file types for bulk export:  CSV  CSV files have some of the widest support for many of your favorite tools. This makes it ideal for exporting user and company data to your CRM and more.  JSON  JSON has become a standard for parsing data quickly for scripting purposes. Many fields in Moesif are deeply nested, making JSON an ideal choice.  Parquet  Parquet is an open source column-oriented data format that can make analysis on a subset of columns faster when compared to loading the entire file in memory. Your schema is directly embedded in the file. This can help SQL warehouse-like tools that require strict schema enforcement.Export SchemaData representing API calls can naturally become quite sparse—for example, you may have certain HTTP headers set by only a few customers. Moesif relies heavily on partitions for performance. Therefore, to ensure exports remain fast while reducing file size, Moesif only includes the columns with at least one defined value for the dataset.If you use any automated ETL tooling, make sure to set up the tool to handle schema evolution. Some tools like BigQuery have very strict requirements around schema detection while incorrectly classifying data. For these tools, we recommend that you leverage a data format like Parquet to overcome the challenges.Export EventsTo export Live Event Log events, follow these steps:  Go to your Live Event Log workspace.  Select Export and then select Bulk Export.  Specify the email address where you want Moesif to send the export file.  Select the export file format.  Select the fields you want to include in the export.  Select Start Export.The time it takes to export your data depends on the number of events you export and the number of fields you select.If you want to trigger export jobs using Moesif Management API, contact your account manager or reach out to support for instructions.Event FiltersBulk exports adhere to any filters that you have applied. Make sure you apply the filters you require before exporting.Fields SelectionIf you don’t want to include all event fields in the bulk export, you can specify the fields you want in table view before selecting Bulk Export. Otherwise, select All Fields in the Bulk Events Export dialog.",
      "url": " /api-analytics/bulk-export/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-sharing-workspaces": {
      "title": "Sharing Workspaces",
      "content"	 : "This document explains how to share a metric workspace.This document also assumes you are familiar with Moesif API Analytics suite. For an introduction, see Introduction to Event Analytics and Logging.Sharable Metric TypesYou can share any workspace that contains one of the five metric types:  Live Event Log  Time Series  Segmentation  Geo Heatmap  Trace ExplorerAccess Restriction and Policy ConstraintsBased on audience visibility and who you want to share a workspace with, Moesif Workspaces fall into three types:  Private  Team  PublicFor more information, see Types of Workspaces.When you share a workspace publicly, you can enforce policy constraints that control what data you expose. You can add constraints like event IDs, user IDs, session tokens, or other constraints. Anyone with the link can only access the data that satisfies these constraints. You can add these constraints using Filters.These constraints appear under Sandbox Policy in the Settings tab when creating a public workspace.In the preceding example, the event data the shared workspace exposes must meet the following criteria according to the constraints:  Events must be HTTP POST and GET requests.  Events must only be associated with the user email alex@example.com.  Events must be from the past year.For security reasons, you cannot change the policy once set. We recommended that you test the link first as policy constraints can limit the view differently from what you are seeing.You can also view the policy constraints for a saved public workspace by selecting Show Detailed Info in the workspace tile and then selecting Public Link.Share a WorkspaceBefore you can share a workspace, you must first save the workspace to a dashboard. Then follow these steps to share your workspace:  Select Share.      Choose the sharing type:    a. If you want to keep the workspace private and only accessible to you, select Private.    b. If you want to share with your team members, select Team. Moesif generates a link that your team members can use to access the workspace.    c. If you want to share the workspace publicly with anyone, select Public and then select Save and Generate Public Link. Then you can choose how you want to share from the Secure Link, iFrame, and Passcode tabs.  Access Shareable LinksTo access the shareable links for a workspace any time, follow these steps:  Go to the dashboard where you saved the workspace to.  Select the title of the workspace.  Select ShareAlternatively, for public workspaces, you can select Show Detailed Info in the workspace tile and then select Public Link. A dialog appears with a sharable public link, a generated &amp;lt;iframe&amp;gt; element, and the policy constraints for the workspace.This example shows how to fetch shareable links for the POST Events public workspace from the Product dashboard.Delete a workspace  Go to the dashboard containing the workspace you want to delete.  Select Delete.  Select Delete again to confirm your choice.Embedded MetricsIf you want to embed your metrics into custom solutions such as customer-facing applications, custom workflows, and so on, use Embedded Templates. Embedded Templates automatically update to the latest data and dynamically associate with different properties, allowing you to securely share metrics outside Moesif and support context-critical use cases.",
      "url": " /api-analytics/sharing-workspaces/",
      "author": "Derric",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-create-event-tags": {
      "title": "Event Tags",
      "content"	 : "Sometimes you may want to group APIs together. For example, when a few different endpoints compose an API product. In Moesif, you can group events together by using tags. Tags allow you to categorize your API calls by using friendly names for events. You can create a new tag from a Live Event Log screen or by uploading your OpenAPI specification.The Tag ManagerYou can manage your existing tags through the Tag Manager. To access Tag Manager, select the account icon to bring up the settings menu and then select Tag Manager.Create an Event TagYou can create event tags in two ways:  From a Live Event Log workspace.  From an OpenAPI or a Swagger document that describes your API.Create Event Tags from Live Event Log ScreenTo create an event tag, you must first apply at least one event filter in a Live Event Log workspace. Then follow these steps from your Live Event Log workspace:  Select Create Tag.  In the Tag Name field, enter the tag name.  Select the tag name you’ve entered in the dropdown that appears.  Select Create Tag.Create Event Tags from an API DocumentMoesif can generate event tags from your API specification file that conforms to the OpenAPI or Swagger API specification format. The specification file must be in JSON format.To upload your API specification file, go to Tag Manager and select Select JSON File.Update an Event TagTo edit or update an event tag, you can either use the Tag Manager or a Live Event Log workspace.Update from the Tag Manager  Go to Tag Manager.  Select ⋯ Actions and then select Edit.  After making your changes, select Save.Update from Live Event Log Screen  Go to your Live Event Log workspace.  Make the changes you want to your event filters.  Select Create Tag.  Select the Tag Name field and then select one of the existing tags from the dropdown. You can select the Select Saved Tags toggle to see the existing tags.  Select Update Tag.Keep in mind that this method requires that you make changes to a workspace. These changes persist if you select Save afterwards. Therefore, we recommend using the Tag Manager to update your event tags so that you don’t accidentally change your workspace filters.Delete an Event TagTo delete an event tag, you can either use the Tag Manager or a Live Event Log workspace. Remember that you cannot recover an event tag once you delete it.Delete from the Tag Manager  Go to Tag Manager.  Select ⋯ Actions and then select Delete.  Select Yes to confirm.Delete from Live Event Log Screen  Go to your Live Event Log workspace.  Make the changes you want to your event filters.  Select Create Tag.  Select the Tag Name field and then select one of the existing tags from the dropdown.  Select the Select Saved Tags toggle.  Select X for the event tag you want to delete.Use an Event TagTo use an event tag, select Tag from the filters list in the Filters pane.If you have too many endpoints, you can specify tags instead. Since you can remember and identify tags more easily, this allows to easily filter events that match the tags. The following example filters out events that match the High Consumption Alert tag.Similarly, you can group by tag names just like any other attribute. The following example shows traffic volume for two APIs represented by the two tags Categories API and Purchase API.Tags can have many use cases. For example, you can organize endpoints into API products with tags when creating billing meters.",
      "url": " /api-analytics/create-event-tags/",
      "author": "Matthew",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-date-math": {
      "title": "Date Math",
      "content"	 : "Accurate time and date calculation is critical for any reporting tool. Because most Moesif customers utilize Moesif for business metrics, the Moesif platform leverages calendar-aligned time and date system. This means all time and dates conform to the calendar system:  Last one minute will start at top of the minute  Last one hour will start at top of the hour  Last 1 day will start at 12 AM of that day  Last 1 week will start at 12 AM of the first day of the week  Last 1 month will start at 12 AM of the first day of the monthDate RangesWhen you specify a date range with or without time, you also make use of the following comparison types:  After  After a specific date.  Before  Before a specific date.The following sections explain how Moesif calculates date ranges in combination with these comparison types.Start DatesFor a start date or After date comparison, Moesif rounds to the beginning of the period. For example, if you specify Last 1 day, Moesif rounds to 12 AM at the beginning of that day.End DatesFor an end date or Before date comparison, Moesif rounds to the end of that period. This effectively means the last millisecond before the next period. For example, if you say Before 1 day ago, Moesif translates this to 23:59:999 of the day before.Moesif always includes the period that you filter. For example, consider the filter From 1 week ago to 1 week ago. This means Moesif shows data from start of the previous week to end of the previous week, not including the current week still in progress. In the same way, the filter From 1 day ago to 1 day ago represents start of yesterday to end of yesterday, whereas From 1 day ago to now means start of yesterday at midnight to now.Partial PeriodsMoesif always displays a full period of time. This means if you filter on Last week, Moesif starts the data set at 12 AM of the first day of the first full week. For example, let’s say today is Tuesday and your week starts on Monday. Then Moesif starts the period 8 days ago at 12 AM.Time ZoneBy default, Moesif uses the locale information from your browser settings for the time zone and start of week. To ensure all team members see the same data regardless of location, we recommend that you define a global time zone and start of the week for your application. For more information, see Time Zone Settings in Apps and Teams.Changing time zone or start of the week does not update previously saved workspaces and tags. However, you can copy or resave any existing workspaces to ensure they use your latest settings.API Query ParametersMany of the APIs have a from and a to query parameter for filtering the dataset. These parameters can either take in an absolute date or a relative date expression. The absolute date expression conforms to ISO 8601 international standards for numerical date format. For relative dates, Moesif parses them using the format {direction}{amount}{units}.The following units are supported:  s for seconds  m for minutes  d for days  w for weeks  M for months  y for years  now for current timeFor example, to specify one day ago, use -1d. To specify one day from now in the future, use +1d or 1d.now is a special alias for the current time.While the API defaults to UTC time zone, we recommend that you specify the time_zone query parameter to ensure histograms and other metrics use the correct time zone.",
      "url": " /api-analytics/date-math/",
      "author": "Matthew",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-filters-reference": {
      "title": "Reference: Analytics Filters",
      "content"	 : "This document provides reference documentation for Moesif’s API analytics filters. These filters are available for the following metric types in Moesif API Analytics suite:  Live Event Log  Time Series  Segmentation  Geo Heatmap  Trace ExplorerFilter TypesThe available filters broadly falls into the following six categories:  Request filters  Response filters  Company filters  User filters  Subscription filters  Metadata filters  OpenTelemetry filters  Common filtersYou may have more filters available to you outside this document’s scope. For example, for GraphQL APIs, Moesif parses GraphQL queries and automatically generates a secondary set of filters called GraphQL Query Filters in the UI. For more information, see API Protocol Support.Search FunctionTo enter a custom query expression, select the search as the filter function. This function allows you to search on single terms within your text fields such as a title or description field.The search function supports the following operators: -+ to perform a logical AND operation among the search terms.  | to perform a logical OR operation among the search terms.  - performs a logical NOT operation and negates a single search term.The search function also supports the following special characters: -&quot; wraps a set of search terms.  * wildcard operator to use at the start or end of any search term.  ( and ) to specify operator precedence.For example, if you want to only match against URI Route that does not start with /v4/, then enter -&quot;/v4/&quot;* as the search term.Request FiltersRequest filters allow you to filter on HTTP request data including headers.Request.Geo IPAllows you to filter by geographic location data with the following filters:  City  Country Code  Country  Region Code  Region  TimezoneRequest.User AgentContains filters to query user agent data:  Build  Device  Major  Minor  Name  OS Major  OS Minor  OS  PatchRequest.BodyContains filters to query data from a HTTP request body. It also contains the wildcard filter to select a body field using wildcards such as locations.*.name. You may find this helpful when you have arbitrary keys in the request body.Request.URI SegmentsAllows you to filter on URI segments. Moesif assigns zero-based numbers to the URI segments. Therefore, the first URI segment has the number 0, and so on.Request.HeadersAllows you to filter on HTTP request headers. It also contains the wildcard filter to query the HTTP request headers using wildcards.Request.API VersionIf you configured API version in the Moesif server integration, you can filter on the version.Request.Content LengthCorresponds to the Content-Length HTTP request header.Request.Content TypeCorresponds to the Content-Type HTTP request header.Request.IP AddressThe IP address of the user agent making a request. Moesif only supports IPv4 addresses.Request.TimeThe request time.Request.URI RawThe raw URI that was requested.Request.URI RouteThe path components of the URI—for example, https://myblog.com/posts contains the /posts route.Request.Verb/MethodAllows you to filter on the HTTP request methods.Response FiltersResponse filters allow you to filter on HTTP response data including headers.Response.BodyContains filters to query data from a HTTP response body. It also contains the wildcard filter to select a body field using wildcards such as locations.*.name. You may find this helpful when you have arbitrary keys in the response body.Response.HeadersAllows you to filter on HTTP response headers. It also contains the wildcard filter to query the HTTP response headers using wildcards.Response.StatusAllows you to filter on the HTTP response status codes.Response.Content LengthCorresponds to the Content-Length HTTP response header.Company FiltersContains filters to query on company analytics and data.For more information about Moesif User and Company analytics features, see Introduction to User and Company Behavior.Company.EnrichmentAllows you to filter on demographic enrichment data that you have attached on company profiles.  Moesif Enterprise supports demographic enrichment for companies that allows you to add demographic data to customers. For more information, contact us.Company.SubscriptionsAllows you to filter on subscription data for a company.If you monetize your API, you can use these filters to set up complex business logic for different billing providers such as Chargebee, Recurly, Stripe, and more.For information about the subscription filters available, see Subscription Filters.Company.CohortAllows you to filter on saved cohorts for companies.Company.Company DomainLets you filter by company website domains after setting them in the company metadata.Company.CreatedThe time you created a company profile in Moesif.Company.First Seen TimeThe first time a company accesses your product.Company.Last Seen TimeThe last time a company used your product.Company.TTFHWThe Time to First Hello World (TTFHW) metric for a company.User FiltersContains filters to query on user analytics and data.For more information about Moesif User and Company analytics features, see Introduction to User and Company Behavior.User.EnrichmentAllows you to filter on demographic enrichment data that you have attached on user profiles.  Moesif Enterprise supports demographic enrichment for companies that allows you to add demographic data to customers. For more information, contact us.User.SubscriptionsAllows you to filter on subscription data for a company.If you monetize your API, you can use these filters to set up complex business logic for different billing providers such as Chargebee, Recurly, Stripe, and more.User.CohortAllows you to filter on saved cohorts for companies.User.CreatedThe time you created a user profile in Moesif.User.First Seen TimeThe first time a user accesses your product.User.Last Seen TimeThe last time a company used your product.User.Modified TimeThe last time a user profile was modified.User.TTFHWThe Time to First Hello World (TTFHW) metric for a user.User.EmailLets you filter by associated user’s email after setting it in the user metadata.User.NameLets you filter by associated user’s name after setting it in the user metadata.User.User Phone NumberLets you filter by associated user’s phone number after setting it in the user metadata.User.MetadataUser demographics or other properties you store in the user metadata.Subscription FiltersThe Subscriptions filters allow you to filter on various subscription-related data like subscription status, provider, and so on. You can access these filters by selecting Company.Subscriptions.Subscriptions.balanceAllows you to filter on subscription balance data. The following filters are available:  Subscriptions.balance.available_balance  Subscriptions.balance.current_balance  Subscriptions.balance.has_balance_transaction  Subscriptions.balance.pending_activity  Subscriptions.balance.sequence_idSubscriptions.cancel_timeThe cancellation date for a subscription.Subscriptions.collection_methodHow Stripe processes payments for subscriptions. Corresponds to Stripe collection_method.Subscriptions.company_external_idThe associated Company ID.Subscriptions.createdThe timestamp when the subscription was created.Subscriptions.currencyThe associated currency for a subscription.Subscriptions.current_period_endThe timestamp marking the end of the current subscription period.Subscriptions.current_period_startThe timestamp marking the start of the current subscription period.Subscriptions.internal_modified_timeThe timestamp when the subscription changed in Stripe, for example, changed to an active status from trial.Subscriptions.itemsAllows you to filter on various subscription items data, for example, Stripe Subscription Items data. The following filters are available:  items.created_at  items.item_price_id  items.plan          items.plan.created_at      items.plan.id      items.plan.name      items.plan.provider      items.plan.status        items.price          items.price.created_at      items.price.currency      items.price.id      items.price.name      items.price.period_units      items.price.period      items.price.plan_id      items.price.price_in_decimal      items.price.pricing_model      items.price.provider      items.price.status      items.price.tax_behavior      items.price.tiers                  items.price.tiers.up_to                    items.price.transform_quantity                  items.price.transform_quantity.divide_by          items.price.transform_quantity.round                    items.price.usage_aggregator        items.price_id: the price that the subscription is associated with  items.status: the price that the subscription is associated with  items.subscription_item_id: the unique identifier for the item as a subscription can contain multiple items  items.unit_of_measure: the unit of measure for the price if the subscription is based usage-based billing.Subscriptions.metadataThe metadata associated with a subscription.Subscriptions.modified_timeThe timestamp when the subscription changed in Moesif.Subscriptions.payment_statusThe payment status of a subscription.Subscriptions.providerThe subscription provider, for example, Stripe.Subscriptions.start_dateThe date when the subscription was first created. It might differ from Subscriptions.created due to backdating.Subscriptions.statusThe status of the subscription:  active  canceled  pending  trialing  draft  futureSubscriptions.subscription_idThe ID of the subscription.Metadata FiltersThe Metadata filter allows you to filter on custom metadata you set using event metadata.OpenTelemetry FiltersIf you’ve integrated OpenTelemetry, these filters become available:  Span.id, representing the span’s span ID  Span.parent_id, representing the span’s parent span ID  Span.status, representing the span status  Trace ID, representing the trace that the span is a part of  log.severity.number, representing the numerical value of the log’s severity  log.severity.text, representing the severity text of the log  scope, representing the instrumentation scope of the logFor more information on how Moesif maps OpenTelemetry data, see the following docs:  Span to Moesif API Event Mapping  Span Attributes Mapping  LogsCommon FiltersThe following common filters are available outside the preceding five filter types:Action NameLets you filter by custom actions.Auth/Session TokenThe authentication or session token used when making API calls—for example, credentials in the Authorization HTTP request header. For more information, see Identification of Users.Blocked ByLets you filter by governance rules.Company IDAllows you to filter API calls for a specific customer by a company ID. This feature requires you to set up company identification using an SDK. Otherwise, you may not get accurate results.Duration (Milliseconds)Lets you filter by the API call duration in milliseconds. The elapsed duration means the time elapsed between the API request and the server response.Event IDMoesif assigns a unique ID to each API call called an event ID. If you know the event ID—for example, you can use it here as a filter.Event TypeAllows you to filter by the event type: API Calls or Actions.Identified User IDAllows you to filter API calls for a specific end user by a user ID. This feature requires you to set up user identification using an SDK. Otherwise, you may not get accurate results.Request DirectionThis filter applies to API Calls only and allows you to filter by the direction of API requests.A value of Incoming shows only API calls to your own services you provide. A value of Outgoing only shows API calls going out to a third-party service.TagAllows you filter by event tags.User IDA random GUID Moesif assigns to anonymous website visitors who don’t possess identified user IDs. This filter is only relevant when using Moesif JavaScript Browser SDK in a client integration.Filter OperatorsWhen you add a filter, you’ll see different operator options depending on the data type. If data type of a field is ambiguous—for exaxmple, field.path.foo might be a string or date, filter operators for both string and date data types become available. However, the operator only acts on the data type that matches the operator.exist, not existAvailable for all data types.Moesif considers either null or undefined as not exist.is, is notAvailable for the following data types:  Numbers  Strings  BooleansYou can select multiple values for these operators.search, begins with, ends with, includes, not includesAvailable for only string data type.&amp;gt;, &amp;lt;, &amp;gt;=, &amp;gt;=, ==Available for numbers and dates.is before, is after, betweenAvailable for numbers and dates.For a number type field, Moesif treats the field value as epoch in milliseconds.count &amp;gt;, count &amp;lt;, count &amp;gt;=, count &amp;lt;=, count =Available for array data type in request or response body.It counts the number of elements inside the array. For example, if the original value of the field field.path.foo is [], the exist operator evaluates to truthy, but the count evaluates to 0.key count &amp;gt;, key count &amp;lt;, key count &amp;gt;=, key count &amp;lt;=, key count =Available for object data type in request or response body.It counts number of keys inside the object. For example:  Original value of field.path.foo is {}. The exist operator evaluates totruthy, but its key count evaluates to 0.  Original value of field.path.foo is { boo: 15}. The key count evaluates to 1.  Original value of field.path.foo is { boo: null, far: null }. The key count evaluates to 2.",
      "url": " /api-analytics/filters-reference/",
      "author": "Sakib",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-using-search-api": {
      "title": "Using Search API",
      "content"	 : "This document explains how to access the data of a metric workspace through API from Moesif Web Portal.This document also assumes you are familiar with Moesif API Analytics suite. For an introduction, see Introduction to Event Analytics and Logging.  You can access analytics data in three different ways from Moesif Web Portal:      Search API: enables you to consume your usage data using API within your applications to drive custom workflows.    Embed Template: enables you to dynamically embed charts in customer-facing apps with minimal frontend work.    Bulk Export: enables you to directly export your raw events to a data warehouse or other system.  OverviewSearch API gives you access to your chart’s data using Moesif’s Management API. You send a POST request to the Management API with your Management API key as the Bearer token and the search definition for the data you want to extract. This returns a JSON object containing the chart data that you can display in a more customized format. The search definition uses the Elasticsearch Query DSL.Search API allows you to build custom solutions using your data, such as custom dashboards, reports, analytics, and so on.Applicable Metric TypesYou can access Search API for any workspace that contains one of these metric types:  Live Event Log  Time Series  Segmentation  Geo Heatmap  Trace ExplorerUse Search APITo use Search API, from the chart you want to access through the Search API, follow these steps:      Select Embed / API from the chart header.          Select Search API.    Moesif generates a cURL command for your workspace criteria that you can use immediately to access the chart data. Moesif also gives you the HTTP request details so you can use HTTP clients like Postman.        Select the Curl Command tab for the cURL command and the HTTP Details tab for the HTTP request details.  Search DefinitionThe search definition Moesif generates uses the Elasticsearch Query DSL. To access the search definition, see the HTTP request body from the HTTP Details tab or the generated cURL command’s -d (or --data)  argument value.This search definition accurately represents your desired report according to your chart’s filters and settings. You can quickly go back to your chart window, reconfigure, select Embed / API, and then select Search API to update your search. If you need help building a query for your business requirements, contact us.The Search API sends your request to the Management API’s events search endpoint. For more information, see the Management API searchEvents documentation.Learn More  Learn about different ways to share your workspaces.  Learn how to securely embed charts and metrics.",
      "url": " /api-analytics/using-search-api/",
      "author": "Sakib",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-ai-explain": {
      "title": "AI Explain",
      "content"	 : "This document explains how to use AI Explain in the Moesif’s API Analytics suite.OverviewMoesif’s AI Explain feature is an GenAI-powered conversational interface that allows you to easily ask questions and gain insights about your analytics data. This feature is designed to enhance the accessibility of Moesif’s analytics for users with minimal experience or knowledge of analytics tools and related concepts. By simply typing a question, users can receive detailed insights, helping them make more informed decisions.AI Explain is available in for the following metric types:  Live Event Log  Time Series  Segmentation  Trace ExplorerHow It WorksAI Explain leverages Azure OpenAI, a leading large language model (LLM) platform, to process user questions and generate insightful responses. This integration allows AI Explain to provide quick and relevant answers based on your API analytics data.Data UsageYour prompts and responses are not used for training or shared with others.To generate responses for your questions, Moesif sends the following event data to Azure OpenAI:  Event properties, including event IDs  Request and response data, such as headers and IP addressesGetting Started with AI Explain for EventsTo start using AI Explain, navigate to the Live Event Log and look for the Ask AI button. There are two ways to use AI Explain:  Use the Last 30 Events: You can select Ask AI, and it will use your last 30 events as context to generate insights.  Select Specific Events: Alternatively, you can select specific events and then click Ask AI to include those specific events in its context, providing more targeted responses.From there, you can type your questions directly, and AI Explain will use the available event data to generate insightful answers for you. Whether you need to identify trends, pinpoint issues, or understand user behavior, AI Explain helps you get the answers without needing to dive deep into complex metrics or dashboards.Getting Started with AI Explain for MetricsYou can also navigate to any metric report and leverage AI Explain to provide insights around the metric. For example, you can ask questions like “what are the key insights” or “summarize this report”In order to get started, navigate to any metric and click the orange “AI Explain” button.Key Benefits  Accessibility: Makes Moesif’s analytics accessible to users without in-depth knowledge of analytics tools.  Efficiency: Saves time by providing direct answers, allowing you to avoid building complicated queries.  Insights on Demand: Ask questions naturally, and get detailed insights about your API analytics in real-time.Your Data and PrivacyMoesif is committed to maintaining the privacy and confidentiality of your data. While the event data and conversational history are sent to Azure OpenAI for processing, it is important to note that Azure OpenAI does not store, train on, or share your prompts, responses, or Moesif data with others. Your data remains secure and is used solely to provide responses to your queries.",
      "url": " /api-analytics/ai-explain/",
      "author": "Dylan",
      "categories": "API-Analytics"
    }
    ,
  

    "api-analytics-otel-trace-explorer": {
      "title": "Trace Explorer",
      "content"	 : "This document explains how to use Trace Explorer in the Moesif’s API Analytics suite.Trace Explorer is superceding the Traces view in Live Event Log. Therefore, to access trace data, you will need to open a new Trace Explorer workspace.OverviewTrace Explorer allows you to observe OpenTelemetry traces, their constituent spans, and logs in real time across your applications and services. You can filter by various attributes, like trace ID, request and response data, and user and company data like user and company ID. Trace Explorer provides an easy-to-navigate means for real-time, continuous observability into your platform.For a step-by-step guide on how to integrate OpenTelemetry and Moesif with your application, see Integrating with OpenTelemetry.Use Cases and BenefitsTrace Explorer provides a dedicated workspace to visualize the end-to-end journey of requests across your distributed systems. It unifies OpenTelemetry traces with correlated logs and helps construct and observe a cohesive story of system behavior, without having to integrate another observability tool separately.Here are some example use cases and benefits:  If you observe failed API requests in a complex network of services, use Trace Explorer to follow the trace ID across every service boundary. You can exactly identify the microservice or specific database query that triggered the error.  If a process takes more time than usual, Trace Explorer can help confirm where the delay originates from.  Observe spans and logs for non-deterministic issues, like intermittent race conditions,that affect user experiences despite not triggering standard alerts.  Analyze the impact of new code deployments by evaluating traces before and after a release to see if internal dependency calls have increased.  Observe logs emitted during a specific operation directly alongside its trace span, easing investigation during a high-traffic incident.  Having traces and logs in a single configurable workspace means you don’t need to manually correlate timestamps.  A single workspace makes sure that every team observes the same correlated data.  Traces’ visual nature helps new team members understand how services interact in production, illustrating a “living map” of the architecture.Create Trace Explorer WorkspaceTo access Trace Explorer and create a new Trace Explorer workspace, select+ Create New in the navigation menu and then select Trace Explorer from the API Observability section.FiltersYou can refine the the trace and span data Moesif displays using filters. To access the filters, select the span filters list in the Filters pane.For more information about the available filters, see Reference: Analytics Filters.You can chain multiple filters together by selecting Where and OR.Filter By CohortsYou can further refine the viewed trace data by selecting a user or company cohort from the Performed By list:This allows you to observe traces pertaining to specific customer cohorts—for example, new users that have been encountering errors or events for enterprise customers. For example, the following filters out enterprise customers and displays traces for non-enterprise customers only for a specific API version:Inline CohortsUse inline cohorts to define a cohort criteria directly in your Trace Explorer workspace. This allows you to instantly refine your analysis when you don’t already have an existing cohort to filter by.To define an inline cohort, select Performed By and then select + Inline User Cohort or + Inline Company Cohort. It opens up a new dialog where you can define a cohort criteria using customer and event filters.Analytics and Filtering on HTTP PayloadMoesif allows you to define filters on and analyze HTTP bodies, even for deeply nested structures. To access HTTP event data like request and response payload, select a trace and then select one of the spans to access the span details.For example, here we observe traces for events that have large context size in an AI API product:You can also select a specific body field key or value and choose to define filters directly from there. For example, here we’re interested in the image resolution data in the request body for an API call in an image generation API. If we select one of the filtering options, Moesif includes or excludes API calls that have requested to generate 768x768 resolution images.For more information about interacting with event data fields this way, see Event Data Field Options.Named Variables for FiltersYou can define named variables that hold filter values and then use it across filters.To add filter variables, select Variables. Then select Add Variables to define a variable. After defining your variables, select Save.To use a variable, enter the variable name enclosed in double curly braces in a filter value. For example:You must manually enter the variable name this way to use it. You can quickly check defined variables by hovering over Variables—the tooltip shows the defined variables and their values.This feature allows you to avoid manually updating filter values in complex and dynamic filtering scenarios.View Events for New Users and Companies OnlyTo see traces pertaining to only new users and companies, enable the New Users Only and New Companies Only filters respectively. These two filters allow you to see events for users or companies who’ve made their first API call within the time period you specify.Trace Data ViewsYou can switch between two views in Trace Explorer:  Trace View  Span ViewTrace ViewDisplays traces and logs data. Selecting a trace opens more details about its constituent spans and the correlated logs.Span ViewDisplays spans and logs data including their time axis visualization and corresponding operations. Selecting a span opens more details about the event, like event type and trace ID.In the expanded menu for a span, you can go to  Span Events to view Span Event data for the span. Span Events is also available in the Stream view of Live Event Log workspaces.Event Data Field OptionsYou can interact with individual event data fields and field values in Trace Explorer:In the dropdown, you can view more detailed information about the data element and perform further actions on that specific data. For example, you can filter and sort, plot the data as a metric in a different chart, and so on.Save and ShareMoesif gives you several options to share a Trace Explorer workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.AI Explain : Use AI to Get Insights About OpenTelemetry DataAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about OpenTelemetry traces and logs.In Trace Explorer, select Ask AI to open up the interface. Moesif selects the first 30 events as target events for the AI to analyze and answer your questions about. A maximum of 30 events at a time can be analyzed.To get started, you can choose from three sample prompts. Otherwise, type in your query and press Enter.",
      "url": " /api-analytics/otel-trace-explorer/",
      "author": "Sakib",
      "categories": "API-Analytics"
    }
    ,
  

    "user-analytics": {
      "title": "Introduction to User and Company Behavior",
      "content"	 : "This guide assumes you are familiar with Users and Companies.User and Company analytics provides the necessary tools for analyzing individual customers and their behaviors. You can look up customers based on their properties and create reports to better understand your user base composition. You can also utilize complex user behavior reporting like funnel and retention analysis.As a user behavior analytics platform, you can perform analysis on not only who the customer is but also what a customer does, in terms of API calls and custom actions. This enables you to segment your customers based on what they perform (or lack thereof). For example, you can leverage user analytics to find all users who performed at least one API call.  Note that events may take up to 20 minutes to show up in the user analytics screens. If your data has not shown up, try again later once the data has had time to filter over.Moesif has two types of customer entities: Users and Companies.UsersA User represents a single end-user or client accessing your API. Moesif tracks this with a unique ID for the user. This ID comes through a Moesif server integration in the middleware configuration or through a gateway plugin, usually by default. If you have a B2C business, this may suffice for all your tracking requirements. If you have a B2B or partnership business, you can associate a user with a company. This allows you to group metrics together and to see trends across all users in the organization.For this functionality to work, you must have user tracking enabled. Most gateways have this functionality enabled by default. You can also enable through configuration options, usually in a header. If you use a Moesif server integration directly in your code, you need to implement the identifyUser hook in your middleware configuration. For an example in Node.js, see the identifyUser function documentation.To access user analytics in Moesif Portal, select Users in the navigation menu.CompaniesA Company in Moesif represents a group of users that belong to the same account, possibly referred to as a tenant or organization. By making companies first class entities, Moesif gives users the ability to track users and companies completely separately. If you have a B2C business, you may not need to use companies functionalities.For this functionality to work, you must have company tracking enabled. Most gateways have this functionality enabled by default. You can also enable through configuration options, usually in a header. If you use a Moesif server integration directly in your code, you need to implement the identifyCompany hook in your middleware configuration. For an example in Node.js, see the identifyUser function documentation.To access company analytics in Moesif Portal, select Company in the navigation menu.User and Company Analysis TypesMultiple types of analysis are available for both Users and Companies. Moesif supports the following types:  Lookup  A CRM-style lookup which allows Moesif users to filter for specific users or companies based on a criteria.  Funnels  Create a user funnel analysis to analyze user or company trends.  Retention  Create a retention analysis to inspect details around user or company retention.  Composition  Create a user composition analysis to understand your products user composition.You can access each of these analysis types from the analysis transition dropdown.Create a New AnalysisTo create a new analysis, select + Create New. Then select the analysis type.API protocol supportMoesif supports a variety of API protocols including REST, GraphQL, and Ethereum Web3 (JSON-RPC) APIs.For more information, see GraphQL Support and JSON-RPC Support.FiltersMoesif offers a vast array of filters that can provide deeper insights into your User and Company analytics data. These filters allow you to construct powerful and complex queries for different analysis types and build intuitive visualizations.For a reference documentation for the filters, see Reference: Analytics Filters.AI ExplainAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about analytics data. AI Explain greatly improves the accessibility of Moesif’s analytics for users who have minimal experience and knowledge about analytics tools and related concepts.This feature is available in for the following User and Company analysis types:  Funnels  Retention  CompositionTo use AI Explain, you must have a paid Moesif plan in Growth or Enterprise. For more information, see Moesif Pricing.Usage of Open AI and Large Language Model (LLM)Moesif AI Explain uses Azure Open AI to process your questions and generate responses. To power AI Explain, Moesif sends the following event data to Azure OpenAI:  Event properties such as event IDs  Request and response data for API calls such as body, status, and IP addressesYour Data and InformationApart from the event data mentioned, Moesif also sends conversational history inlcuding previous questions and responses to the OpenAI API. However, OpenAI doesn’t store or train on your prompts, responses, and Moesif data nor share them with others.",
      "url": " /user-analytics/",
      "author": "Derric",
      "categories": "User-Analytics, Company Analytics"
    }
    ,
  

    "user-analytics-user-lookup": {
      "title": "User and Company Lookup",
      "content"	 : "This document explains how to use Lookup analysis in the Moesif’s User and Company Analytics suite.Moesif supports Lookup analysis for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.OverviewThe Lookup analysis allows you to look up individual customers, like a CRM (customer relationship management) system. You can filter by any user properties like email or company domain. Since Moesif is a user behavior analytics platform, you can also filter based on events that a user or company performs. This incluces API calls and custom actions.Before You StartEvents may take up to 20 minutes to show up in the user analytics screens. If your data has not appeared, make sure you wait until Moesif has completed the instrumentation process and loaded the data.Create a New Lookup AnalysisYou can create a new Lookup analysis in two ways:From the Create New Dialog  Log into Moesif Portal.  Select + Create New in the navigation menu.  Select Lookup for Users or Companies.From Users or Companies Screen  Log into Moesif Portal.  Select Users or Companies in the navigation menu.  Select Retention from the dropdown menu.Example QueryWith the Lookup analysis, you can filter users or companies based on properties of a user or company. You can also filter based on events that they have performed within your product. You can add a filter for user or company properties, events properties, or both.For example, to see all self-service users running into 400 Bad Request error response, you can add two filters:  Users that are not on an enterprise plan. This indicates a custom user property.  Users who’ve made at least one API call in last seven days, getting a 400 Bad Request error response.FiltersYou can refine a Lookup table using filters.For more information about the available filters in Lookup, see Reference: Analytics Filters.The following sections discuss some common recipes and examples to demonstrate how to use the filters.Filtering by User and Company PropertiesUser or company filters enable you to filter based on customer properties such as email, name, and time of creation. Customer properties are stateful. This means that customer properties can receive updates. Updates can come from yourself to add customer demographic information or Moesif with information like Last Seen Time.You can also find your custom user metadata and company metadatahere.You can chain multiple filters together by selecting Where and OR.Filter by Event PropertiesEvent filters enable you to filter based on the events a customer has performed. A single user or company may have performed multiple events.Since events represent something that occurs at a single instance in time, you need to specify the time range—for example, Last 24 hours.Let’s say we want to look up users with the following criteria:  At least 10 API calls in the last 24 hours.  AND the response is 400 Bad Request error response.  AND /purchases/:id/decline OR /purchases as the route of the API calls.The query looks like the following:Event TypesEvents can fall into one of two types:  API Calls  The requests hitting your servers at various API endpoints such as GET requests to the /items endpoint.  Actions  Custom actions triggered by users within your application or UI—for example, a user signing up.You can filter by these event types by selecting the Event Type filter.Creating Event FiltersYou can think about combining event filters in two ways:  Customers who performs an event matching both X AND Y, in a single event.  Customers who performs an event matching X AND an event matching Y. This means multiple events.Filters within the same group (Moesif outlines the group in a box in the UI) matches against the same event. Separate groups match against separate events.1. Customers Who Perform an Event Matching Both X AND YTo find a single event that matches multiple criteria, make sure to keep the properties in the same group. Remember that Moesif outlines the group in a box in the UI.For example, you may want to display all users who made an API call that returned 400 Bad Request error response AND the route of that API call was either /purchases/:id/decline OR /purchases. This means matching multiple properties of the same event. Therefore, the query looks like this:2. Customers Who Perform Event Matching X AND an Event Matching YIf you want to match across independent events a user performs, add multiple OR or AND condition boxes. Each filter box then contains the filters for each individual event criteria.For example, you may want to match against both an API Call and an Action. Let’s say you want to show all users who fall into the following criteria:  Made API calls to either /purchases/:id/decline OR /purchases_ URI route that returned 200 OK responses.  AND performed a custom action where Action Name is Signed-In.The query for this looks like the following:Event numeric aggregationsBesides equality, event fields also support aggregations such as average, max, or distinct. For example, you can create a cohort of users who accessed your API with over 10 distinct IP Addresses per hour anytime over the last 7 days. This can be done like so:Table ActionsYou can perform a variety of actions to a Lookup table.Select Fields to DisplayTo display more data fields in a Lookup table, select Select Columns and specify the fields. For example, you can select Request.Geo IP.Country as your custom field. Now in the default Lookup view for each user or company, the country where the request originates from appears.Any columns you add to the table also appears in a bulk export.Custom ColumnYou can also add a custom column containing calculated data from the table by selecting Add equation.A modal then appears where you need to enter the details of your custom column formula.The formula details include the following:  An optional name for your formula.  An operator that for the calculation method.  Fields or constant values as operands.For example, the following formula calculates the difference between the first and the last seen times for customers. This data now appears in the column Activity Period in the Lookup table.If your field is missing, add it via the Select Fields button first. Also, please note the table formulas are based on values currently in the table not based on an queries from database.Deleting a Custom ColumnTo delete a custom column, select X in the column header.Sorting the Results  Select the field you want to sort on.  Select the sort direction, ascending or descending.Timestamp ValuesIn a Lookup table, Moesif parses the timestamps into human-readable format in your timezone. To display the raw timestamp values in ISO 8601 format instead, select Original Raw Values.Adding New Users or CompaniesYou can also add new users or companies from the Lookup table screen.To add new users or companies, select + Add Users or + Add Companies. Select the method of import and then follow the instructions on the page. For example, you can use CSV files to import user or company data.Creating a User and Company NotificationFor each user or company, you can create an alert to trigger whenever a customer meets the desired condition. To create a notification, follow these steps:  Apply the filters you want for the alert condition.  Select More Actions and then select Internal Notification.    Next, you must create a cohort that defines the alert criteria based on the filters you’ve defined. In the dialog that appears, enter the cohort name and then select Save and Continue.  In the next dialog, select the notification channel where you want to send the alert notification to. If you use a webhook, copy the sample payload if you need to.  Select  Save.Create CohortSaved cohorts define groups of users based on their properties and events they’ve performed. For example, a cohort that defines users who are exceeding rate limits in the last 24 hours. Think of cohorts like a saved list of users that matches some criteria and one that Moesif continuously updates in automatically.To save a cohort based on your filters, follow these steps:  Select Create Cohort.    Enter the cohort name.  Select Create Cohort.After creating a cohort, you can target the cohort with Moesif’s automation features like triggering behavioral emails and dynamically sampling customers.Creating a Sample Rate for a CohortTo set a sample rate from the User Lookup screen, follow these steps:  Select More Actions and then select Set Sample Rate.    In the dialog that appears, create a cohort for the sample rate.  In the Add User Sampling Rule dialog, set the Sample Rate and Priority for the sampling rule.  Select Save.For more information, see Dynamic Sampling.Save and ShareMoesif gives you several options to share a Lookup workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.",
      "url": " /user-analytics/user-lookup/",
      "author": "Derric",
      "categories": "User Lookup, Company Lookup"
    }
    ,
  

    "user-analytics-conversion-funnel-analysis": {
      "title": "Conversion Funnel Analysis",
      "content"	 : "This document explains how to use Funnel analysis in the Moesif’s User and Company Analytics suite.Moesif supports Funnel analysis for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.OverviewFunnel analysis allows you to understand where customers drop off as customers use your APIs and products. Funnels use a combination of steps that can include specific API calls, but also custom actions a customer performs in your UI such as signing in. This enables tracking metrics like Time to First Hello World (TTFHW) and Time to First Working App (TTFWA).If you’re not familiar with funnel analysis, see the second chapter of API Analytics: The Ultimate Guide to Grow Your Platform Business eBookBefore You StartEvents may take up to 20 minutes to show up in the user analytics screens. If your data has not appeared, make sure you wait until Moesif has completed the instrumentation process and loaded the data.Create a New Funnel AnalysisYou can create a new Funnel analysis in two ways:From the Create New Dialog  Log into Moesif Portal.  Select + Create New in the navigation menu.  Select Funnel for Users or Companies.From Users or Companies Screen  Log into Moesif Portal.  Select Users or Companies in the navigation menu.  Select Retention from the dropdown menu.Example FunnelFunnels compose a series of actions that a single user or company performs. These actions can either come from the API or originate within your UI through custom actions.For example, the following funnel has two steps:  Users who performed a Signed-In action  Users who also made at least a single API call to the /esignature/documents API endpoint.We can see that only 36.12% of users who signed in also made an API call to /esignature/documents. It took a day on average to reach the second step.FiltersIn a Funnel analysis, you must specify the step requirements to define a conversion funnel. And defining a conversion funnel requires you to use event filters. You can further refine the Funnel analysis by filtering on customer data.The next sections discuss how to define the conversion funnel and make use of the powerful filters available to you.For more information about the available filters in Funnel analysis, see Reference: Analytics Filters.Step CriteriaYou can build funnels with a number of steps that represent milestones a customer reaches with your API. For example, the beginning of your funnel may start on your website as a visitor signs up to use your API. However, once they created an API key, much of the magic happens on the API side rather than the web side. This means you want to track the customer journey as they make their first API call, then they make enough API calls that they receive value from your product.Step OrderingYou can compute the conversion steps in two orders. Select the order you prefer in Steps completed.  In Order  The first step must occur before the second step for Moesif to consider the user as converted. Other events are allowed between the first and second step, as long as the first step occurs before the second one.  Any Order  Moesif doesn’t take into account the order the steps occur in. This means Moesif considers users as converted as long as they perform the steps, regardless of the order they perform them in.Step Completion PeriodYou can also specify a conversion window that specifies within what time period all the steps must complete. By default, the time period remains null and Moesif doesn’t take into account how long it takes for customers to convert.You can override this such as to only show customers who covert within a window like seven days.Event filtersEvent filters enable you to filter based on the events a customer has performed. A single user or company may have performed multiple events.You can filter by any custom actions you are tracking within your UI like users signing up, purchasing a plan, and so on. You can also formulate steps based on API call properties such as API route, request HTTP headers, or other criteria to narrow down your conversion steps.Events can fall into one of two types:  API Calls  The requests hitting your servers at various API endpoints such as GET requests to the /items endpoint.  Actions  Custom actions triggered by users within your application or UI—for example, a user signing up.You can filter by these event types by selecting the Event Type filter.Step FrequencyYou can also specify how many times a user must perform a step before you consider that user as converted. For example, you may want to understand users who made over a 100 API calls which is your cutoff to consider receiving value from the API.This can become useful if you want to see the drop off between users who made their first API call and users who made a minimum number of API calls, implying a more complete integration.In the following chart, we see that only 30.97% of users who made at least a single call to the /esignature/documents/:id endpoint has also made more than 10 calls to that endpoint.User criteriaYou can also narrow your funnel to specific segments of users or compare across customer segments.Group DataYou can break down funnels by user or company fields such as acquisition channels or industry to understand what converts the best.In the following example, we are grouping by UTM source. Moesif automatically tracks this property by moesif-browser-js to understand which paid marketing channels drive the most integrated users.FiltersIf you want to narrow down your funnel analysis to a specific segment of users, you can do so with the user filters in the Filter pane.For example, to include only new users created within the last four weeks till now who also live in the United States, define the filters this way:Moesif doesn’t consider users who don’t match your criteria entering the funnel.Any fields that you save as part of user profiles remain available in funnel analysis.Conversion Over TimeConversion over time shows conversion rates for users who enters the funnel on a specific date. Therefore, if a user enters the funnel on November 30th, but completed the second step on December 3, that user will be counted for the day November 30.Moesif aligns all dates to top of the calendar date. So daily means midnight to midnight, whereas monthly indicates start of the month to the end of the month.The following graph shows the conversion rate broken down for each day for the last seven days.Chart OptionsYou have several chart options that allow you to customize how Moesif plots funnel analysis and what information appears to you.Plotting in PercentagesSelect Plot Percentage to plot funnel metrics as percentages. Moesif uses this option by default when using the default entire range plot interval.Plotting CountsSelect Plot Count to plot metric values instead of percentages when using the default entire range plot interval.Profile InspectionSelect Inspect Profiles to include user or company IDs for each funnel step in the funnel table when using the default entire range plot interval.Funnel Analysis Time SpanSelect the time span dropdown menu to specify the period of time you want to perform funnel analysis for. You can select from one of the builtin time spans, for example, Last 7 days or Last week. If you want more precise control, use the relative date range or absolute date range options.Funnel Analysis Time IntervalTo specify the time interval for the funnel analysis plot, select an interval from the interval dropdown.By default, Moesif plots the funnel for the entire range of the period of time you specify. If you want to break down the chart for definite time intervals and understand how conversion looks within those intervals, you have the following options:  daily  weekly  monthly  quarterlyWhen you specify one of these intervals, you have the following two chart options available to you:  Vertical axis data  You can select what metric data Moesif plots on the vertical axis:          Select Conversion Rate to plot conversions as percentages.      Select Entity Count to plot number of unique users that convert.      Select Time to Convert to plot the time it takes for users to convert.      Select Percent Change of Conversion Rate to plot conversion rate changes for each time interval in percentages.      Select Percent Change of Entity Count to plot entity count changes for each time interval in percentages        Funnel steps  You can choose to plot for the entire funnel, or just one of the individual steps.AI Explain : Use AI to Get Insights About Funnel AnalyticsAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about funnel analytics data.In a Funnel workspace, select Ask AI to open up the interface. To get started, you can choose from the sample prompts. Otherwise, type in your query and press Enter.Save and ShareMoesif gives you several options to share a Funnel analysis workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.",
      "url": " /user-analytics/conversion-funnel-analysis/",
      "author": "Derric",
      "categories": "conversion-funnel-analysis"
    }
    ,
  

    "user-analytics-cohort-retention-analysis": {
      "title": "Cohort Retention Analysis",
      "content"	 : "This document explains how to use Retention analysis in the Moesif’s User and Company Analytics suite.Moesif supports Retention analysis for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.OverviewThe Retention analysis allows you to accurately measure product retention and stickiness over time.Product retention measures the percent of users within a cohort that interact with your API in some way and thenreturn to continue interacting with your API. This contrasts with subscription retention that merely tracks whether a customerhas an active subscription. Product retention, on the other hand, tracks whether users come back and actively use your product.If you’re not familiar with retention analysis, see the third chapter of API Analytics: The Ultimate Guide to Grow Your Platform Business eBookTo start a Retention analysis, you need to decide on initial and returning criteria in the First Event and Returning Event fields respectively. By default, Moesif considers any activity, but you can specify your criteria based on API events or custom actions.For example, consider an electronic signature API. Then you can set the following criteria:  First event criteria  POST request to the /esignature/documents endpoint.  Returning event criteria  POST request to the /esignature/documents endpoint.Before You StartEvents may take up to 20 minutes to show up in the user analytics screens. If your data has not appeared, make sure you wait until Moesif has completed the instrumentation process and loaded the data.Create a Simple Retention AnalysisYou can create a new Retention analysis in two ways:Use the Create New Dialog  Log into Moesif Portal.  Select + Create New in the navigation menu.  Select Retention for Users or Companies.Use Users or Companies Screen  Log into Moesif Portal.  Select Users or Companies in the navigation menu.  Select Retention from the dropdown menu.Next, specify the first and returning events criteria. For example, here we create a simple retention analysis where we want to understand company retention by different subscription plans over the past month.If you don’t specify the First and Returning events, Moesif calculates the retention based on any event Moesif receives for that user. This can sometimes prove useful but to accurately analyze customer retention, we recommend picking specific first and returning events.FiltersIn a Retention analysis, you must define how you consider customer retention for your use case. In Moesif, this means specifying a pair of events using event filters. You can further refine your analysis with groups and segmentations.The next sections discuss how to define the retention events and make use of the powerful filters available to you.For more information about the available filters in Funnel analysis, see Reference: Analytics Filters.Determining First Event and Returning EventsCreating a retention analysis requires you to define two events. These two events define when you consider a customer retained.Define the initial event in the First Event pane. The initial event represents when a user first receives value from the product. For example, on an e-commerce platform, this may capture the first time the user actually creates a purchase order. For a communications platform, the event may capture a user sending a text message through the platform.Lastly, define the second event in the Returning Event pane. The returning event indicates when a customer returns back to the platform and performs an event where they receive value from the product. This means the customer has become a repeat custome or buyer. Typically, you define the same type of event as the initial event and the returning event, but it may be something completely different. Every time a user performs the returning event they Moesif considers them a retained customer. When a user no longer performs the returning event, the user is no longer retained and likely is no longer using the product.Setting the Event CriteriaAfter setting the criteria, you can inspect the resulting chart and table showing user retention data.The vertical axis in the chart shows the percentage of users performing the returning event for each interval after the cohort date. The horizontal axis breaks down into cohort date intervals according to the retention interval and the period of time you perform the retention analysis for.For example, the preceding example illustrates daily retention in the last three days. Therefore, day 1 indicates one day after the cohort date, day 2two days after the cohort date, and so on.If instead you select weekly or monthly retention interval, then Moesif counts user for week 1 if they performed the returning action any day of the following week after the cohort date.For example, if you show daily retention, then Moesif segments your user baseinto daily cohorts based on when they performed the first API call.Configuring SegmentationBy using a segmentation clause in the Segment By pane, you can make the retention analysis only include retention for customers who performed a certain action or belong to a certain segment of the customer base. This can help you see how specific segments perform in terms of retention. Without segmentation, Moesif groups all retention together and creates an average.For example, here we add a segmentation clause where we want to look at the differences in retention for customers in both Enterprise and non-Enterprise plans.Configuring GroupsThe grouping feature in the Group By pane allows you to see what the retention looks like across different cohorts of users based on demographic information or acquisition channels. Select + Group By in the Group By pane and then define your criteria by selecting fields to group your customers.For example, to group users by UTM sources, select the Campaign.utm_source field. This shows what customer retention looks like for users depending on what UTM source they come from.Setting the Retention IntervalYou can set the retention interval in the retention interval dropdown.The following intervals are available:  daily  monthly  weeklySetting the Retention Analysis Time SpanYou can set the retention analysis time span by selecting the interval from the dropdown. You select from one of the builtin time spans, for example, Last 7 days or Last week. If you want more precise control, use the relative date range or absolute date range options.All Users versus New Users OnlyTo specify whether you want to include all users or only new users in the retention analysis, select All Users or New Users. By default, Moesif uses All Users.New Users filters each cohort by only new users. New Users can help you to measure how sticky your adoption funnel is while excluding users who you already consider long-term customers. These users therefore may already have high retention rates.Alternatively, you can also select All Users to include all users in the analysis.Profile InspectionSelect Inspect Profiles to include user or company IDs that have recently entered into the retention analysis in the retention data table. To see the IDs, select a group in the retention table and and then select a number in the Total Users column.A dialog appears with the following information:  User IDs and corresponding profile pages of users who completed the First Event on that day.  Link to a Live Event Log metrics report for each user ID.Interpreting the ResultsWhen understanding a retention report, it might help to keep a few scenarios in mind. Some of these scenarios show healthy retention and others show unhealthy retention or retention that can use improvement.High or Optimal RetentionThe optimal retention rate varies by industry, making it difficult to pinpoint the exact place you want your retention rate to land. Depending on your industry, you obviously want to make sure that your retention curve begins to flatten quickly and stays roughly around the target for your business or industry. You must also consider what efforts go in to have high retention. You need to continue those efforts to keep customers loyal. If retention starts to drop as you make changes to onboarding, business processes, marketing, and other factors, you may want to look at reverting back to tactics that made retention higher. In case retention drops, likely the experience of your service or app have failed to meet the customer expectations. Your customer retention strategy must always aim to keep retention as high as possible.Retention Drops off QuicklyIf retention drops quickly to low levels, this usually means one of these possibilities:  The product has failed to satisfy the customers  The customers have not been getting the value out of the product to justify returning.If you look at retention on a monthly level and by the second month retention drops significantly, you may want to look at retention in a smaller time segment, such as weekly or even daily. With poor retention, small changes may lead to massive differences.The Retention Report Contains Less HistoryConsider a business that has only been around for four weeks or you’ve only been tracking retention for four weeks. Then it proves difficult to look at retention on a 12-month basis since the data doesn’t exist. If you find that your retention report stops sooner than you expect, you need to make sure that you have enough data to support the time span that you want to look at. If you have limited data, consider using a smaller unit of time. For example, consider looking at retention on a daily or weekly basis until your data grows big enough to assess at a monthly or yearly level.AI Explain : Use AI to Get Insights About Retention AnalysisAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about retention analytics data.In a Funnel workspace, select Ask AI to open up the interface. To get started, you can choose from the sample prompts. Otherwise, type in your query and press Enter.Save and ShareMoesif gives you several options to share a Retention analysis workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.",
      "url": " /user-analytics/cohort-retention-analysis/",
      "author": "Derric",
      "categories": "cohort-retention-analysis"
    }
    ,
  

    "user-analytics-composition": {
      "title": "Composition Analysis",
      "content"	 : "This document explains how to use Composition analysis in the Moesif’s User and Company Analytics suite.Moesif supports Composition analysis for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.OverviewMoesif’s Composition analysis allows you to understand your user base by breaking them down into segments and groups. Instead of events, you break down the data based on user properties. This gives you a deep look into your user distribution from different point of views, allowing you to identify important trends and strategize accordingly.Before You StartEvents may take up to 20 minutes to show up in the user analytics screens. If your data has not appeared, make sure you wait until Moesif has completed the instrumentation process and loaded the data.Set up a New Composition AnalysisTo create your own Composition analysis, follow these steps:Step 1: Create a New Composition Analysis WorkspaceYou can create a new Composition analysis workspace in two ways:From the Create New Dialog  Log into Moesif Portal.  Select + Create New in the navigation menu.  Select Composition for Users or Companies.From Users or Companies Screen  Log into Moesif Portal.  Select Users or Companies in the navigation menu.  Select Composition from the dropdown menu.Step 2: Select User and Event Filters (Optional)You can go really low-level and fine tune your Composition analysis by selecting user and event filters. This lets you filter your Composition chart by specific user properties like location, or by specific events that users have performed.See the example where it selects one user filter and one event filter to narrow down the composition analysis data.Step 3: Select the Breakdown CriteriaNext, select the user properties you want to use to break down the chart. The example in the next section selects the initial UTM source as the breakdown property.Step 4: Select the MetricLastly, select the metric you want to plot in the Composition chart based on the user property and filters you’ve defined in the preceding steps. You can plot more than one metric in the chart.Moesif offers several predefined metrics. If these predefined metrics don’t suit you, you can define custom metrics.ExampleLet’s consider the following requirements for a composition analysis:  Unique customers from the United States. Unique means we want to exclude anonymous visitors and only include users with identified user IDs.  We want to break down the data based on initial UTM sources. This helps understand how users come to know about the product and examine marketing strengths  in different platforms.  Customers must’ve used the product successfully at least once. Let’s measure this by filtering on HTTP 200 OK status code.  We want the data for the past week.Then we can define the user filter, event filter, and breakdown property in the following way:This results in the following composition analysis chart:The next sections discuss more about the steps you need to follow to build a Composition analysis in Moesif.FiltersIn a Composition analysis, you need to define the data breakdown criteria by selecting one or more user properties. You can go deeper and narrow down the data by selecting from user and event filters. For more information about these filters, see Reference: Analytics Filters.Configure GroupsSelect Group By and then select the property by which you want to break down the data. You can group by user or company metadata, company domain, user ID, and many more. In our example, we select Campaign.initial_utm_source as the user property. This breaks down the chart by sources from where users come from.You can specify at most three groups at a time. For more than one group, you have two extra chart options to customize the plot. For more information, see Stacking Plots and Merging Groups.Configure SegmentationIf you want to use your own criteria to segment data by custom groups, use the Segmentation option.In the previous example, let’s say we want to see the number of Enterprise plan users. To do so, we select  + Segment and then select Company.Metadata.plans from the Select Field list. This results in the following chart.It still shows the number of unique users from the last week in the United States and breaks down the data into the UTM sources the users came from. But now, we have a breakdown of unique users who are subscribed to the Enterprise plan.After selecting + Segment, Moesif generates a unique name for the segment that you can change—for example, segmentcd635fbb. In the preceding example, we entered the name Enterprise Users. You can reference this name when you define a custom metric formula.Configure Metrics and ChartYou can specify, configure, and visualize a composition analysis metrics in different ways.Select the Metrics to PlotBy default, Composition plots only the Unique Users metric. You can always plot more than one metric in the same chart by selecting + Add Metric.The following predefined metrics are available:  Unique users: number of unique users, including both identified users with identified user IDs and anonymous users  Unique identified users: number unique users, including only users with identified user IDs  Unique companies: number of unique companies with company IDs  Unique company domains: number of unique company domains  Unique sessions or keys: number of unique session tokens or API keys  Average TTFHW: the average time to first hello world (TTFHW) metric  Maximum TTFHW: the maximum time to first hello world (TTFHW) metricYou can also add custom metrics by selecting a new data field or specifying a custom formula that references other metrics.Create Custom MetricYou can create custom metrics in two ways:  Add another data field and specify how to compute the metric from the field.  Add a custom formula that computes a metric from other metrics.Add Another Data Field  Select + Add Metric and then select { } Select Field.    Select an event field from the Select a field list.      Select a computation method for the values of the event field.    The computation methods available depend on the data type of the field. For example, numeric types have the following computation methods available:          avg      min      max      percentiles      distinct      Add a Custom FormulaMoesif allows you to create a custom arithmetic formula to use the values from other metrics or segments that you’ve defined.Moesif assigns a unique letter to each metric you plot. You can then reference those letters to build an arithmetic expression that computes a custom metric. You can also refer to segments in the custom formula as well by using the segment name.The following example defines the custom metric formula b/a where a corresponds to a Unique Users metric and b corresponds to an Average TTFHW (time to first hello world) metric.To use segments as part of your formula, use the syntax SEGMENT_NAME.METRIC_LETTER.For example, if you have two segments API and All, and a metric a, you can define the formula (API.a/All.a)*100.To add a custom formula and plot its metric, follow these steps:  Select + Add Metric and then select Enter Formula.    Enter your formula. The following operators are supported for a formula:          Addition (+)      Subtraction (-)      Division (/)      Multiplication (*)      Exponentiation (^)      Square root (sqrt)      Natural logarithm (ln, log)      Base-10 or common logarithm (log10)      Base-2 or binary logarithm (log2)      Change Chart StyleYou can change how Moesif plots segmentation charts and toggle from one style to another. This allows you to view the metrics in multiple ways.The following styles are available:  Bar chart  Line chart  Pie chart  TableBar ChartA bar chart represents data with rectangular bars. The height of each bar corresponds to a quantity of the metric data and each bar belongs to a category. The categories come from the grouping you specify and each bar represents a single category. In the example Composition analysis, we plot the Unique Users metric in a bar chart and group the data by UTM sources. Therefore, each bar represents data for a UTM source like Facebook and LinkedIn. The height of each bar changes in proportion to the number of unique users associated with a UTM source.Line ChartA line chart plots your metrics by connecting the data points with lines. Each data point represents a value of the metric at a specific time period. Line charts help you visualize and understand how metrics change over time.Pie ChartPie chart uses a circular graph to represent how a total amount of your data is divided into categories. Each radial portion of the chart corresponds to the amount that belongs to a category. Pie charts help you visualize how each category or group contributes to the entirety of your data. For example, a pie chart can help you visualize how your customers are using your products across different countries and regions.TableThe table view shows the metrics data in a tabular format, similar to a spreadsheet.Metric Configuration and Shortcuts MenuFor each metric in the Metrics pane, select ⋯ Configuration and Shortcuts to further customize your chart.Custom NameSelect the Custom Name checkbox to set a custom name for the metric.Combo ChartsA combo chart combines line and bar charts. Combo charts allow you to represent multiple metrics in the same chart for better visualization and comparison.To create a combo chart, open the ⋯ Configuration and Shortcuts menu and then select Combo Chart.Customize Vertical AxisWhen you have more than one metric in a chart, you may want to use independent Y-axes for each. Metrics on separate Y-axes can vertically scale independently of one another within the same chart. This proves useful in scenarios such as comparing values at very different scales.To use a different Y-axis for your metric, open the ⋯ Configuration and Shortcuts menu and then select Assign to Y-Axis. The following Y-axis types are available:  Y-Axis A  The default Y-axis.    It’s always on the left side of the chart. If you select a different Y-axis for a metric, the Y-axis appears on the right side. When you select the Log Scale option, it only affects  this default Y-axis.    Y-Axis B  Expresses a metric with a decimal ratio as a whole number percentage—for example, 0.5 as 50%. This axis multiplies the values by 100 and adds a percentage sign to the chart units.  Y-Axis C  Adds a new Y-axis on the right side of the chart based on the metric values.  Y-Axis D  Adds a new Y-axis on the right side of the chart based on the metric values.Duplicate a MetricSelect Duplicate to duplicate the corresponding metric in the same chart.Stacking PlotsYou may have multiple groups that you have used to break down your data. Then you can combine the group plots by stacking them on top of one another. This generates a more composite visualization of your composition data.In our example composition analysis, let’s change it so that we also get a breakdown of Enterprise users based on the SDKs they use to interact with the API. To do that, we define the filters and chart settings the following way:We can now select Stacked to generate a stacked chart.Without stacking plots, the chart looks like this, with several bar plots representing different SDKs:Merging GroupsSimilar to stacked plots, if you have more than one group, you can merge two groups into a single key by selecting Paired Keys. If you have sparse data, this can help you generate better visualizations.AI Explain : Use AI to Get Insights About Composition AnalysisAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about retention analytics data.In a Funnel workspace, select Ask AI to open up the interface. To get started, you can choose from the sample prompts. Otherwise, type in your query and press Enter.Save and ShareMoesif gives you several options to share a Composition analysis workspace. Before you can share, you must first save the workspace to a dashboard.After saving, follow the instructions in Sharing Workspaces to share your workspace.Download Chart DataYou can download your Composition analysis data in CSV format for further processing in tools like Microsoft Excel:  Select Export.  Select Download Chart - Current View or Download Chart - All Terms.",
      "url": " /user-analytics/composition/",
      "author": "Sakib",
      "categories": "User Composition, Company Composition"
    }
    ,
  

    "user-analytics-saved-cohorts": {
      "title": "Saved Cohorts",
      "content"	 : "This document explains user and company cohorts in the Moesif’s User and Company Analytics suite.Moesif supports cohorts for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.A saved cohort represents a dynamic list of users or companies that match some specific criteria. That criteria can consist of specific user or company properties, or based on what the user or company performs in terms of API calls and custom actions. Because of the dynamic nature of these lists, Moesif continuously updates them in the background automatically.Here some examples of cohorts:  Users who are exceeding rate limits in the last 24 hours  Users who accessed your API with over 10 distinct IP addresses per hour  Companies who have unpaid invoicesSaved cohorts serve as powerful tools in analyzing customers and APIs. You can use them as targeting criteria through Moesif in many ways. For example:  Trigger behavioral emails to warn customers of issues like rate limits.  Block API abusers and threats from accessing your API.  Dynamically sample customers based on their behavior.Before You StartEvents may take up to 20 minutes to show up in the user analytics screens. If your data has not appeared, make sure you wait until Moesif has completed the instrumentation process and loaded the data.Creating a CohortYou can create a cohort in several ways.From the Create New Dialog  Log into Moesif Portal.  Select + Create New in the navigation menu.  Select User Cohort or Company Cohort.From Users or Companies Screen  Log into Moesif Portal.  Select Users or Companies and then select User Cohorts or Company Cohorts in the navigation menu.  Select + Cohort in the Users or Companies screen that appears.From a Lookup or Composition Analysis Screen  Go to the Lookup analysis screen or Composition analysis screen.  Define the filters and criteria for your Lookup or Composition analysis.  Select Create Cohort.ExampleCohorts support filtering on both user and company fields along with the events that a user or company performs.Event fields also support how often the user or company performs events within a period.For eample, let’s say an API has a response header that keeps track of rate limits. Therefore, you can create a cohort for users who were close to API rate limits at least 5 times in the last 24 hours.To do so, we follow these steps:  Add an event filter Response.Headers.X-Ratelimit-Remaining &amp;lt; 10.  Select At Least and then enter the number 5. These specify the measurement policy of the number of times the event occurs.  Select Last Week as the time period.After defining these criteria, you can see a preview of all users that match your criteria in tabular format. You can go further with your criteria and add more filters. For example, you can add a user filter to only include your non-Enterprise plan users.Finally, enter a name for your cohort. Then select Create Cohort. A confirmation dialog appears. Select Create Cohort again to create the cohort.Filtering on Event TimeYou can specify the period of time for your event filter criteria. For example, if you want to create a behavioral cohort for all users who performed an event in the last month, select Last Month from the time span dropdown menu.If you want more precise control, use the relative date range or absolute date range options.The cohort may take up to 15 minutes to process before Moesif adds the matching users or companies to automation workflows like Behavioral Emails and sampling.Filtering Based on Billing Period or Term For CompaniesYou can also filter events based on billion period or term of companies by selecting one of these values from the time span dropdown:  Subscriptions’ Current Month  Includes events that have occurred in the subscription’s current monthly billing period. For billing periods longer than a month, Moesif only looks at the current month.  Subscriptions’ Last Month  Includes events that have occurred in the subscription’s last monthly billing period that has already passed. For billing periods longer than a month, Moesif only looks at the current month.  Subscriptions’ Current Period  Includes events that have occurred in the subscription’s current billing period. For quarterly or yearly billing periods, this option shows all of the events within those time periods. For monthly billing periods, it shows the same results as the Subscriptions’ Current Month option.If you’re using Moesif for API monetization, these options can help you implement powerful governance rules from cohorts that control access to your API based on your customers’ subscription terms. For example, you may create a governance rule where a customer’s subscription tier only allows them to consume 10,000 API calls per month. By selecting the Subscriptions’ Current Month option, you can create a cohort to make sure that customers stay within their limits during their monthly billing periods.Accessing saved cohortsTo access the saved cohorts, select Users or Companies and then select User Cohorts or Company Cohorts in the navigation menu.Select a cohort name to open the edit screen for that cohort. From there, you you can make edits to the cohort and then select Save Cohort to save it.Using cohortsYou can use cohorts across different features and tools in Moesif, specially the automation features like Behavioral Emails.For example, you can set up a recurring email that reminds users they have rate limit issues. The earlier cohort example created a cohort that defines users who’ve reached their rate limits. When you create a behavioral email, you can select that cohort as the email recipient.Advanced FeaturesNumeric AggregationsBesides equality, event fields also support aggregations and computations methods like averaging, summation, and so on. For example, you can create a cohort of users who’s average latency goes over 1 second.After selecting the event field, the Select operator… field lists all the available computation methods available to you for that field.You can also specify how Moesif quantifies events by defining the threshold on a custom aggregated field. The default aggregation takes into account the number times an event occurs. But you can specify a custom one by selecting ⋮ Customize Threshold.In the dialog that appears, specify your custom aggregation and then select Apply. If you want to go back to the default, select Reset to Occurrence Count.Grouping filtersYou can also group filters together, enabling order of operations and logic among the filters. To chain filters together, use the Where, OR, and AND clauses.For example, let’s say you want to match users who fall into one of these criteria:  Received 500 Internal Server Error status code only when they placed a buying order.  Made an explicit API call to decline.You can think about combining event filters in two ways:  Customers who performs an event matching both X AND Y, in a single event.  Customers who performs an event matching X AND an event matching Y. This means multiple events.Filters within the same group matches against the same event. Moesif outlines the group in a box in the UI. Separate groups match against separate events.1. Customers Who Perform an Event Matching Both X AND YTo find a single event that matches multiple criteria, make sure to keep the properties in the same group. Remember that Moesif outlines the group in a box in the UI.For example, you may want to display all users who made an API call that returned 400 Bad Request error response AND the route of that API call was either /purchases/:id/decline OR /purchases. This means matching multiple properties of the same event. Therefore, the query looks like this:2. Customers Who Perform Event Matching X AND an Event Matching YIf you want to match across independent events a user performs, add multiple OR or AND condition boxes. Each filter box then contains the filters for each individual event criteria.For example, you may want to match against both an API Call and an Action. Let’s say you want to show all users who fall into the following criteria:  Made API calls to either /purchases/:id/decline OR /purchases_ URI route that returned 200 OK responses.  AND performed a custom action where Action Name is Signed-In.The query for this looks like the following:Select Fields to DisplayTo display more data fields in the Cohort data table, select Select Columns and specify the fields. For example, you can select Geo IP.Country as your custom field. Now you can see the respective countries of the matching customers in the Cohort table.Any columns you add to the table also appears in a bulk export.Custom ColumnYou can also add a custom column containing calculated data from the table by selecting Add equation.A modal then appears where you need to enter the details of your custom column formula.The formula details include the following:  An optional name for your formula.  An operator that for the calculation method.  Fields or constant values as operands.For example, the following formula calculates the difference between the first and the last seen times for customers. This data now appears in the column Activity Period in the Cohort data table.If your field is missing, add it via the Select Fields button first. Also, please note the table formulas are based on values currently in the table not based on an queries from database.Deleting a Custom ColumnTo delete a custom column, select X in the column header.Sorting the Results  Select the field you want to sort on.  Select the sort direction, ascending or descending.Timestamp ValuesIn the Cohort data table, Moesif parses the timestamps into human-readable format in your timezone. To display the raw timestamp values in ISO 8601 format instead, select Original Raw Values.Exporting Cohort DataBulk Export is an enterprise feature that provides direct access to your data stored in Moesif. It allows you to efficiently retrieve hundreds of millions of User and Company data from Moesif and quickly load them into data warehouses like Snowflake, Redshift, and BigQuery.You can use Bulk Export both from Moesif UI in the browser and Moesif Management API. Using the Management API, you can set up recurring bulk exports for different use cases—for example, a data pipeline that feeds your data in Moesif into a data warehouse like BigQuery.Supported Export File TypesMoesif supports the following file types for bulk export:  CSV  CSV files have some of the widest support for many of your favorite tools. This makes it ideal for exporting user and company data to your CRM and more.  JSON  JSON has become a standard for parsing data quickly for scripting purposes. Many fields in Moesif are deeply nested, making JSON an ideal choice.  Parquet  Parquet is an open source column-oriented data format that can make analysis on a subset of columns faster when compared to loading the entire file in memory. Your schema is directly embedded in the file. This can help SQL warehouse-like tools that require strict schema enforcement.Filters for Exported DataBulk exports adhere to any filters that you have applied to define the cohort. Make sure you apply the filters you require before exporting.Export Cohort Data from Moesif PortalTo export Cohort data from Moesif Portal, follow these steps:  Open the Cohort you want to export.  Select Export and then select Bulk Export.  Specify the email address where you want Moesif to send the export file.  Select the export file format.  Select the fields you want to include in the export.  Select Start Export.The time it takes to export your data depends on the number of customers that match the cohort and the number of fields you select.Export Cohort Data using Moesif Management APIIf you want to trigger export jobs using Moesif Management API, contact your account manager or reach out to support for instructions.Fields SelectionIf you don’t want to include all data fields of the matching customers in the bulk export, specify the fields you want before selecting Bulk Export. Otherwise, select All Fields in the Bulk Events Export dialog.",
      "url": " /user-analytics/saved-cohorts/",
      "author": "Derric",
      "categories": "Saved Cohorts"
    }
    ,
  

    "user-analytics-user-notifications": {
      "title": "Cohort Notifications",
      "content"	 : "With User (and Company) Notifications, you can receive notifications when customers match specific behaviors. This might include scenarios such as when a user has made their first API call or when a user hasn’t sent any traffic through your APIs after X number of days.The User and company notification capabilities are all driven through a saved cohort. Moesif will send customer notifications specifying which users (or companies) were added and removed to a saved behavioral cohort that you created. A saved cohort is a dynamic list of customers that match your specific criteria. An example behavioral cohort would be New users who made their first API call today which would create a group, or cohort, of users that are new to the platform and sent their first API call through in the last day.Saved cohorts drive a massive amount of functionality within Moesif. Here are a few example use cases of how cohorts can be used:  Trigger marketing automation workflows such as when a customer makes their first API call.  Receive Slack notifications on struggling customers with issues and proactively reach out.  Get email update when customers stop sending trafficAlert Rules vs Cohort NotificationsFor background, Moesif has two different notification systems that can be used for different use cases. This page is focused on User Notifications.The differences between the two are described below:  User Notifications will send a list of users (or companies) that match your specific behavior such as customers who made their first API call. There are no metrics involved, rather the notification is a list of customers.  Alert Rules monitor a time-series metric such as average latency or request volume in real-time and alerts you when the metric deviates from what you expect. The alert can be triggered when the metric passes a static threshold or when Moesif detects an anomaly. Alert rules can also be multi-dimensional which allows you to track metrics on a per customer level.            Name      Type      Primary User      Use Case      Frequency              User Notifications      User behavior centric      Marketing &amp;amp; Customer Success      Receive notifications on customers who exhibit certain behaviors      Whenever customer added to a cohort (sent as a batch)              Alert Rules      Time-series centric      Product &amp;amp; Engineering      Receive alerts when a metric has abnormal behavior or passes a threshold      Real-time or specific intervals      How to Set Up Cohort Notifications1. Create a Saved CohortIn the left sidebar menu, chose Users or Companies. In the User/Company Lookup screen, set the filters to match the criteria of the target customers you’re interested in. For example, if you’re interested in receiving notifications when customers made their first API Call today, but they also saw 400 errors, we would add the following filter criteria:Users who’s first_seen_time is today and Who performed an API Call where response status is 400To create the cohort, click the Create Cohort button in the top right. In the modal that appears you will give a name to the cohort in the Cohort Name field and verify the filter set is correct. Once complete, click the Create Cohort button in the bottom right of the modal to create the cohort. Once created, you’ll be able to use this cohort to drive notifications.For more instructions on creating saved cohorts, check out the saved cohorts documentation.2. Create the Cohort NotificationWhen a new cohort is created, you will be brought to the saved cohort page. A modal will appear that allows you to easily add automated flows built on top of the saved cohort, including cohort notifications. To add a cohort notification from here, click on the __Notification/Webhook link.Alternatively, if the cohort is already created, you can access it by going to the User/Company Cohorts menu item, underneath Users/Companies in the left-side menu. After selecting the cohort, on the Cohort Details screen, you’ll click the edit/pencil icon beside the Notifications entry in the Cohort Info located on the right side of the screen.In the Set Up User Cohort Notification modal that appears, fill out the fields based on your needs for this specific notification.The fields to fill in/select include:  Send to - This is the channel(s) that the alert will be sent to when it fires. Currently, Webhooks, Slack_, and Email are supported channels. See Adding a channel below for details on adding a new channel.  Send when - This can be set to specify when the alert should fire. Possible values to select include User Joins Cohort, User Leaves Cohort, or Both.  Includes custom fields when joining - This setting allows you to add fields to the data that gets sent in the alert when a user joins the cohort.At the bottom of the modal you can specify the frequency that the notification will get sent sent. By checking off Once Only, all alerts within 5 minutes will be aggregated into a single notification. This can help to keep the noise down from multiple notifications spamming the selected channel.You’ll also be able to create a resend interval by selecting the User eligible for resend checkbox and specifying a time interval.Once the fields are filled out, click Save in the bottom-right corner of the modal.Adding a ChannelIn the Send to field in the Set Up User Cohort Notification modal you can select a channel to send notifications to. To add a new channel, in the Send to field, select the New channel… option in the dropdown.In the Create Notification Channel modal that appears, you can create a new channel to send notification to.Currently, Webhooks, Slack, and Email are supported channels that can be added. In the modal, you’ll need to fill out the following fields:  Channel name - the name of the channel you are adding  Channel type - the channel you’d like to send it to (email/Slack/webhook)  Email Address/Slack Webhook URL/Webhook URL - the email address or webhook URL  Method (if Webhook is selected) - specify whether the webhook request will be a POST or PUT  Notification Throttle - used to set throttling on the notifications to make sure notification don’t get too noisyReceiving NotificationsYou’ll receive notifications as customers are added or removed from your cohort based on their behavior. To avoid sending too many notifications, this will happen in batches (usually within 15 to 30 minutes).",
      "url": " /user-analytics/user-notifications/",
      "author": "Derric",
      "categories": "Saved Cohorts, Notifications, Updates"
    }
    ,
  

    "user-analytics-profile-view": {
      "title": "Profile View",
      "content"	 : "Profile View provides access to user and company account metrics in an easy and uniform fashion.You can customize Profile Views with a wide variety of metrics. Similar to Profile Dashboards, Profile Views also act as a form of a template and are specific to User and Company profiles. Any updates you make to a Profile View applies to all layouts of the same profile type.Customizing Profile ViewTo add, edit, or rearrange what appears in a Profile View, select the ⋯ More Actions dropdown and then select Customize Profiles’ Layout.The entire Profile View then becomes editable.In this mode, you can perform the following operations:  Add or remove columns.  Add or remove column fields.  Change column icons.  Rearrange fields and columns.After applying changes to Profile Views, select Save.The following sections discuss the customization operations in more details.Adding Profile View ColumnsYou can add additional columns by selecting + following the rightmost column.Select the initial field you want to add and the new column appears.Adding and Removing Profile View FieldsTo add a new field to a column, select + at the top of each column. Then select the field you want to add to the Profile View.You can remove any field by selecting X in the field tile.Change Profile View Column IconsYou can change the icons on any column. Select the the icon for the column you want to change and then choose an icon from the icon list.Rearranging Profile View Fields and ColumnsYou can rearrange the fields and columns in customization mode.To move a column or field, drag the six-dot icon in the column or field tile. When you drag a column or field tile to a new location on the dashboard, a blue line appeas to help you position the tile.Create Alert RulesYou can start creating alert rules for the user or company from their respective profile views.To create an alert rule, select ⋯ More Actions and then select Create Alert. THE Alert Rules screen appears. Moesif automatically creates an event filter with the corresponding user or company ID.Get User or Company DataThe Profile View of a user or company also gives you access to the user or company data in JSON format.You can can get this data in two ways:  From the Profile View page  To get the JSON data for a user or company in the Profile View, select ⋯ More Actions and then select Show JSON Data. A dialog appears containing user or company data in JSON.  Through Moesif Management API  To get the JSON data for a user or company through the Moesif Management API, select ⋯ More Actions and then select Get via API. A dialog appears with a generated cURL command similar to the following:    curl -X GET -H &#39;Authorization: Bearer YOUR_MANAGEMENT_API_KEY&#39; -H &#39;Content-Type: application/json&#39; -i &#39;https://api.moesif.com/v1/search/~/users/USER_OR_COMPANY_ID&#39;        You must replace YOUR_MANAGEMENT_API_KEY with your Management API key. The USER_ID corresponds to the user or company ID that Moesif automatically fills in for you.    To generate a Management API key , follow these steps:          In Moesif Portal, select the account icon to bring up the settings menu.      Select API Keys.      From the Management API Key section, select the read:user scope and optionally set the key’s expiration time.      Select Generate Token.      Profile DashboardProfile Views also contain profile dashboards. To view the dashboard, go to the bottom of a Profile View page.Billing UsageIn Company Profile Views, you can access billing usage statistics for the company in the Billing Usage tab at the bottom of the Profile View page.Billing Usage pane allows you to do the following:  Observe usage and corresponding billing data of a company for existing meters and subscriptions in graph and tabular formats.  View associated events.  Filter data by successful or failed reports.  Export billing usage data in JSON format.",
      "url": " /user-analytics/profile-view/",
      "author": "Dylan",
      "categories": "Profile View"
    }
    ,
  

    "user-analytics-csv-import": {
      "title": "Importing Customer Data from CSV",
      "content"	 : "A key component in leveraging metrics in Moesif is identifying calls by user and/or company. Using CSV import, you can enrich user and company data in Moesif with your business data. This allows you to import customer demographics, subscription status, or other business information readily available in another system, such as your customer relationship management (CRM) system.If a user or company already exists in Moesif, Moesif merges any new columns in your CSV with their existing profile. This means that you don’t need to worry about data duplication. But remember that the customer’s user ID and company ID, if configured, must match between the CSV and the existing data in Moesif.Importing Users Through CSV FileFollow these instructions to import user data using a CSV file.Step 1: Prepare the CSV FileCreate or generate a CSV file containing user attributes like name or job title. Follow this sample format:Make sure that your CSV includes a column with the label user_id. If you want to use behavioral emails or automatic enrichment features, the CSV must have an email column as well.Step 2: Import the CSV in Moesif  From Moesif Portal, select your account icon to bring up the settings menu.  Select Installation and then select Import Users/Companies.  In the Select Installation Option pane, select Import CSV.  In the Import CSV tab, make sure you select Track Users.  Lastly, either drag and drop your CSV file onto the screen or select Select A CSV File.After uploading the user CSV file, you can choose to either map the uploaded data fields to existing user profile fields or create a new field. To create a new field, enter the field name in the Moesif Field column fields and press Enter.In the following example, we create two new fields: metadata.title and metadata.org.Finally, select Import Users.Once the user import process completes, you can view the details of the newly imported users in the User Lookup table.To view the updated metadata fields, you can get the JSON data in the user profile page.Importing Companies via CSV FileFollow these instructions to import company data using a CSV file.Step 1: Prepare the CSV FileCreate or generate a CSV file containing company information. Follow this sample format:Make sure that your CSV includes a column with the label company_id. If you want to leverage Moesif’s automatic enrichment feature, set a company_domain column in the CSV file.Step 2: Import the CSV in Moesif  From Moesif Portal, select your account icon to bring up the settings menu.  Select Installation and then select Import Users/Companies.  In the Select Installation Option pane, select Import CSV.  In the Import CSV tab, make sure you select Track Companies.  Lastly, either drag and drop your CSV file onto the screen or select Select A CSV File.After uploading the CSV file, you can choose to either map the uploaded data fields to existing company profile fields or create a new field. To create a new field, enter the field name in the Moesif Field column fields and press Enter.In the following example, we create four new fields:  metadata.company_name  metadata.plan_name  metadata.employee_count  metadata.mrr.Finally, select Import Companies.Once the company import process completes, you can view the details of the newly imported companies in the Company Lookup table.To view the updated metadata fields, you can get the JSON data in the company profile page.",
      "url": " /user-analytics/csv-import/",
      "author": "Dylan",
      "categories": "User Analytics"
    }
    ,
  

    "user-analytics-filters-reference": {
      "title": "Reference: Analytics Filters",
      "content"	 : "This document provides reference documentation for Moesif’s User and Company analytics filters.Filter TypesThe available filters broadly falls into the following three categories:  User filters  Company filters  Cohort history filters  Subscription Filters  Event filtersYou may have more filters available to you outside this document’s scope. For example, for GraphQL APIs, Moesif parses GraphQL queries and automatically generates a secondary set of filters called GraphQL Query filters. For more information, see API Protocol Support.Search FunctionTo enter a custom query expression, select the search as the filter function. This function allows you to search on single terms within your text fields such as a title or description field.The search function supports the following operators:-+ to perform a logical AND operation among the search terms.  | to perform a logical OR operation among the search terms.  - performs a logical NOT operation and negates a single search term.The search function also supports the following special characters:-&quot; wraps a set of search terms.  * wildcard operator to use at the start or end of any search term.  ( and ) to specify operator precedence.For example, if you want to only match against URI Route that are not /esignature/, then enter -&quot;/esignature/&quot; as the search term.User FiltersContains filters to query on user analytics and data.Geo IPAllows you to filter by geographic location data associated with the user:  City  Country Code  Country  Region  TimezoneUser AgentContains filters to query user agent data associated with the user:  Build  Device  Major  Minor  Name  OS Major  OS Minor  OS  PatchEnrichmentAllows you to filter on demographic enrichment data that you have attached on user profiles.  Moesif Enterprise supports demographic enrichment for companies that allows you to add demographic data to customers. For more information, contact us.CohortAllows you to filter on saved cohorts for companies.CreatedThe time you created a user profile in Moesif.First Seen TimeThe first time a user accesses your product.Last Seen TimeThe last time a company used your product.Modified TimeThe last time a user profile was modified.TTFHWThe Time to First Hello World (TTFHW) metric for a user.User EmailLets you filter by associated user’s email after setting it in the user metadata.NameLets you filter by associated user’s name after setting it in the user metadata.User Phone NumberLets you filter by associated user’s phone number after setting it in the user metadata.MetadataUser demographics or other properties you store in the user metadata.Company IdAllows you to filter for a specific customer by a company ID. This feature requires you to set up company identification using an SDK. Otherwise, you may not get accurate results.CompanyIf the user is a member of a company, this object contains the linked company’s data. For more information, see Company Filters.CampaignAllows you to filter by HTTP Referer data and various UTM parameters.By filtering on the Campaign object, you can track effectiveness of your acquisition channels. Moesif JavaScript browser SDK automatically sets this object, but not for server side SDKs.Auth/Session TokenAllows you to filter by all API keys or session tokens a users have used. For more information, see Identification of UsersInitial Request RouteInitial Request Route refers to the API endpoint the user sent their very first request to. You can use this filter to understand how customers started to use your product.Company FiltersContains filters to query on company analytics and data.Geo IPAllows you to filter by geographic location data associated with the company:  City  Country Code  Country  Region  TimezoneUser AgentContains filters to query user agent data associated with the company:  Build  Device  Major  Minor  Name  OS Major  OS Minor  OS  PatchEnrichmentAllows you to filter on demographic enrichment data that you have attached on company profiles.  Moesif Enterprise supports demographic enrichment for companies that allows you to add demographic data to customers. For more information, contact us.SubscriptionsAllows you to filter on subscription data for a company.If you monetize your API, you can use these filters to set up complex business logic for different billing providers such as Chargebee, Recurly, Stripe, and more.For information about the subscription filters available, see Subscription Filters.MetadataUser demographics or other properties you store in the company metadata.CampaignAllows you to filter by HTTP Referer data and various UTM parameters.By filtering on the Campaign object, you can track effectiveness of your acquisition channels. Moesif JavaScript browser SDK automatically sets this object, but not for server side SDKs.Auth/Session TokenAllows you to filter by all API keys or session tokens associated with the company. For more information, see How to Track CompaniesCohortAllows you to filter on saved cohorts for companies.Company DomainLets you filter by company website domains after setting them in the company metadata.Company IdAllows you to filter by company IDs.This feature requires you to set up company identification using an SDK. Otherwise, you may not get accurate results.Initial Request RouteInitial Request Route refers to the API endpoint the company sent their very first request to. You can use this filter to understand how customers started to use your product.CreatedThe time you created a company profile in Moesif.First Seen TimeThe first time a company accesses your product.Last Seen TimeThe last time a company used your product.Modified TimeLast time you modified a company’s metadata through UI or API.TTFHWThe Time to First Hello World (TTFHW) metric for a company.Cohort HistoryThe Cohort History filters allow you to filter on user or company cohorts and the time when users or companies join or leave cohorts. It contains the following filters:  Cohort History.id  Cohort History.last_join_time  Cohort History.last_leave_timeSubscription FiltersThe Subscriptions filters allow you to filter on various subscription-related data like subscription status, provider, and so on. You can access these filters by selecting Company.Subscriptions.Subscriptions.balanceAllows you to filter on subscription balance data. The following filters are available:  Subscriptions.balance.available_balance  Subscriptions.balance.current_balance  Subscriptions.balance.has_balance_transaction  Subscriptions.balance.pending_activity  Subscriptions.balance.sequence_idSubscriptions.cancel_timeThe cancellation date for a subscription.Subscriptions.collection_methodHow Stripe processes payments for subscriptions. Corresponds to Stripe collection_method.Subscriptions.company_external_idThe associated Company ID.Subscriptions.createdThe timestamp when the subscription was created.Subscriptions.currencyThe associated currency for a subscription.Subscriptions.current_period_endThe timestamp marking the end of the current subscription period.Subscriptions.current_period_startThe timestamp marking the start of the current subscription period.Subscriptions.internal_modified_timeThe timestamp when the subscription changed in Stripe, for example, changed to an active status from trial.Subscriptions.itemsAllows you to filter on various subscription items data, for example, Stripe Subscription Items data. The following filters are available:  items.created_at  items.item_price_id  items.plan          items.plan.created_at      items.plan.id      items.plan.name      items.plan.provider      items.plan.status        items.price          items.price.created_at      items.price.currency      items.price.id      items.price.name      items.price.period_units      items.price.period      items.price.plan_id      items.price.price_in_decimal      items.price.pricing_model      items.price.provider      items.price.status      items.price.tax_behavior      items.price.tiers                  items.price.tiers.up_to                    items.price.transform_quantity                  items.price.transform_quantity.divide_by          items.price.transform_quantity.round                    items.price.usage_aggregator        items.price_id: the price that the subscription is associated with  items.status: the price that the subscription is associated with  items.subscription_item_id: the unique identifier for the item as a subscription can contain multiple items  items.unit_of_measure: the unit of measure for the price if the subscription is based usage-based billing.Subscriptions.metadataThe metadata associated with a subscription.Subscriptions.modified_timeThe timestamp when the subscription changed in Moesif.Subscriptions.payment_statusThe payment status of a subscription.Subscriptions.providerThe subscription provider, for example, Stripe.Subscriptions.start_dateThe date when the subscription was first created. It might differ from Subscriptions.created due to backdating.Subscriptions.statusThe status of the subscription:  active  canceled  pending  trialing  draft  futureSubscriptions.subscription_idThe ID of the subscription.Event FiltersThe event filters allow you to filter on event data.These filters fall into four catagories:  Request filters  Response filters  Metadata filters  Common filtersRequest FiltersRequest filters allow you to filter on HTTP request data including headers.Request.Geo IPAllows you to filter by geographic location data with the following filters:  City  Country Code  Country  Region Code  Region  TimezoneRequest.User AgentContains filters to query user agent data:  Build  Device  Major  Minor  Name  OS Major  OS Minor  OS  PatchRequest.BodyContains filters to query data from a HTTP request body.Request.URI SegmentsAllows you to filter on URI segments. Moesif assigns zero-based numbers to the URI segments. Therefore, the first URI segment has the number 0, and so on.Request.HeadersAllows you to filter on HTTP request headers.Request.API VersionIf you configured the API version in your Moesif server integration, you can filter on the version.Request.Content LengthCorresponds to the Content-Length HTTP request header.Request.Content TypeCorresponds to the Content-Type HTTP request header.Request.IP AddressThe IP address of the user agent making a request. Moesif only supports IPv4 addresses.Request.TimeThe request time.Request.URI RawThe raw URI that was requested.Request.URI RouteThe path components of the URI—for example, https://myblog.com/posts contains the /posts route.Request.Verb/MethodAllows you to filter on the HTTP request methods.Response FiltersResponse filters allow you to filter on HTTP response data including headers.Response.BodyContains filters to query data from a HTTP response body.Response.HeadersAllows you to filter on HTTP response headers.Response.Status CodeAllows you to filter on the HTTP response status codes.Metadata FiltersThe Metadata filter allows you to filter on custom metadata you set using event metadata.Common filtersThe following common filters are available outside the preceding three event filter types:TagAllows you filter by event tags.Action NameLets you filter by custom actions.Auth/Session TokenThe authentication or session token used when making API calls—for example, credentials in the Authorization HTTP request header. For more information, see Identification of Users and How to Track Companies.Duration (Milliseconds)Lets you filter by the API call duration in milliseconds. The elapsed duration means the time elapsed between the API request and the server response.idMoesif assigns a unique ID to each API call called an event ID. If you know the event ID—for example, you can use it here as a filter.Event TypeAllows you to filter by the event type: API Calls or Actions.Request DirectionThis filter applies to API Calls only and allows you to filter by the direction of API requests.A value of Incoming shows only API calls to your own services you provide. A value of Outgoing only shows API calls going out to a third-party service.",
      "url": " /user-analytics/filters-reference/",
      "author": "Sakib",
      "categories": "User-Analytics, Company Analytics"
    }
    ,
  

    "user-analytics-user-notifications": {
      "title": "Cohort Notifications",
      "content"	 : "Moesif supports notifications through saved cohorts for both Users and Companies. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.With User and Company Notifications, you can receive notifications when customers match specific behaviors. This might include scenarios such as when a user has made their first API call or when a user hasn’t sent any traffic through your APIs after a definite number of days.Saved cohorts power all User and Company notification capabilities. For example, let’s say you create a cohort named “New users who made their first API call today”. This creates a group, or cohort, of users who make their first API call today. Whenever a new user signs up for your product and makes their first API call, Moesif adds that user to the cohort. If you configure notifications in your cohort, Moesif notifies you whenever Moesif adds a new user to the cohort, or removes a user from the cohort.Saved cohorts drive a massive amount of functionality within Moesif. The following example use cases demonstrate how you can use cohorts:  Trigger marketing automation workflows such as when a customer makes their first API call.  Receive Slack notifications on struggling customers with issues and proactively reach out.  Get email update when customers stop sending traffic.Alert Rules versus Cohort NotificationsMoesif has two different notification systems that you can use for different use cases. This document focuses on User Notifications.Let’s discuss the differences between these two systems:  User Notifications sends a list of users or companies that match a specific behavior according to your definition. For example, customers who made their first API call. The notification doesn’t involve any metrics, rather the notification contains a list of customers.  Alert Rules monitor a time-series metric such as average latency or request volume in real time and alerts you when the metric deviates from what you expect. You can trigger the alert when the metric passes a static threshold or when Moesif detects an anomaly. Alert rules can also work multi-dimensionally that allows you to track metrics on a per-customer level.The following table further illustrates the differences:            Name      Type      Primary User      Use Case      Example Metrics      Frequency              User Notifications      User behavior centric      Marketing and Customer Success      Receive notifications on customers who exhibit certain behaviors      Whenever Moesif adds a customer to a cohort (sent as a batch)                     Alert Rules      Time-series centric      Product &amp;amp; Engineering      Receive alerts when a metric has abnormal behavior or passes a threshold      Real-time or specific intervals             How to Set Up Cohort NotificationsStep 1: Create a Saved CohortFollow the instructions in Creating a Cohort to create a cohort.Step 2: Create the Cohort NotificationAfter you create a saved cohort, select Notification ✐ in the Cohort Actions pane.In the Set Up User Cohort Notification dialog that appears, fill out the details of your notification:  Recipient  Select a notification channel in the Send to field to specify where you want to send the notifications to. The following channels are supported:          Email      Slack      Webhooks        For more information, see Adding a channel.    Notification trigger criteria  In Send when, select the condition when you want Moesif to send notifications:          When user joins cohort.      When user leaves cohort.      When user either joins or leaves cohort.        Custom data in notifications  To include custom data fields in notifications, specify them in Includes custom fields when joining.  Notification frequency  In the last two configuration options, you can specify the frequency at which Moesif sends notifications:          By selecting the Once Only checkbox, Moesif aggregates all alerts within 5 minutes into a single notification. This can help you keep the noise down from multiple notifications spamming the selected channels.      If you want to receive notifications each additional time a user enters or leaves a cohort, select the User eligible for resend checkbox and specify a time interval.      Finally, select Save to finish your notification configuration for the cohort.Adding a Notification ChannelIn configuring notification for a cohort, you have to select a channel in the Send To field to send cohort notifications to. A channel defines communication method to receive notifications. Notification channels make it easier to ensure the right people receive the right notification alerts. Moesif supports the following channel types for cohort notifications:  Email  Slack  WebhooksTo add a new channel, in the Send to field, select New channel…. The Create Notification Channel dialog appears where you need to fill in the details of the notification channel.Channel NameGive your channel a friendly name such as Support Team or Backend Alerts. If you create multiple channels, this helps identify the audience.Channel TypeSelect the type of channel you want to create. Depending on the type you select, additional input fields may appear such as Slack webhook URL or email address.The following channel types are supported:  Email  Enter your email address of choice where Moesif sends email notifications to.    Add team@moesif.com to your address book to ensure email notifications don’t land in your spam folder.    Slack  Moesif routes Slack alerts to a specific Slack channel. You must reate a Slack hook URL by following Slack’s Incoming WebHooks instructions.. Then paste your Slack hook URL in the Slack Webhook URL field.  Webhook  To receive notificaiton through a webhook, enter your webhook URL and select the corresponding HTTP method you want to allow.    Webhooks enable leveraging of Moesif’s alerting infrastructure to trigger automated workflows in your infrastructure unlocking a large variety of use cases. This allows you to trigger workflows for consumption-based billing, marketing automation, and more, all from customer API usage data in Moesif.    To authenticate webhook requests as coming from Moesif, we strongly recommended that you add a secret key in a HTTP request header.For security, Moesif only allows webhooks protected by HTTPS.  Notification ThrottleSet a reasonable throttle for this alert. This prevents spams with a storm of alerts. After Moesif sends the first notification, Moesif silences additional alerts. You can still see silenced notifications within the Alert History page.Moesif has a correlation engine which detects related anomalies or triggers and consolidates them in the same notification.Throttling only impacts separate notifications.Receiving NotificationsYou receive notifications as Moesif adds or removes customers from your cohort based on their behavior. To avoid sending too many notifications, this  happens in batches, usually within 15 to 30 minutes.",
      "url": " /user-analytics/user-notifications/",
      "author": "Derric",
      "categories": "Saved Cohorts, Notifications, Updates"
    }
    ,
  

    "user-analytics-sharing-workspaces": {
      "title": "Sharing Workspaces",
      "content"	 : "This document explains how to share a User or Company analytics workspace.This document also assumes you are familiar with Moesif User and Company Analytics suite. For an introduction, see Introduction to User and Company` Behavior.Moesif supports sharing both Users and Companies analysis workspaces. Unless this document states explicitly, it uses the term user to represent both Users and Companies for simplicity.Sharable Analysis TypesYou can share any workspace that contains one of the four user analysis types:  Lookup  Funnels  Retention  CompositionAccess Restriction and Policy ConstraintsBased on audience visibility and who you want to share a workspace with, Moesif User and Company Analytics workspaces fall into two types:  Private  TeamFor more information, see Types of Workspaces.Share a WorkspaceBefore you can share a workspace, you must first save the workspace to a dashboard. Then follow these steps to share your workspace:  Select Share.      Choose the sharing type:    a. If you want to keep the workspace private and only accessible to you, select Private.    b. If you want to share with your team members, select Team. Moesif generates a link that your team members can use to access the workspace.  Access Shareable LinksTo access the shareable links for a workspace any time, follow these steps:  Go to the dashboard where you saved the workspace to.  Select the title of the workspace.  Select ShareDelete a workspace  Go to the dashboard containing the workspace you want to delete.  Select Delete.  Select Delete again to confirm your choice.API Access to Analytics DataIf you want to embed User and Company analytics data into custom solutions such as customer-facing applications, custom workflows, and so on, use Search API.Search API gives you access to analytics data so you can craft bespoke solutions that tell important stories about user and company behavior. The data youaccess through Search API automatically updates. So you don’t need to worry about your workflows getting stale.Search API is supported for Lookup and Composition analysis types.",
      "url": " /user-analytics/sharing-workspaces/",
      "author": "Sakib",
      "categories": "User Analytics, Company Analytics"
    }
    ,
  

    "user-analytics-using-search-api": {
      "title": "Using Search API",
      "content"	 : "This document explains how to access the data of a User and Company analyticsworkspace through API from Moesif Web Portal.This document also assumes you are familiar with Moesif user and company analytics suite. For an introduction, see Introduction to User and Company` Behavior.  You can access analytics data in three different ways from Moesif Web Portal:      Search API: enables you to consume your usage data using API within your applications to drive custom workflows.    Bulk Export: enables you to directly export your raw User and Company Lookup data to a data warehouse or other system.    You can also download chart data for User and Company Composition analysis.OverviewSearch API gives you access to your chart’s data using Moesif’s Management API. You send a POST request to the Management API with your Management API key as the Bearer token and the search definition for the data you want to extract. This returns a JSON object containing the chart data that you can display in a more customized format. The search definition uses the Elasticsearch Query DSL.Search API allows you to build custom solutions using your data, such as custom dashboards, reports, analytics, and so on.Applicable Metric TypesYou can access Search API for any workspace that contains one of these metric types:  Lookup  CompositionUse Search APITo use Search API, from the chart you want to access through the Search API, follow these steps:  Select Embed / API from the chart header.    Moesif generates a cURL command for your workspace criteria that you can use immediately to access the chart data. Moesif also gives you the HTTP request details so you can use HTTP clients like Postman.  Select the Curl Command tab for the cURL command and the HTTP Details tab for the HTTP request details.Search DefinitionThe search definition Moesif generates uses the Elasticsearch Query DSL. To access the search definition, see the HTTP request body from the HTTP Details tab or the generated cURL command’s -d (or --data)  argument value.This search definition accurately represents your desired report according to your chart’s filters and settings. You can quickly go back to your chart window, reconfigure, select Embed / API, and then select Search API to update your search. If you need help building a query for your business requirements, contact us.The Search API sends your request to the Management API’s events search endpoint. For more information, see the Management API searchEvents documentation.Learn More  Learn about different ways to share your workspaces.  Learn how to import customer data into Moesif.",
      "url": " /user-analytics/using-search-api/",
      "author": "Sakib",
      "categories": "User-Analytics"
    }
    ,
  

    "user-analytics-bulk-export": {
      "title": "Bulk Export",
      "content"	 : "Bulk Export is an enterprise feature that provides direct access to your data stored in Moesif. It allows you to efficiently retrieve hundreds of millions of User and Company Lookup data from Moesif and quickly load them into data warehouses like Snowflake, Redshift, and BigQuery.You can use Bulk Export both from Moesif UI in the browser and Moesif Management API. Using the Management API, you can set up recurring bulk exports for different use cases—for example, a data pipeline that feeds your data in Moesif into a data warehouse like BigQuery.Bulk Export is designed to move large amounts of your raw events for archival and data warehousing purposes. If you want to import a chart’s dataset into tools like Microsoft Excel and Google Sheets, download the chart instead for your Composition analysis.Supported Analysis TypesBulk export is available for User and Company Lookup analysis.Supported Export File TypesMoesif supports the following file types for bulk export:  CSV  CSV files have some of the widest support for many of your favorite tools. This makes it ideal for exporting user and company data to your CRM and more.  JSON  JSON has become a standard for parsing data quickly for scripting purposes. Many fields in Moesif are deeply nested, making JSON an ideal choice.  Parquet  Parquet is an open source column-oriented data format that can make analysis on a subset of columns faster when compared to loading the entire file in memory. Your schema is directly embedded in the file. This can help SQL warehouse-like tools that require strict schema enforcement.Event Filters for Exported DataBulk exports adhere to any filters that you have applied. Make sure you apply the filters you require before exporting.Export Lookup Data from Moesif PortalTo export Lookup analysis data from Moesif Portal, follow these steps:  Go to your Lookup workspace.  Select Export and then select Bulk Export.  Specify the email address where you want Moesif to send the export file.  Select the export file format.  Select the fields you want to include in the export.  Select Start Export.The time it takes to export your data depends on the number of customers you export and the number of fields you select.Export Lookup Data using Moesif Management APIIf you want to trigger export jobs using Moesif Management API, contact your account manager or reach out to support for instructions.Fields SelectionIf you don’t want to include all Lookup fields in the bulk export, you can specify the fields you want in the Lookup table before selecting Bulk Export. Otherwise, select All Fields in the Bulk Events Export dialog.",
      "url": " /user-analytics/bulk-export/",
      "author": "Sakib",
      "categories": "User-Analytics"
    }
    ,
  

    "user-analytics-ai-explain": {
      "title": "AI Explain",
      "content"	 : "This document explains how to use AI Explain in the Moesif’s User and Company Analytics suite.OverviewMoesif’s AI Explain feature is an GenAI-powered conversational interface that allows you to easily ask questions and gain insights about your analytics data. This feature is designed to enhance the accessibility of Moesif’s analytics for users with minimal experience or knowledge of analytics tools and related concepts. By simply typing a question, users can receive detailed insights, helping them make more informed decisions.AI Explain is available in for the following User and Company analysis types:  Funnels  Retention  CompositionHow It WorksAI Explain leverages Azure OpenAI, a leading large language model (LLM) platform, to process user questions and generate insightful responses. This integration allows AI Explain to provide quick and relevant answers based on your User and Company analytics data.Data UsageYour prompts and responses are not used for training or shared with others.To generate responses for your questions, Moesif sends the following event data to Azure OpenAI:  Event properties, including event IDs  Request and response data, such as headers and IP addressesGetting Started with AI Explain for User and Company AnalyticsTo start using AI Explain, navigate to any Funnel, Retention, or Composition analysis workspace and then select Ask AI. You can type your questions directly, and AI Explain uses the available event data to generate insightful answers for you. Whether you need to identify trends, pinpoint issues, or understand user behavior, AI Explain helps you get the answers without needing to dive deep into complex metrics or dashboards.Key Benefits  Accessibility  Makes Moesif’s analytics accessible to users without in-depth knowledge of analytics tools.  Efficiency  Saves time by providing direct answers, allowing you to avoid building complicated queries.  Insights on demand  Ask questions naturally, and get detailed insights about your customer analytics in real-time.Your Data and PrivacyMoesif is committed to maintaining the privacy and confidentiality of your data. While the event data and conversational history are sent to Azure OpenAI for processing, it is important to note that Azure OpenAI does not store, train on, or share your prompts, responses, or Moesif data with others. Your data remains secure and is used solely to provide responses to your queries.",
      "url": " /user-analytics/ai-explain/",
      "author": "Sakib",
      "categories": "User-Analytics, Company Analytics"
    }
    ,
  

    "api-monitoring": {
      "title": "API Monitoring &amp; Alerts",
      "content"	 : "Alert rules are a key feature for users looking to monitor and alert users about specific user and system conditions.About AlertingAlert rules enable you to monitor your APIs for issues impacting customers and be more proactive in ensuring a great customer experience.You can also leverage alerting to track metrics at a “per-customer” level. For example, you may want to get alerted when a new customer has a large drop in traffic orhas a large spike in average latency.  Since alert rules are scoped to the Moesif application, so you can have different rules for a Development vs a Production app.Alert Rules vs. Cohort NotificationsMoesif has two different notification systems for different use cases. This section is focused on Alert Rules.  Alert Rules monitor a time-series metric such as average latency or request volume in real-time and alerts you when the metric deviates. The alert can be triggered when the metric passes a static threshold or when Moesif detects an anomaly. Alert rules can also be multi-dimensional which allows you to track metrics on a per customer level. You can create an alert rule on any Time Series chart via the orange Alert button. See Creating Alerts.  User Notifications will send a list of users (or companies) that match your specific behavior such as customers who made their first API call. There are no metrics involved, rather the notification is a list of customers. You can trigger webhooks that drive marketing automation, consumption-based billing, and more.            Name      Type      Primary User      Use Case      Example Metrics      Frequency              Alert Rules      Time-series centric      Product &amp;amp; Engineering      Receive alerts when a metric has abnormal behavior or passes a threshold      Real-time or specific intervals                     User Notifications      User behavior centric      Marketing &amp;amp; Customer Success      Receive notifications on customers who exhibit certain behaviors      Whenever customer added to a cohort (sent as a batch)             If you’re not already familiar with API Analytics, you should first check out What does API Monitoring Mean for API Product ManagersAlert RulesAn Alert Rule contains the trigger conditions such as any filters and thresholds. Alerts triggered from an alert rule can be routed to any number of channels. This makes it easy to ensure the right people are notified of the right issues. Moesif supports both static alerts where you set a predefined threshold and dynamic alerts which leverage Moesif’s anomaly detection to automatically detect issues. See Creating Alert Rules.Notification ChannelsA channel is a communication method to receive notifications. Moesif supports the following channel types:  Email  SMS  Slack  PagerDuty  WebhookYou can create any number of channels in Moesif and may even have multiple channels with the same type. For example, you may have a Slack channel  #support-issues used by customer success and another Slack channel #backend-alerts used by engineering. See Creating Channels.AI ExplainAI Explain gives you an AI-powered conversational interface where you can ask questions and gain insights about your alerts. AI Explain greatly improves the accessibility of Moesif’s analytics for users who have minimal experience and knowledge about analytics tools and related concepts.To use AI Explain, you must have a paid Moesif plan in Growth or Enterprise. For more information, see Moesif Pricing.FAQI am not receiving any alertsAnswer: If you set the threshold to Dynamic, Moesif needs a couple days of data before a historical model of your API behavior is built. If you recently deployed Moesif or have low traffic volume (such as for develop environments), then we recommend static alerts. You can also reduce the sensitivity within the alert rule. Email us or adjust the detection sensitivity in dynamic alerts. Also, ensure you have an active channel under Alert Settings.I am receiving too many alertsAnswer: Your metric may be varying too much. This can happen when you have non-customer traffic such as health probes and bots that cause spikes in traffic. You can add more filters to your alert rule to focus only on the metrics that matter. If you are using dynamic alerts, you can also decrease the Abrupt spike detector if your time series is naturally varies a lot.",
      "url": " /api-monitoring/",
      "author": "Derric",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-creating-alert-rules": {
      "title": "Creating Alert Rules",
      "content"	 : "This guide assumes you are familiar with Alerts already. If not, please review API Monitors &amp;amp; Alerts.Example Creating an Alert RuleThe easiest way to create a new Alert Rule is to select + Create New and then Alert Rule from Customer Experience section.Alternatively, select Alert Rules in the navigation menu and then select + Alert Rule.You can create Alert Rules on any time series chart in Moesif.The following example walks you through creating a dynamic alert rule to detect abnormal spikes in API traffic for an embeddings AI API.  Select + Create New and then select Time Series to create a new Time Series analysis.  Configure your chart’s filters, metric, and time period for what you want to monitor.  Select Alert to open the alert configuration page.  Configure your alert in the Create Alert Rule pane.          Enter an alert name.      Specify the evaluation period and frequency  of your alert that dictates when Moesif evaluates the rule. By default, the  alert has the same evaluation period as the time interval of your time series chart.      Select the On checkbox to turn on the alert immediately after creating it.      Select Dyanamic Alert.      Specify the trigger condition by choosing a Direction. Since we want to   receive alerts when API traffic abruptly increases, select Increase.      Configure the detector sensitivity sliders.      Pick which channels to send notifications to.      (Optional) Specify a custom message that you want the alert to include when  it triggers and notifies you.        Select Create. A confirmation dialog appears detailing how the rule is triggered.Since it’s important to track each customer’s experience independently, the example uses Company.Company Domain to group customers by company domains.For more information about each of the steps in the example, see Alert Options and Alert Rule Settings.Alert OptionsChart FiltersAny filters you add to your time series chart also be applied to the alert rule. For example, to only alert whenthe response.status is 500 Internal Server Error, add a filter this way:Chart Group ByBy adding a group by to your chart, Moesif creates a multi-dimensional alert which means Moesif monitors each ofthe group by values separately. This makes it easy to create a single alert rule that monitors hundreds of different metrics withoutmanually creating hundreds of different alert rules. For example, you may want to track a metric separately for each customer or each URI route.Let’s say we want to get alerts when a specific customer has a spike in latency. The alert rule then looks like the following:The alert criteria will be presented in the red box shown above.Chart MetricMoesif monitors the metric plotted in the chart. You can select one of the predefined metrics or build your own bydefininig a custom metric.   For example, here we define a custom metric to get alerts on when a customer sends an unusually large amount of data to your API which may imply abuse or a hacker:In this case, we group by User.User Email so we can track each user’s upload amount separately.Alert Rule SettingsIn addition to the chart conditions rules, you must configure additional settings in the Create Alert Rule pane.Alert NameSelect a friendly name for your alert in the Name field. This name identifies an alert in emails and notifications.Evaluation Period and FrequencyAlerts require an interval for the metric aggregation. Real-time Rolling and Calendar-based Rolling indicates the evaluation period type for your alert.Use real-time rolling to set real-time alerts and calendar-based rolling to monitor long-term trends. For more information, see Real-Time Alerts   and Calendar Alerts.ChannelsSelect the channels you want to send the alert notifications to from the Send To field.A channel is a communication method to receive notifications and make it easier to ensure the right people receive the right alerts.Moesif supports the following channel types:  Email  SMS  Slack  PagerDuty  WebhookIf you already have existing channels, you can select them from here. Otherwise, select New Channel to set up a new channel. For more information about channels, see Creating Notification Channels.Alert TypeMoesif supports two types of alerts:  Static alert enables you to define a specific threshold for when to trigger an alert.  Dynamic alert leverages Moesif’s anomaly detection and triggers alerts when the metric deviates from the historical trend line.Static AlertStatic alerts serve as simple alerts that trigger when your metric reaches the threshold you specify for your metric.The alert triggers once your metric (such as Event Count) reaches your threshold.Static alert supports the following operators:  &amp;gt;  &amp;lt;  &amp;gt;=  &amp;lt;=  anyIf you want a recurring alert that triggers for every time interval regardless of metric value, select the any operator in Threshold.Dynamic AlertDynamic alert leverages Moesif’s anomaly detection that learns the trend line from historical data and alerts when the metric looks abnormal.Dynamic alerts can help you when the metric varies drastically that would normally make static alerts impossible.You can set Direction to monitor the important changes for your use case:  Increase alerts you when the monitored metric has an abnormal increase.  Decrease alerts you when the monitored metric has an abnormal drop off.  Both alerts you when the monitored metric has an abnormal change in either direction.When you combine dynamic alerts with Group By, Moesif monitors the trend line for each value separately. For example, let’s say you want to monitor when a customer has a drop-off in API traffic so customer success can preempt any customer churn issue. In this case, group by user.email and set the dynamic alert’s Direction to Decrease only. Moesif alerts you when a specific user’s API usage has a large decrease relative to the user’s historical trend line.Changing Dynamic Alert SensitivesMoesif recommends the default sensitivities to start. Adjust the sensitivity if you feel that you’re receiving too few or too many false alerts.You can configure how fast the detectors generate alerts by dragging the Metric Anomaly Detectors sliders left and right. If you’re receiving too many false alerts,drag slider left. If you want alerts for small deviations, drag the slider right.The following table summarizes the detectors:            Detector      Alert name      When to decrease sensitivity              Abrupt spike detector      SPIKE      Your API receives a low volume of traffic so small fluctuations in error rates throw off the spike detector.              Unusual change detector      RISE/FALL                     Slow trend detector      POSITIVE TREND      Your API has seasonal patterns—for example, an API only used during working hours that naturally has an increase in error rates at 9 AM.      Custom MessageUse the Custom Message field to add a custom message or note to your alerts. This is not supported for SMS messages.Advanced SettingsAdvanced settings enable you to tweak when Moesif sends or silences notifications. For example, once an alert rule is triggered, you may want to silence it for a short period of time to avoid too many notifications.  Silencing alerts  This setting allows you to silence any future notifications for the same alert rule for a specific period of time. This can help reduce the number of notificationsfor noisy alert rules.  Alert downtime  The downtime setting allows you to add a quiet period where during which Moesif doesn’t send any alerts. For example, if you have a cron job that performs some maintenance that brings down a service from 5 AM to 6 AM UTC everyday, you can set this schedule to avoid receiving false alerts.    To add a downtime, select Add Downtime and set values for the following fields:                            Field          Description          Example                          Start time          The start time for downtime window in 24-hour clock time.          05:00                          End time          The end time for downtime window in 24-hour clock time.          06:00                          Timezone          The timezone to use for the start and end time.          PDT                    ",
      "url": " /api-monitoring/creating-alert-rules/",
      "author": "Philip",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-creating-notification-channels": {
      "title": "Creating Notification Channels",
      "content"	 : "A channel is a communication method to receive notifications and make it easier to ensure the right people receive the right alerts. Moesif supports the following channel types:  Email  SMS  Slack  PagerDuty  WebhookYou can create multiple channels, even of the same type. In addition, you can route notifications from an alert rule to any number of channels.Creating a channelTo create a channel, follow these steps:  Select the account icon to bring up the settings menu.  Select Notification Channels. This shows you the list of channels you currently have for your application.  Select + Create Channel.You can also access notification channels when creating alert rules. In the Create Alert Rule pane, selecting Select a channel shows you the channels you currently have to send alerts to. To create a new channel, select  New Channel.Channel NameGive your channel a friendly name such as Support Team or Backend Alerts. If you create multiple channels, this helps identify the audience.Channel TypeSelect the type of channel you want to create. Depending on the type you select, additional input fields may appear such as Slack webhook URL or email address.The following channel types are supported:  Email  Moesif sends email notifications to your email address of choice. Moesif also includes context like a time series chart. This allows you to make a decision quickly on importance without logging into the Moesif web portal.Add team@moesif.com to your address book to ensure email notifications don’t land in your spam folder.  SMS  To receive SMS alerts, add your phone number. Moesif does not charge for sending text messages, but do reserve the right to cancel any account that abuses this policy. However, your mobile carrier may charge you for receiving text messages.  Slack  Slack alerts are routed to a specific Slack channel. To do so, create a Slack hook URL by following Slack’s Incoming WebHooks instructions.. Then paste your Slack hook URL in the Slack Webhook URL field.  PagerDuty  You can connect your Moesif account to your PagerDuty account to route alerts to it. This makes it easier to leverage PagerDuty’s platform to create complex incident responses and escalation policies.    To get started, see Moesif Integration Guide with PagerDuty.    Webhook  Webhooks enable leveraging of Moesif’s alerting infrastructure to trigger automated workflows in your infrastructure unlocking a large variety of use cases.This allows you to trigger workflows for consumption-based billing, marketing automation, and more, all from customer API usage data in Moesif.    To authenticate webhook requests as coming from Moesif, we strongly recommended that you add a secret key in a HTTP request header.For security, Moesif only allows webhooks protected by HTTPS.        The JSON payload looks like the following:    {    &quot;type&quot;: &quot;alert&quot;    &quot;name&quot;:  &quot;events_exceeded_threshold&quot;    &quot;metric&quot;: &quot;event count For Each response.status Condition is greater than 100 over the last day&quot;    &quot;grouping_feature_level1&quot;: null // 1st level of &quot;group by&quot; for the alert such as user_id, if any    &quot;grouping_feature_level2&quot;: null // 2nd level of &quot;group by&quot; for the alert such as route, if any    &quot;metric_values&quot;: [{      &quot;feature&quot;: &quot;global&quot;, // If this alert had a &quot;grouping&quot;, this will have the key name such as a user_id    // feature value can be    //  1. &quot;global&quot; if grouping_feature_level1 is empty    //  2. &quot;The metric value for a key in grouping_feature_level1&quot; if grouping_feature_level2 is empty    //. 3. &quot;The key name grouping_feature_level1&quot; + &quot;-&quot; + &quot;value if grouping_feature_level2 is set      &quot;value&quot;: 10.0, // Double, the actual metric value at time of alert      &quot;direction&quot;: &quot;spike&quot;,  // If dynamic alert, will be set to &quot;spike&quot;, &quot;increase&quot;, &quot;drop&quot;, or &quot;positive_trend&quot;    }],    &quot;timestamp&quot;: &quot;2023-07-05T06:16:54.953Z&quot; // UTC time of the current alert    &quot;history&quot;: { // Last X timestamps for this alert rule      &quot;2023-07-05T06:16:50.953Z&quot; : [{          &quot;feature&quot;: &quot;global&quot;          &quot;value&quot; :  &quot;100&quot;      }],      &quot;2023-07-05T06:16:40.953Z&quot; : [{          &quot;feature&quot;: &quot;global&quot;          &quot;value&quot; :  &quot;120&quot;      }]    }}      Notification ThrottleSet a reasonable throttle for this alert. This prevents you from being spammed with a storm of alerts. After the first notification is sent, Moesif will silence additional alerts. You can still see silenced notifications within the Alert History page.For example, you can set one channel of type email to always receive alerts on an email channel, but to avoid SMS charges you can set your channels that are SMS type to only receive a maximum of 1 alert per hour.Moesif has a correlation engine which detects related anomalies or triggers and consolidates them in the same notification.Throttling only impacts separate notifications.Both alert rules and channels support throttling. An alert will be silenced if either the rule or the channel is actively throttling.",
      "url": " /api-monitoring/creating-notification-channels/",
      "author": "Derric",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-viewing-alert-rules": {
      "title": "Viewing Alert Rules",
      "content"	 : "This guide assumes you are familiar with Alerts already. If not, please review API Monitors &amp;amp; Alerts.AlertingYou can find a full list of your alerts in the Alert Rules page. Here you can see an overview of your alerts, as well as access the notification channels.ChannelsTo view the notification channels for your alerts, select  Notification Channels. This page contains details about current channels in your application and allows you to create new ones. For more information, see Creating Notification Channels.Alert DetailsYou can turn on or off individual alerts using the On-Off toggle.To delete an alert, select  Delete.To access the details of an alert, select the alert title or  Edit. From this page, you can edit and reconfigure your alert.Alert Detail ViewThe alert details page allows you to see the time series chart of your alert, as well as the alert rules and settings for the alert.You can modify an alert by adjusting the different alert rule options and settings displayed in this page. For example, adding a new channel adds a new channel to this alert. Similarly, modifying the API filters or the tracking metrics updates the alert rules for the alert. After you’ve added your changes, select Save. For more information about this page, see Creating Alert Rules.Alert HistoryThe  Alert History pane in the Alert Rules section shows the recent history of all active alerts that has been triggered, including deleted alerts.By default, Alert History shows alert history for all active channels and alert rules. From the Filters pane, you can filter the history by channels and alert rules.Alert History Information            Column      Description              Alert name      The alert name              Status      Whether the alert is active or deleted.              Channel      The channels configured to get notifications for this alert.              Notification status      Whether notification has been sent successfully to channels or was suppressed due to a silence or downtime period.              Time      The UTC time and date for the trigger.      Selecting on the name of the alert takes you to its Alert Rule page where you can view and edit the alert rule. Selecting anywhere else opens up a pane with more details about the triggered alert:  The corresponding metric, metric value, and metric graph triggering the alert.  Any metadata that you may have attached.  Number of supperesed alerts during a silence or downtime period.  Any custom message you may have attached to the alert rule.",
      "url": " /api-monitoring/viewing-alert-rules/",
      "author": "Philip",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-ai-explain": {
      "title": "AI Explain",
      "content"	 : "This document explains how to use AI Explain in Alert Rules.OverviewMoesif’s AI Explain feature is an GenAI-powered conversational interface that allows you to easily ask questions and gain insights about your API monitoring and alerts data. This feature is designed to enhance the accessibility of Moesif’s analytics for users with minimal experience or knowledge of analytics tools and related concepts. By simply typing a question, users can receive detailed insights, helping them make more informed decisions.How It WorksAI Explain leverages Azure OpenAI, a leading large language model (LLM) platform, to process user questions and generate insightful responses. This integration allows AI Explain to provide quick and relevant answers based on your User and Company analytics data.Data UsageYour prompts and responses are not used for training or shared with others.To generate responses for your questions, Moesif sends the following event data to Azure OpenAI:  Event properties, including event IDs  Request and response data, such as headers and IP addressesGetting Started with AI Explain for Alert RulesTo start using AI Explain, navigate to the detail Alert Rule screen of any existing Alert Rule and then select Ask AI.You can type your questions directly, and AI Explain uses the available alerts data to generate insightful answers for you. Whether you need to identify trends, pinpoint issues, or understand behavior, AI Explain helps you get the answers without needing to dive deep into complex alert metrics yourself.Key Benefits  Accessibility  Makes Moesif’s analytics accessible to users without in-depth knowledge of analytics tools.  Efficiency  Saves time by providing direct answers, allowing you to avoid building complicated queries.  Insights on demand  Ask questions naturally, and get detailed insights about your existing alerts and associated metrics in real time.Your Data and PrivacyMoesif is committed to maintaining the privacy and confidentiality of your data. While the event data and conversational history are sent to Azure OpenAI for processing, it is important to note that Azure OpenAI does not store, train on, or share your prompts, responses, or Moesif data with others. Your data remains secure and is used solely to provide responses to your queries.",
      "url": " /api-monitoring/ai-explain/",
      "author": "Sakib",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-real-time-alerts": {
      "title": "Real-Time Rolling Alerts",
      "content"	 : "This document describes how the real-time rolling evaluation period type works for alerts and how to use it to set up real-time alerts. To detect long-term trends and anomalies, use calendar-based alerts.Real-Time Rolling Evaluation PeriodReal-time rolling allows you to set the evaluation period for smaller time periods like hours and minutes. Moesif evaluates them continuously every minute in overlapping rolling windows. For example, if you select 15 minutes, Moesif aggregates the metric from the last 15 minutes with a series like 12:00 to 12:15, 12:01 to 12:16, 12:02 to 12:17, and so on.If you want to get real-time alerts for sudden spikes or drop-offs, use real-time rolling alert periods.Example: Set Dynamic Alert with Real-Time Rolling Window to Monitor Short-Term AnomaliesThis example sets up a dynamic alert using Moesif’s anomaly detection system to monitor abrupt increase in 401 Unauthorized errors.Assume that you have a protected resource that requires valid credentials to access. You want to set up an alert to monitor and identify unauthorized access errors. A sudden spike in 401 errors might indicate  configuration and credential issues, or active security threats.This use case requires a real-time dynamic alert that evaluates your target metric every minute, instead of an alert with calendar-based rolling window for long-term anomalies.Specify Event Filters  Select API call event type.  Select 401 Unauthorized as the HTTP response status code.Select Group ByCategorize the metric by request URI route in the Group By pane. This helps understand affected endpoints and distribution of the issue across your API surface.Specify the MetricSelect Event Count as the metric.Specify Alert Rule Settings  Enter a name for the alert  Select 15 min as the evaluation period.  Turn the alert on by selecting the on-off checkbox.  Select Dynamic Alert as the alert type.      Select Increase for the alert trigger direction since we want to detect spikes in 401 errors.    Tip: For static alerts,   you can select the any operator in Threshold to trigger the alert for   every evaluation period regardless of any criteria. This is helpful in use cases   like when you want to send daily or monthly reports of top customers.    In metric anomaly detector settings, make sure to set them at a reasonable level that aligns with how often you want to get alerts.  Select or create a new notification channel where you want Moesif to dispatch alert notifications to.  Optionally, add a custom message or note to the alert. This shows up in the notification.  Select Save.Tip: For static alerts, you can select the any operator in Threshold to trigger the alert for every evaluation period regardless of any criteria. This is helpful in use cases like when you want to send daily or monthly reports of top customers.",
      "url": " /api-monitoring/real-time-alerts/",
      "author": "Sakib",
      "categories": "api-monitoring"
    }
    ,
  

    "api-monitoring-calendar-based-alerts": {
      "title": "Calendar-Based Alerts",
      "content"	 : "This document describes how the calendar-based evaluation period works for alerts and how to use it to monitor long-term trends and anomalies. To set up real-time alerts, see Real-Time Rolling Alerts.Calendar-Based Evaluation PeriodA calendar-based evaluation period sets the alert’s evaluation period to once per calendar interval. This means if you select a daily interval, Moesif aggregates your metric from 12:00 AM to 11:59 PM and sends a daily report. Similarly, if you select a weekly time period, you receive alerts once per week.To change your calendar and timezone settings, see Apps and Team settings.Calendar-based alerts aren’t real time since they look at longer historical trends compared to real-time alerts where evaluation occurs every minute. In contrast, for example in a daily calendar-based alert period, Moesif evaluates after each day at midnight to see if the previous period differs from history.Calendar-based evaluation period lets you retrospectively monitor, detect, and act on long-term trends and anomalies.Example: Set Dynamic Alert with Calendar-Based Evaluation Period to Monitor Long-Term TrendsThis example sets up a dynamic alert that alerts you when your API incurs a large drop in usage.Monitoring for significant drop in your product’s usage can help you proactively tackle urgent issues affecting your product, for example:  Service outages or service degradation  Customer integration issues  SDK or client library bug  Deprecation or breaking changes  Loss of a major customer: a worst-case scenarioThis use case requires a calendar-based dynamic alert that evaluates your target metric over a longer time period like a week or a month. The baseline itself is a long-term average; and we are looking for a change in the established pattern of usage. Therefore, we do not need real-time alert in this case.Specify Event Filters  Select API call event type.  Only consider customers that has user IDs.Select Group ByCategorize the metric by user IDs in the Group By pane. This helps youquickly identify affected customers and take appropriate measures like reaching out.Specify the MetricSelect Event Count as the metric.Specify Alert Rule Settings  Enter a name for the alert  Select Each Calendar Week as the evaluation period.  Turn the alert on by selecting the on-off checkbox.  Select Dynamic Alert as the alert type.      Select Decrease for the alert trigger direction since we want to detect decrease in usage.    Tip: For static alerts,   you can select the any operator in Threshold to trigger the alert for   every evaluation period regardless of any criteria. This is helpful in use cases   like when you want to send daily or monthly reports of top customers.    In metric anomaly detector settings, make sure to set them at a reasonable level that aligns with how often you want to get alerts.  Select or create a new notification channel where you want Moesif to dispatch alert notifications to.  Optionally, add a custom message or note to the alert. This shows up in the notification.  Select Save.",
      "url": " /api-monitoring/calendar-based-alerts/",
      "author": "Sakib",
      "categories": "api-monitoring"
    }
    ,
  

    "metered-billing": {
      "title": "Introduction to Metered Billing",
      "content"	 : "Metered Billing is a turnkey solution enabling you to monetize your APIs effortlessly. Because it doesn’t require any code changes, you can accelerate your monetization plans.Moesif supports direct integration with your favorite billing providers for metered billing. Simply create a new Metered Billing plan, plug in your billing provider, set up a filter to manage which API calls you want to bill for, and begin monetizing your APIs.You can create billing meters in Moesif in a few clicks that implement your usage-based pricing strategy.Setup Billing ProviderFirst, you’ll want to connect Moesif to your billing provider like Stripe. This allows Moesif to automatically invoice and collect payments. Moesif supports prepaid, postpaid, tiered, and many other consumption-based models. You can also connect Moesif to a custom provider via webhooks if your billing provider is not natively supported by Moesif.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Recurly                                                                                                                                                                                                        Stripe                                                                                                                                                                                                        Chargebee                                                                                                                                                                                                        Zuora                                                                                                                                                                                                        Custom                                                       via Webhooks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Navigating to Metered BillingTo get to the Metered Billing screen, simply click the Metered Billing navigation item in the left-side navigation.  Billing plans report usage of your defined metric to your billing provider and charges them with the correct quantity for the plan’s billing period.",
      "url": " /metered-billing/",
      "author": "Matthew",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-integrate-with-recurly": {
      "title": "Integrating with Recurly",
      "content"	 : "  This page assumes that you already have a Recurly account created and are able to create plans. To sign-up and create a Recurly account, visit the Recurly website.How it worksA billing meter is created via the Moesif UI for a specific metric and filter criteria that you want to charge for.  The filter criteria defines what the meter should include such as specific endpoints, certain customers, or other filter criteria.  The metric is what is metered. It could be number of API calls, unique users, an aggregation on a header or body field, or any other metric trackable by Moesif.Once the meter is created, Moesif will automatically meter the usage for each company and charge your customers via Recurly. Moesif billing meters support a variety of billing models including prepaid, postpaid, Pay As You Go (PAYG) and more. If you have different features or metrics you need to charge on, you can create multiple meters in Moesif, each linked to a different plan in Recurly. The integration also syncs subscription and revenue data from Recurly to Moesif so you can understand how API usage translates to revenue.PrerequisitesIn order to integrate Recurly with Moesif, there are a few prerequisites which must be completed. These include:  Creating an account with Recurly  Creating a plan in Recurly          Include at least one add on in your Recurly Plan.      Configure your add-on to bill customers at the end of the billing cycle.      Configure your add-on to charge per unit of usage.      Configuring the Recurly integrationMoesif’s connection with Recurly involves 2-way communication. Moesif has created a simple way to get all the info you need and to configure certain variables for Recurly in a single screen. To access the Recurly setup details screen,follow one of these methods:Access From Account Settings Menu  Select your account icon to bring up the settings menu.  Select Extensions.  Search and select Recurly.Access From Billing Meters Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select Edit Billing Providers dropdown  Select Recurly.Access From New Billing Meter Creation Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select + Add Billing Meter.  Select Set up Recurly from the Select Billing Provider dropdown.Once you’ve opened the configuration screen through one of the routes above, you can get the info needed to add the Moesif Webhook to Recurly, inputs to plug the Recurly API into Moesif, and customize your Customer ID source in a single place.Adding the Moesif Webhook to RecurlyAfter logging into your Recurly account, follow these steps to add Moesif webhook endpoint to Recurly:      Select Integrations and then select Webhooks in the navigation pane.     In the Webhooks screen, select Manage Endpoints.   In the Webhook Endpoints screen, select New Endpoint.  In the New Endpoint screen, enter the endpoint details:          Enter a name for the endpoint,      Enter Moesif webhook URL in the ENDPOINT URL field and your Moesif Application ID in the HTTP AUTH USERNAME field. Leave the HTTP AUTH PASSWORD field blank.   Remember that you can get these details from the Recurly configuration dialog in Moesif.         Select JSON as the webhook payload format.      In the Notifications pane, select all notifications associated with account and subscription.        Select Save Changes.The webhook you’ve added appears in the Webhooks screen in Recurly.Configuring the Recurly extension in MoesifNext, you must add the Recurly API key to Moesif.Moesif supports Recurly API version 3 or higher (v2019-10-10, v2021-02-25, or higher).To add your Recurly API key to Moesif, follow these steps:  Select Integrations and then select API Credentials in the navigation pane.  Copy the API key from the PRIVATE API KEY field.   Paste the API key in the Recurly API Key field of the Recurly configuration dialog in Moesif. After you finish, select Save in the Recurly configuration dialog.Set the Id MappingThe Set Id Mapping section of the Recurly configuration dialog in Moesif enables you to specify the correct Recurly subscription field that contains the Moesif Company Id. Moesif will use this to link your Subscriptions in Recurly with Companies in Moesif. By default this is subscription.uuid, but you’ll likely need to modify this unless you use Recurly’s default subscription ids to identify customers on your API. Typically, this is a Custom Field added to the Recurly Subscription object like company_id or tenant_id.Correct linking of Moesif companies to Recurly subscriptions is required for metered billing to function.While not required, you can also link Recurly Customer Accounts to Moesif User Objects. By default, this is account.account_code, but you can chagne it to any field present on the Account object in Recurly such as a Custom Field.For example, both the Customer Account and Subscription objects have the ability to add Custom Fields. You can add a Custom Field programmatically through Recurly API or using the Recurly web UI. After adding Custom Fields, you will be able to see them in the Recurly UI and retrieve them from the Recurly API.Now, you’d want to make sure that the data you enter into the Custom Field matches whatever value you have in the Moesif UserId and/or CompanyId fields. Based on the Custom Fields above, we could map the values into Moesif by going to the Recurly configuration screen and changing the values in the Set Id Mapping fields to match.It’s important to remember that the values you see under the Moesif CompanyId and UserId should be what you are mapping to in Recurly through this configuration. This is how usage is synced for the user/company.Linking a plan in Recurly to a billing meterWhen creating a new billing meter, in the Link To section you can specify Recurly as the Billing Provider and then select the Plan and Add-on you’d like the usage to be linked to.",
      "url": " /metered-billing/integrate-with-recurly/",
      "author": "Matthew",
      "categories": "Billing, Billing Integration"
    }
    ,
  

    "metered-billing-integrate-with-stripe": {
      "title": "Integrating with Stripe",
      "content"	 : "  This page assumes that you already have a Stripe account created and are able to create plans. To sign-up and create a Stripe account, visit the Stripe website.How it worksA billing meter is created via the Moesif UI for a specific metric and filter criteria that you want to charge for.  The filter criteria defines what the meter should include such as specific endpoints, certain customers, or other filter criteria.  The metric is what is metered. It could be number of API calls, unique users, an aggregation on a header or body field, or any other metric trackable by Moesif.Once the meter is created, Moesif will automatically meter the usage for each company and charge your customers via Stripe. Moesif billing meters support a variety of billing models including prepaid, postpaid, Pay As You Go (PAYG) and more. If you have different features or metrics you need to charge on, you can create multiple meters in Moesif, each linked to a different Product and Price in Stripe. The integration also syncs subscription and revenue data from Stripe to Moesif so you can understand how API usage translates to revenue.PrerequisitesTo integrate Stripe with Moesif, make sure you have an active Stripe account.Additionally, make sure to meet the following requirements:  The product has a recurring price.  The pricing model is usage-based and usage is metered.  The price contains a description (optional, but highly recommended).  A Stripe billing meter only associates with one price. Reusing a Stripe billing meter for more than one price might result in charging a customer multiple times for the same usage amount.  The Stripe billing meter uses either a Sum or Last aggregation formula to aggregate meter events.These docs are for Stripe’s new meter APIs which is recommended for new setups. Moesif also supports Stripe prices configured for the legacy usage records API.Alternatively, you can model your products and prices usingMoesif’s Product Catalog that automaticallysyncs with Stripe Product Catalog.The following example creates a product and price in Stripe to demonstrate howyou can use Stripe to model your usage-based pricing structure:Creating a Product and Price in StripeThe following steps demonstrate how to create a product, define its pricestructure, and create a billing meter for the price in Stripe.  Go to your Stripe Dashboard.  Go to Product Catalog and then select Create product.    Select Recurring and then select More pricing options.   Select Recurring and choose Usage-based as the pricing model. You canchoose the usage amount as package, unit, or tier.  Define your price amounts, for example, $0.01 for each 1k API requests.      In the Meter section, select the plus icon + to create a billing meter to associate the price with.    a. Enter the meter name.    b. Enter the event name for which the billing meter reports usage.    c. Select the aggregation method for meter events. Moesif supports the Sum and Last aggregation methods.    d. Expand Advanced Options and make sure that Event Time Window is set to Raw.    In the Advanced section, enter a description for the price.  Select Next and then select Add product to finish.After you finish configuring Stripe by following the rest of this document, theproducts and prices you have in Stripe appears in Moesif’s Product CatalogPlans and Prices. Any new product and price you create also syncs automaticallybetween Moesif and Stripe, irrespective of which platform you create them in.Configuring the Stripe integrationMoesif’s connection with Stripe involves 2-way communication. Moesif has created a simple way to get all the info you need and to configure certain variables for Stripe in a single screen. To access the Stripe setup details screen, follow one of these methods:Access From Account Settings Menu  Select your account icon to bring up the settings menu.  Select Extensions.  Search and select Stripe.Access From Billing Meters Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select Edit Billing Providers dropdown  Select Stripe.Access From New Billing Meter Creation Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select + Add Billing Meter.  Select Set up Stripe from the Select Billing Provider dropdown.Once you’ve opened the configuration screen through one of the routes above, you can get the info needed to add the Moesif Webhook to Stripe, inputs to plug the Stripe API into Moesif, and customize your Customer ID source in a single place.Adding the Moesif Webhook to StripeIn Stripe, you need to add a webhook through which Stripe can send subscription updates to Moesif. Follow these steps to add the webhook:  Go to your Stripe Dashboard.  Select Developers in the navigation pane to access the Developers Dashboard.    Go to the Webhooks tab and then select + Add endpoint.        In the Listen to Stripe events screen that appears, paste in the Moesif Webhook URL in the Endpoint URL field. Optionally, add a description for the endpoint.      Remember that you can get the Moesif Webhook URL for Stripe in the Stripe configuration dialog. The Endpoint URL value you add to Stripe also contains your Moesif Application ID. The generated URL in the Moesif-Stripe configuration dialog already contains the correct Application ID and have it appended to the URL.        Next, configure the endpoint to listen to all events by selecting Select events.      In the Select events to send screen, select all events for the Customer and Invoice event types and then select Add events at the bottom of the page.        Back in the Listen to Stripe events screen, select Add endpoint at the bottom (you’ll likely need to scroll to the bottom of the page).  The new webhook you’ve just added appears in the Webhooks tab of Stripe Developers Dashboard.Configuring the Stripe extension in MoesifIn Moesif, enter your Stripe API key in the Stripe API Key field of the Stripe configuration dialog.Moesif supports Stripe API Versions 2020-08-27 or higher.To get your Stripe API key, follow these steps:  Go to your Stripe Dashboard.  Select Developers in the navigation pane to access the Developers Dashboard.  Go the API Keys tab.  In the Standard keys list, in the Secret key row, select Reveal test key.  Copy the key by clicking the key value. If you need more fine-tuned control over access, create a restricted key and copy that.Stripe may prompt you to enter your password if the account has been inactive for a while.This example uses test keys. To get a production key, switch over to live mode.After you finish, select Save in the Stripe configuration dialog.Set the Id MappingIn Set Id Mapping in the Stripe configuration dialog, you can customize how Stripe customers link to Companies in Moesif:  A Stripe Customer maps toMoesif Company.  A Stripe Subscription maps to a Moesif Subscription.By default, the Stripe configuration dialog contains the following mappings:            Moesif field      Stripe field                  company_id      customer.id              subscription_id      subscription.id      You can’t modify the mappings between Stripe Subscriptions and Moesif Subscriptions.Moesif always maps Stripe’s subscription ID to Moesif’s subscription ID.However, you can modify how Stripe Customers map to Companies in Moesif, for example, if you have attachedmetadata information to the Stripe Customer object.You can add metadata to the Customer object programmatically through the Stripe APIs or through the Stripe UI like this:  Go to your Stripe Dashboard.  Select Customers in the navigation pane and then select a customer field to access its details.  Select edit in the Metadata section.Next, make sure that the data you enter into the metadata fields match the value you have in the Moesif company_id field.For example, we have a metadata field saas_company_id in the Stripe Customer object. So we can define the mapping like this:Remember that the values for Moesif company ID and user ID must match what you’re mapping to in Stripe through this configuration. This is how Moesif syncs usage for the User or Company.Note: If you change the mapping for an existing subscription, you must manually trigger a subscription update in Stripe. This makes sure that Stripe subscription data syncs to Moesif after your changes and Moesif continues to correctly meter and report usage. To achieve this, update Stripe Customer metadata.Linking a plan in Stripe to a billing meterWhen creating a new billing meter, in the Link To section you can specify Stripe as the Billing Provider and then select the Product and Price you’d like the usage to be linked to.Permission needed For Stripe Restricted API keyIf you decide to create a Restricted Stripe API key, the minimum permission scope you need when creating the Stripe API Key are below:{  &quot;permissions&quot;: [    {      &quot;permission&quot;: &quot;customer_read&quot;,      &quot;purpose&quot;: &quot;Need to read customer details to report usage.&quot;    },    {      &quot;permission&quot;: &quot;customer_write&quot;,      &quot;purpose&quot;: &quot;Need to create customer balance transactions to support prepaid credits.&quot;    },    {      &quot;permission&quot;: &quot;invoice_read&quot;,      &quot;purpose&quot;: &quot;Needed for usage reporting and credit consumption.&quot;    },    {      &quot;permission&quot;: &quot;plan_read&quot;,      &quot;purpose&quot;: &quot;Need to get plan and price details to report usage.&quot;    },    {      &quot;permission&quot;: &quot;plan_write&quot;,      &quot;purpose&quot;: &quot;Enable creating plan and price using Moesif Product Catalogue tool.&quot;    },    {      &quot;permission&quot;: &quot;product_read&quot;,      &quot;purpose&quot;: &quot;Enable creating plan and price using Moesif Product Catalogue tool.&quot;    },    {      &quot;permission&quot;: &quot;product_write&quot;,      &quot;purpose&quot;: &quot;Enable creating plan and price using Moesif Product Catalogue tool.&quot;    },    {      &quot;permission&quot;: &quot;subscription_read&quot;,      &quot;purpose&quot;: &quot;Need to get subscription details to report usage.&quot;    },    {      &quot;permission&quot;: &quot;usage_record_read&quot;,      &quot;purpose&quot;: &quot;Need to see previous usage reported.&quot;    },    {      &quot;permission&quot;: &quot;usage_record_write&quot;,      &quot;purpose&quot;: &quot;Enabled report usage.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_read&quot;,      &quot;purpose&quot;: &quot;Enabled reading of Stripe billing meter.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_write&quot;,      &quot;purpose&quot;: &quot;Enabled writing of Stripe billing meter.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_event_read&quot;,      &quot;purpose&quot;: &quot;Need for usage based billing.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_event_write&quot;,      &quot;purpose&quot;: &quot;Need for usage based billing.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_event_adjustment_read&quot;,      &quot;purpose&quot;: &quot;Need for usage based billing.&quot;    },    {      &quot;permission&quot;: &quot;billing_meter_event_adjustment_write&quot;,      &quot;purpose&quot;: &quot;Need for usage based billing.&quot;    }  ]}Subscribing to a Product and PriceSee Provider Mapping to understand how Stripe concepts like Products map toMoesif.If you want to sell your product through a subscription model, you must set upStripe Subscriptions.You can create and manage Stripe subscriptions in different ways.You may have already integrated Stripe with Moesif.When you create products and prices in Stripe, Moesifautomatically creates the corresponding Plans and Prices. You can access them inProduct Catalog any time. Whenever acustomer confirms a Stripe Subscription,Moesif automatically tracks and captures the subscriptiondata including the associated products and prices. For example, you may have built a subscription page for your product orservices with Stripe Checkout. At the end of a successful checkout session, youhave a customer who’ve subscribed to pay a recurring price to use your product.Moesif starts tracking the subscription usage according to the Billing Meter you’vecreated.Moesif automatically syncs all the subscription data without any manualsupervision.Create SubscriptionsYou can create subscriptions in different ways:  Create and edit a subscription manually in your Stripe Dashboard.  Use the Stripe API to create or update subscriptions.See Create a Subscription inStripe API Reference for more information about the Stripe Subscriptions API.",
      "url": " /metered-billing/integrate-with-stripe/",
      "author": "Matthew",
      "categories": "Billing, Billing Integration"
    }
    ,
  

    "metered-billing-integrate-with-chargebee": {
      "title": "Integrating with Chargebee",
      "content"	 : "  This page assumes that you already have a Chargebee account created, have metered billing enabled, and are able to create plans. To sign-up and create a Chargebee account, visit the Chargebee website.  If you can’t enable metered billing, contact support@chargebee.com to enable the feature on your Chargebee site.How it worksA billing meter is created via the Moesif UI for a specific metric and filter criteria that you want to charge for.  The filter criteria defines what the meter should include such as specific endpoints, certain customers, or other filter criteria.  The metric is what is metered. It could be number of API calls, unique users, an aggregation on a header or body field, or any other metric trackable by Moesif.Once the billing meter is created, Moesif will automatically meter the usage for each company and charge your customers via Chargebee. Moesif billing meters support a variety of billing models including prepaid, postpaid, Pay As You Go (PAYG) and more. If you have different features or metrics you need to charge on, you can create multiple meters in Moesif, each linked to a different Plans and Prices in Chargebee. The integration also syncs subscription and revenue data from Chargebee to Moesif so you can understand how API usage translates to revenue.PrerequisitesIn order to integrate Chargebee with Moesif, there are a few prerequisites which must be completed. These include:  Creating an account with Chargebee  Creating a plan in ChargebeeMake sure the plan has This plan is metered enabled in order for usage to be updated correctly by Moesif. We also recommendd that you set Process charges for shared usage data by option to Sum of all usages.Configuring the Chargebee integrationMoesif’s connection with Chargebee involves 2-way communication. Moesif has created a simple way to get all the info you need and to configure certain variables for Chargebee in a single screen. To access the Chargebee setup details screen, you can follow one of these methods:Access From Account Settings Menu  Select your account icon to bring up the settings menu.  Select Extensions.  Search and select Chargebee.Access From Billing Meters Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select Edit Billing Providers dropdown  Select Chargebee.Access From New Billing Meter Creation Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select + Add Billing Meter.  Select Set up Chargebee from the Select Billing Provider dropdown.Once you’ve opened the configuration screen through one of the routes above, you can get the info needed to add the Moesif Webhook to Chargebee, inputs to plug the Chargebee API into Moesif, and customize your Customer ID source in a single place.Adding the Moesif Webhook to ChargebeeIn Chargebee, you need to add Moesif webhook through which Chargebee can send subscription updates to Moesif. Follow these steps in your Chargebee site to add the webhook after logging into your Chargebee account:  Select Settings and then select Configure Chargebee in the navigation pane.  In the API Keys and Events section, select Webhooks and then select + Add Webhook.   In the Create a Webhook dialog, enter the webhook details.          Enter a name for the webhook.      Select the Protect webhook URL with basic authentication toggle to the on position.      Add the Moesif Webhook URL into the Webhook URL field and the Moesif Application ID into the Username field.        Select Create.After you create the webhook succesfully, it appears in the API Keys and Webhooks screen. From here, you can also test the webhook by selecting Test Webhook.Then select Test URL. The results show a Successfully received OK response from the webhook message with the request details.Configuring the Chargebee extension in MoesifIn Moesif, you will need to plug in the Chargebee API details so that Moesif can post usage details to Chargebee to bill upon. These details can be entered into the Chargebee API Key, and Site fields on the Chargebee Setup Details screen. Make sure you’re using Chargebee API Version v2 or higher.Moesif supports Chargebee API v2 or higher.To get the Chargebee API key from your Chargebee site, follow these steps:  Select Settings and then select Configure Chargebee in the navigation pane.  In the API Keys and Events section, select API keys tab and copy the full access key.  Paste the key in the Chargebee API Key field of the Chargebee setup details dialog in Moesif.Lastly, grab the your Chargebee site name from your URL bar in your browser and paste it into the Site field. For example, if the URL is example-test.chargebee.com, your Chargebee site name is example-test.The filled out entries will look similar to this.Once completed, be sure to select Save.Set the Id MappingThe Id Mapping Configuration enables you to specify the correct Chargebee subscription field that contains the Moesif Company Id. Moesif will use this to link your Subscriptions in Chargebee with Companies in Moesif. By default this is subscription.id, but you’ll likely need to modify this unless you use Chargebee’s default subscription IDs to identify customers on your API. Typically, this is a metadata field or Custom Field added to the Chargebee Subscription object like company_id or tenant_id.Correct linking of Moesif companies to Chargebee subscriptions is required for metered billing to function.While not required, you can also link Chargebee Customers to Moesif User Objects. By default, this is customer.id, but can be changed to any field present on the Customer object in Chargebee such as a metadata field or custom field.An example of how to do this is through Custom Fields and Metadata in Chargebee. For instance, both the Customer and Subscription objects could have Custom fields that enable you to attach custom fields and metadata in Chargebee. Once you add a Custom Field through the Chargebee APIs or through the Chargebee UI, you will see the value populated in the in the UI. For example, we can add our own user identifier for a Customer:The same can be seen for the Subscription object as well.Now, you’d want to make sure that the data you enter into the Custom Fields match whatever value you have in the Moesif UserId and/or CompanyId fields. Based on the custom fields above, we could map the values into Moesif by going to the Chargebee configuration screen and changing the values in the Set Id Mapping fields to match.If you are using Metadata fields, the configuration will look like this.It’s important to remember that the values you see under the Moesif CompanyId and UserId should be what you are mapping to in Chargebee through this configuration. This is how usage is synced for the user/company.Linking a plan in Chargebee to a billing meterWhen creating a new billing meter, in the Link To section you can specify Chargebee as the Billing Provider and then select the Item Plan and Item Price you’d like the usage to be linked to. For a Chargebee plan to appear in Moesif, you must create a price for the plan.  When creating a billing meter linked to Chargebee, you can select the reporting period. You can select “hourly” for testing purposes. However for production, we recommend daily reporting as Chargebee has a limit of 50k usage records for the lifetime of each subscription.More resourcesStep-by-step guide on creating a billing meter with Chargebee",
      "url": " /metered-billing/integrate-with-chargebee/",
      "author": "Matthew",
      "categories": "Billing, Billing Integration"
    }
    ,
  

    "metered-billing-integrate-with-zuora": {
      "title": "Integrating with Zuora",
      "content"	 : "  This page assumes that you already have a Zuora Billing account created and have already created products with corresponding plans and prices. To sign-up and create a Zuora account, visit the Zuora website.How it worksA billing meter is created via the Moesif UI for a specific metric and filter criteria that you want to charge for.  The filter criteria defines what the meter should include such as specific endpoints, certain customers, or other filter criteria.  The metric is what is metered. It could be number of API calls, unique users, an aggregation on a header or body field, or any other metric trackable by Moesif.Once the meter is created, Moesif will automatically meter the usage for each company and charge your customers via Zuora. Moesif billing meters support a variety of billing models including prepaid, postpaid, Pay As You Go (PAYG) and more. If you have different features or metrics you need to charge on, you can create multiple meters in Moesif, each linked to a different Plan and Price in Zuora. The integration also syncs subscription and revenue data from Zuora to Moesif so you can understand how API usage translates to revenue.Prerequisites  You must have permissions to create new users in Zuora such as a Platform Admin.  You must have permissions to create Custom Events in Zuora such as a Platform Admin.Create a Webhook in Zuora  A custom event type needs to be created in Zuora in order for Moesif to receive all the data it needs to access Zuora plans and prices and send usage data.1. Navigate to the area ‘Create Custom Event’, following the screenshots belowWhile logged in to your Zuora Billing Account, click the top-right avatar menu and navigate to the Administration option.Click on Setup Profiles, Notifications and Email TemplatesSelect Custom Events tab from the top of the screen and click on Create Custom Event button on the right side. It will launch create custom event modal.  2. Create Custom Event for ‘Subscription’  Name and API Name can be any arbitrary name.          API Name should not contain any whitespace.        Advanced (JEXL) needs to be selected to enable freeform entry for Set Conditions          Paste the following into Set Conditions: changeType =~ [&#39;INSERT&#39;, &#39;UPDATE&#39;, &#39;DELETE&#39;] &amp;amp;&amp;amp; Subscription.Id_old != Subscription.Id        Click the Create button once all the fields are configured correctly.Now that the custom event has been created, we will create a notification that is triggered by the event.3. Follow the screenshot below to navigate to Add New Notification for Billing Notifications4. Select the Custom Event you created in Step 2It should be listed under Subscription in the dropdown5. Fill out the rest of the form accordingly  Custom Zuora event created in Step 2  Arbitrary name that describes the notification  Make sure to activate notification  Callout is Zuora&#39;s equivalent for a webhook  Base URL should be https://api.moesif.net/v1/partners/zuora  Need to add 3 parameters  Use the dropdowns to select the 3 parameters shown above          IMPORTANT: Do not change the Parameter Names, or Moesif will not recognize the Zuora webhook      Select Username/Password  Username should be your Moesif app&#39;s Application ID           This can be found in Moesif&#39;s Zuora Extension setup page or Moesif&#39;s API Keys page              Enter any arbitrary field for Password. Moesif does not use this value, but Zuora does not allow the field to be blank.  Configure settings in MoesifNow that the Zuora custom Subscription event and webhook has been setup, now we can configure Moesif to interpret the Zuora webhooks it receives.To access the Zuora setup details screen, you can follow one of these methods:Access From Account Settings Menu  Select your account icon to bring up the settings menu.  Select Extensions.  Search and select Zuora.Access From Billing Meters Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select Edit Billing Providers dropdown  Select Zuora.Access From New Billing Meter Creation Page  Select Billing Meters in the navigation menu to open the Billing Meters screen.  Select + Add Billing Meter.  Select Set up Zuora from the Select Billing Provider dropdown.The first part of the setup instructions links back to this page, so we’ve come full circle! Let’s continue the setup.1. Create OAuth Client in ZuoraNext we need to add Zuora OAuth credentials in the Zuora UI into Moesif.To do so, we need to create a new API User. For more details, see Zuora docs on Creating API Users.  Log into Zuora UI and go to Administration -&amp;gt; Manage Users  Create a new user such as a “Moesif API User”  The user must have at least the permission Platform “API Write Access”  Scroll to bottom of the created user. Enter a client name for “New OAuth Client” and click “Create”  Add the client id and client secret in your Moesif settings panel.2. Set the Base URLYou will also need to set your Zuora base URL from the list available on Zuora’s website.The Zuora Base URL is rest.{{your Zuora app URL prefix}} . In the example below, the prefix is apisandbox so the Base URL to enter is rest.apisandbox.3. Set the Id MappingThe Id Mapping Configuration enables you to specify the correct Zuora customer account field that contains the Moesif Company Id. Moesif will use this to link your Customer Accounts in Zuora with Companies in Moesif. By default this is account.id, but you’ll likely need to modify this unless you use Zuora’s default customer account ids to identify customers on your API. Typically, this is a metadata field added to the Zuora Customer Account object like company_id or tenant_id.Correct linking of Moesif companies to Zuora accounts is required for metered billing to function.It’s important to remember that the values you see under the Moesif Field should be what you are mapping to in Zuora through this configuration. This is how usage is synced for the user/company.Create a new Billing MeterOnce you are done, you can continue with creating your billing meter. Ensure you select Zuora as the Billing Provider and then select the Plan and Price you’d like the usage to be linked to.",
      "url": " /metered-billing/integrate-with-zuora/",
      "author": "Praveen/Andy",
      "categories": "Billing, Billing Integration"
    }
    ,
  

    "metered-billing-integrate-with-a-custom-webhook": {
      "title": "Integrating with a Custom Webhook",
      "content"	 : "How It WorksWith a Billing Meter that uses Webhooks, Moesif will automatically meter the usage and send the usage data to your Webhook endpoint. Moesif Billing Meters support a variety of billing models including prepaid, postpaid, Pay As You Go (PAYG), and more. If you have different features or metrics you need to charge on, you can create multiple meters in Moesif, each linked to a plan.Creating a Billing Meter that sends usage data to custom webhooks adds unlimited possibilities. Using custom Webhooks makes it easy for you to integrate a Moesif Billing Meter with a custom or in-house billing platform. Moesif will handle the scheduling and reporting of usage, you just need to implement a custom webhook handler to add the reported usage to the respective customer’s invoice/subscription in your internal billing system.  This page assumes that you already have a Webhook service/endpoint already created and available so that Moesif will be able to send messages/requests to it.Configuring Your Webhook in MoesifWith your Webhook URL handy, go to the Billing Meters page in Moesif by clicking the Billing Meters link in the left-side menu. From the Billing Meters main screen, click on the Add Billing Meter button in the top right. This will display the Create New Billing Meter screen.1 - Select Webhook Billing ProviderClick on the Select billing provider dropdown (under the Billing Provider section) and select Custom (Report/Webhook). Once selected, you dropdowns become available for selecting webhooks and plans.2 - Select Your Webhook(s)To select the Webhook to send usage to, click on the Webhook(s) dropdown. If you have a Webhook already available/added in Moesif, you can select it from the list. Multiple Webhooks can be selected for a single meter. If not, select the Add New Webhook option to add a new webhook. In the Create Notification Channel modal that appears, you’ll need to add:To authenticate webhook requests as coming from Moesif, it’s strongly recommended to add a secret key in a request HTTP header.For security, Moesif only allows webhooks protected by https.  Channel Name          This will be the name that your webhook is referred to as in Moesif.        Channel Type          This will be defaulted to Webhook.        Webhook URL          This is your Webhook URL that you want Moesif to send requests to.        Method          This is the HTTP method, POST or PUT that should be used when sending requests to your Webhook URL.        Request Headers          These are any headers that you want to add to the Webhook request, such as an Authorization or Content-Type header. To authenticate requests as coming from Moesif, we recommend adding a secret key in a request header.      Once the Webhook fields are filled out,  click Save.3 - Select/Create a Billing PlanTo select the plan that usage should be attributed to, click on the Select Plan dropdown. IF you have plans that are already created, you can select them here. If not, select the Add New Plan option to add a new plan. In the Create Billing Plan modal that appears, you’ll need to add:  Plan Name          This is the name for your plan that will be displayed in Moesif.        External Plan Id          This can be used to store the Plan Id from your billing solution or any unique identifier that will help with mapping usage.        Reporting Schedule          This is the schedule type for how Moesif will report/send the usage to your Webhook. For more details see Choosing a Reporting Schedule and Reporting Period.        Reporting Period          This is the period that Moesif will gather the usage data over before sending. For more details see Choosing a Reporting Schedule and Reporting Period.      Once the Plan fields are filled out in the modal, click Create.4 - Set the “Report for Subscriptions In” OptionIn the Report for Subscriptions in selector, you will select what subscription status you want to meter. For instance, you may want to meter usage only for subscriptions which have an Active status. Options here include:  Active  Future  In Trial  Paused  Non-Renewing5 - Configure the Filters and Metrics and Save the Billing MeterThese details are covered in details on our Adding Billing Criteria docs page. Once the billing criteria is set, click the Create button in the top-right of the screen.6 - Create a SubscriptionLastly, in order for usage data to be sent through the Webhook you need to make sure you’ve created a Subscription for the company(s) to be billed. This will be done by calling the Moesif /subscriptions API endpoint. An example cURL can be seen below:curl --request POST --url &#39;https://api.moesif.net/v1/subscriptions&#39; --header &#39;X-Moesif-Application-Id: YOUR_COLLECTOR_APPLICATION_ID&#39; --header &#39;Content-Type: application/json&#39; --data &#39;{  &quot;subscription_id&quot;: &quot;{unique_subscription_id}&quot;,  &quot;company_id&quot;: &quot;{moesif_company_id}&quot;,  &quot;current_period_start&quot;: &quot;2022-04-01T20:13:00.001Z&quot;,  &quot;current_period_end&quot;: &quot;2024-06-03T20:13:00.001Z&quot;,  &quot;status&quot;: &quot;active&quot;,  &quot;items&quot;: [    {      &quot;plan_id&quot;: &quot;{moesif_plan_id}&quot; &amp;lt;-- the GUID of the Moesif Plan    }  ]}&#39;The above cURL command requires the following details:  url          in the URL you will need to include both the orgId and the appId. The easiest way to grab these values is through your browser URL when you are logged into Moesif (https://www.moesif.com/wrap/app/{orgId}-{appId}/).        header - Authorization          For this parameter you will add your Moesif Management Token. To create one you can click Settings (your name in the bottom left) and then select API Keys from the pop-up menu. Under the Management API Key section, add the Scope for subscriptions under the [Admin] header and any other scopes your API key will require. After this, scroll to the bottom, set your Expiration and click Generate Token. The generated token can now be added to the request.        data          subscription_id                  This will be a generated subscription ID that will be generated by you. Any unique value can be used here.                    company_id                  Here you will set the Company Id you used within Moesif. This can be found in the Company profile and other places within the Moesif app.                    current_period_start                  This is the current subscription period start date. If this is irrelevant for your billing scheme, stamp it with the current date and time.                    current_period_end                  This is the current subscription period end date. If this is irrelevant, you can set a date and time far into the future.                    status                  This is the status of the subscription. Possible allowed values here include  &quot;active&quot;, &quot;cancelled&quot;, &quot;trialing&quot;, and &quot;past_due&quot;                    items                  plan_id                          This will be the GUID of the plan you created in Moesif. To find this value, click Settings (select your name on the left-side navigation pane) and then select Billing Plans from the pop-up menu. Select the billing plan you want the plan_id for and in the modal that appears you will see the value you need in the Moesif Plan Id field.                                            An important note for current_period_start and current_period_end must be set manually when using Webhook billing. This will require custom logic, likely in your Webhook, to ensure they are adjusted correctly depending on the customer-selected billing period (eg, daily, weekly, monthly, etc.).Once the data is sent to the API endpoint, your subscription will be created. Any usage that comes in that matches your Webhook Billing Meter will now be correctly sent to your Webhook.PayloadsThe following snippet shows an example request Moesif sends to your webhook endpoint: {  &quot;idempotency_key&quot;: &quot;KG5LxwFBepaKHyUD&quot;,  &quot;company_id&quot;: &quot;0a497&quot;,  &quot;subscription_id&quot;: &quot;sub_1MowQVJkdIwHu7ixeRlqHVzs&quot;,  &quot;plan_id&quot;: &quot;6631d0f6b0bbd31159137af8&quot;,  &quot;billing_meter_id&quot;: &quot;6631e7c55e2dbf1867129d3e&quot;,  &quot;quantity&quot;: 1,  &quot;start_time&quot;: &quot;2024-05-01T06:54:40&quot;,  &quot;end_time&quot;: &quot;2024-11-01T06:54:41&quot; }Editing and Updating a WebhookTo edit a Webhook, click on the Settings menu in the bottom left of the screen (shown as your name) and select Notification Channels. On the Notification Channels screen, select your Webhook by clicking on its name. On the modal that appears you can update and edit the Webhook settings. Once completed, click Save.Testing Your WebhookYou can test your custom webhook by using Webhook.site. Webhook.site generates a unique and random URL that you can use as the webhook endpoint URL when setting up your webhook in Moesif. Webhook.site instantly shows any data the URL receives. Therefore, you can easily test if everything works as you expect and what data Moesif sends.Editing and Updating a PlanTo edit a Plan, click on the Settings menu in the bottom left of the screen (shown as your name) and select Billing Plans. On the Billing Plans screen, select your Plan by clicking on its name. On the modal that appears you can update and edit the Plan’s settings. Once completed, click Save.  For auditing purposes, the only detail that can be changed for a plan is the plan’s Name. To edit it further, you’ll need to archive the existing plan and create a new one.Choosing a Reporting Schedule and Reporting PeriodCurrently there are three options for Reporting Schedule in the Moesif Billing Plan configuration. These options include:  Continuous Reporting          This option reports usage in near real-time throughout the billing period. This is the recommended option if your billing system can handle aggregating multiple reports in same billing period.        Calendar-Aligned Billing          This option reports all usages on same calendar date or quarter, such as the last day of the month.        Subscription-Based Billing          This option reports the usage separately for each subscription based on a subscription end date. You will need to keep these up to date using the Moesif Update Companies API.      For each of these Reporting Schedule options, there are also configurable Reporting Periods.For Continuous Reporting the Reporting Period select will aggregate usage within the chosen time period before sending to the Webhook. For Continuous Reporting, these Reporting Periods include:  Every 5 Minutes  Every 15 Minutes  Every HourFor Calendar-Aligned Billing the Reporting Period select will aggregate usage within the chosen calendar period before sending to the Webhook. For Calendar-Aligned Billing, these Reporting Periods include:  Daily  Weekly  Monthly  QuarterlyFor Subscription-Based Billing the Reporting Period is based on the subscription.current_period_start and subscription.current_period_end set in the Company object. For subscription-based billing to work, your custom solution will need to write the subscription.current_period_start and subscription.current_period_end (or equivalent) to Moesif. This can be done by using the Moesif API.See Also  Creating Billing Meters  Choosing a Billable Metric  Testing Billing Meters  Managing Subscriptions for Custom Billing Providers",
      "url": " /metered-billing/integrate-with-a-custom-webhook/",
      "author": "Matthew",
      "categories": "Billing, Billing Integration"
    }
    ,
  

    "metered-billing-creating-billing-meters": {
      "title": "Creating Billing Meters",
      "content"	 : "This page describes how you can create Billing Meters and set them up.Creating a New Billing Meter  Select Billing Meters menu item in the navigation menu and then select + Add Billing Meter.  Alternatively, select + Create New in the navigation menu and then select Billing Meter from  the API Monetization section.  Fill out the necessary details for your new billing meter.To create a new Billing Meter, you have to enter the following details:NameA name for your new billing meter.Billing Provider InformationBilling provider information covers the following details:  Your billing provider, for example, Stripe  The product  The prices for the product  The reporting period that specifies how often Moesif syncs with the billing provider  The credit balance and invoice credit behaviors (for Stripe)Credit Balance BehaviorMoesif allows you to control when credits are issued in Stripe. You have the following options to choose from:  Bill Customer (Default)  This option credits the customer in Stripe if prepaid credit exists for the subscription in Moesif. For a negative subscription balance or if Moesif doesn’t track the balance, it charges customer normally.  Zero Out Invoices  Moesif reports the usage to Stripe, but the invoices will be zeroed out with credits. Use this option if you plan to invoice customers manually or through another system.For more information, see Credit Balance Behavior.Invoice Credit BehaviorThe Invoice Credit Behavior options allow you to specify whether Moesif automatically applies prepaid credits to Stripe invoices. For more information, see Invoice Credit Behavior.FiltersThe filters define the criteria for which Moesif should include API transactions or actions in the metric.Metric to Charge OnThe metric that you charge customers on. Generally, Event Count is common to choose, but other options exist including Unique Users, Unique Companies. You can also formulate your own metric using custom metadata fields such as to track bandwidth consumed or other metrics.  Usage is always grouped by Company Id. The usage totals for each company will be tallied and sent to the billing provider to charge the customer based on plan and add-on billing cycle.Linking a Billing Meter to a Billing Provider  If you have not set up a billing provider, follow the instructions in Set up Billng Provider. Alternatively, select your profile icon in your Moesif Web Portal to bring up the Settings menu. Then select Extensions. Then find your billing provider in the extensions list and follow the instructions.When you create a new billing meter, you first select your billing provider. Based on the billing provider you select, you’ll have options to select other billing details like the plan or product, and add-ons or prices that Moesif should count the usage data towards and link to. The dropdown menus will retrieve the necessary data from the products and plans you’ve created in your billing provider. This happens seamlessly and automatically since you’ve already configured the billing provider with Moesif.Setting up a Usage Multiplier/TieringIf required, you can optionally multiply your usage by a ratio in your selected billing provider. Depending on the billing provider chosen, this can be done in a few ways. For instance, you may want to charge a set rate per 100 API calls. One of the most common ways to do this is to set up tiered pricing or volume pricing.Depending on the billing provider you’re using, each offer their own mechanisms for implementing such a pricing model. Below are the corresponding links for common billing providers that work with Moesif:  Stripe Quantity Transformation  Chargebee Pricing Models  Recurly Billing Models  Zuora Billing ModelsAdding Billing CriteriaWhen you create a Billing Meter, you must establish what criteria you want to bill on. To do so, specify your criteria using the filters in the Filters pain and the metrics in the Metric pane.For example, the following meter bills on all API calls that return an HTTP 200 OK  status code.Adding a Custom or Scripted FieldIf a field does not exist in your request or response that you want to bill on, you can compute and create the field using a script. For more information, see Scripted Fields for Billing Meters.Usage ReportingFor most integrations, the usage is synced to the provider at an optimal rate. Typically, this is every 15 minutes. However, some providers requiresyncing at a slower rate like daily to ensure API and data limits are not breached.",
      "url": " /metered-billing/creating-billing-meters/",
      "author": "Matthew",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-managing-billing-meters": {
      "title": "Managing Billing Meters",
      "content"	 : "This page describes how you can manage your existing Billing Meters.Select the Billing Meters menu item in the navigation menu to open the Billing Meters screen.The Billing Meters screen shows you a list of all billing meters that you have created. From here, you can manage your meters and perform actions like editing, cloning, and archiving meters.Edit and Update Existing Billing Meters  Select Billing Meters from the navigation menu.  Select the name of the Billing Meter you want to update. Alternatively, select ⋮ Actions for the Billing Meter you want to udpate and then select View Details.  Make your edits.  Select Update.You can only update the name, status, and price of a Billing Meter. To ensure proper audit history, the rest of the Billing Meter details become locked out of any further changes once you create the meter.Enable and Disable Billing Meters  Select Billing Meters from the navigation menu.  Select the name of the Billing Meter you want to enable or disable and then select the On | Off toggle. Alternatively, for the Billing Meter you want to enable or disable, select the corresponding toggle in the State column.Archiving a Billing Meter  Select Billing Meters from the navigation menu.  Select ⋮ Actions for the Billing Meter you want to archive and then select Archive.  Select Archive Billing Meter to confirm.Keep the following in mind when you archive a Billing Meter:  For audit reasons, you cannot delete a Billing Meter.  Once you archive a Billing Meter, you cannot enable the Billing Meter again.If you simply want to just make the plan inaccessible for a temporary period, disable the meter instead.Cloning a Billing Meter  Select Billing Meters from the navigation menu.  Select the name of the Billing Meter you want to clone.  Select Copy.  Make your edits.  Select Create.Alternatively, select ⋮ Actions for the Billing Meter you want to clone and then select Clone.",
      "url": " /metered-billing/managing-billing-meters/",
      "author": "Sakib",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-choosing-a-billable-metric": {
      "title": "Choosing a Billable Metric",
      "content"	 : "What is a Billable Metric?A billable metric is a measurement or unit of usage that determines the cost or pricing structure of an API service. It serves as the basis for calculating charges or fees associated with API consumption. The following are examples of common billable metrics used when charging for API usage:            Billable Metric      Description                  API Calls      Number of requests made to the API              Per User/Session      Number of unique users or sessions using the API              Data Transfer      Volume of data transferred between the API server and the client              Compute Resources      Complexity or computational resources required to process requests              Transactions/Events      Number of transactions or events processed              Feature-based Usage      Usage of specific features or functionality      These examples represent some of the commonly used billable metrics across various industries. However, it’s important to note that billable metrics can vary depending on the specific API and the goals of the API provider. To get a bit more specific, below are some common billing metrics based on industry:            Industry      Common Billing Metrics                  Finance      API Calls, Transactions, Data Transfer, Compute Resources              Communications      API Calls, SMS Messages, Voice Minutes, Data Transfer              Data Infrastructure      Data Transfer, Storage Usage, Compute Resources, API Calls              E-commerce      API Calls, Transactions, Data Transfer, Compute Resources              Healthcare      API Calls, Data Transfer, Patient Records Accessed, Compute Resources              Social Media      API Calls, Data Transfer, User Engagement Metrics, Compute Resources              Travel      API Calls, Transactions, Data Transfer, Compute Resources              IoT      API Calls, Data Transfer, Device Connections, Compute Resources      How to Determine Your Billable MetricOnce you are aware of the billing metrics available, you’ll need to decide on which billing metric(s) to apply to your API(s). To decide on a billable metric, companies can employ the following tactics to determine which are most suitable:      Business Objectives: Align the billable metric with your business objectives. For example, if the goal is to drive adoption, an API call-based metric might be suitable.        Resource Consumption: Analyze the resources consumed by API clients and determine the most relevant metric based on usage patterns. This could be API calls, data transfer, or compute resources.        Industry Standards: Research common billable metrics within your industry or similar API services to understand established practices and pricing models.        Customer Feedback: Engage with API users to gather feedback on their requirements and preferences. This can help identify the metrics that align with customer needs.        Experimentation: Consider running pilot programs or A/B testing different billable metrics to assess their impact on adoption, revenue, and user satisfaction.  Ultimately, the chosen billable metric should be fair, transparent, aligned with business goals, and provide value to both the API provider and users. You may even use more than one billable metric across your API(s) or experiment/change your pricing model as you go.How to Specify Your Chosen Billable Metric in MoesifWhen creating a Billing Meter in Moesif, the billable metric is set by using the Metrics dropdown and selecting a value. The values you can select include:            Metric      Description                  Event Count      Number of requests made to the API              Unique Users/Keys      Number of unique users or sessions using the API              Average Latency      Charge based on the APIs average latency              Request Body Count      Number of elements in the request body of the API call              Response Body Count      Number of elements in the response body of the API call              Custom Metric      If a default metric is not suitable, create/calculate a metric based on available data within your requests/responses      Once the Metric is set, the usage will be calculated based on it. This is how you can select and apply a billable metric via a Moesif Billing Meter.Metering Unique ValuesFor metering unique values, such as “Unique Users”, the billing meter configuration must work in unison with the corresponding plan and price in the billing provider.In the billing provider, you’ll want to make sure that the MAX or most recently reported value is what is used towards the billable metric. For instance, if you choose to bill monthly based on “Unique Users” in your Moesif Billing Meter and are using Stripe, you will need to make sure that the price’s Measure Usage as attribute is set to “Max of” unit(s) used every “Month”, in “$USD”.Here is an example of what this might look like in Moesif’s Product Catalog.For the Billing Meters themselves, below are two examples. The first one shows what a meter would look like for users aiming to charge based on “Unique Users” for the API. You’ll notice that for Metrics, “Unique Users” is selected as the metric to bill on.Alternatively, you may also choose to charge based on a custom unique value. Below is an example of a custom metric that will be aggregated by distinct value. In this example, for each electronic signature extracted from the URI parameter, the meter will tally the number of unique/distinct documents and charge the user for that amount.",
      "url": " /metered-billing/choosing-a-billable-metric/",
      "author": "Matthew",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-testing-billing-meters": {
      "title": "Testing Billing Meters",
      "content"	 : "Once a Billing Meter is created, it is important to test it to make sure that the integration is working correctly and that other configuration details are set up as needed in Moesif and the Billing Provider.Accessing the meter testsIf you created a new billing meter, once you click the Create button, you will be prompted to test the meter.  We generally do not suggest dismissing or skipping the tests since it can help to troubleshoot connectivity issues more easily. You can also run the tests later as well.If you have an existing meter, you can test it at any time by clicking the Test Meter button after going into the Billing Meter.Testing StepsThere are 4 parts in a Meter Test. Each of them play a critical role in ensuring that the meter is active, subscriptions are created, API calls are being added to metered usage, and that usage is syncing to the billing provider.Part 0 - PrerequisitesThe first step in the test is to ensure that the billing provider integration is enabled on Moesif and that the billing meter is active. Both of these should be enabled.  If both of the billing provider integration and billing meter are enabled, this step may be skipped by default and start the test on Part 1.Part 1 - Create SubscriptionThis step requires that you create one or more subscriptions for a customer which uses the product/price/add-on that is used on the billing meter. You will need to go into the Billing Provider and create the subscription. This will then be synced over to Moesif and the test will show as passed/completed. The subscriptions that are synced will also display in the table at the bottom of the test screen.Part 2 - Send API CallsOnce the subscription is created, you’ll then want to send API calls through for that subscription. The API calls that come into Moesif should be for the user that you created the subscription for in the billing provider. Once the API call comes into Moesif, you should see the test pass and the table at the bottom of the test populate.Part 3 - Verify ResultsLastly, the test will verify that the API call usage is synced to the billing provider. This may take a little bit of time, up to 30 minutes before this part of the test passes.Before usage is synced to billing provider and Moesif, the screen will be in a pending state look like this.Once the usage is synced to the billing provider, the test will then show as passed. At this point, the billing meter is correctly set up and ready to use.",
      "url": " /metered-billing/testing-billing-meters/",
      "author": "Matthew",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-scripted-fields": {
      "title": "Using Scripted Fields for Complex Metrics",
      "content"	 : "What Are Scripted Fields?If a field does not exist that you’d like to observe and meter, you can create a new field using a script which combines other fields in your API requests and responses. The script retroactively creates a custom field from other fields, using formulas, arithmetic, and conditional expressions. A scripted field has the following capabilities and limitations:  Only numbers, booleans, and datetime data types (treated as a number, milliseconds since epoch) are supported.  [field.path.field_name] references a field.  If field value does not exist, for numbers it defaults to 0, and for dates it defaults to the epoch. You can use [field.path.field_name|50] to set the default value.  Most mathematical functions are supported. Conditional expressions using if, else, then, and end operators are supported.  Only expressions are supported. No other variables or statements are supported.Scripted fields with body fields may take several minutes to query.Creating a Scripted FieldTo add a scripted field, follow these steps:  Select Event Count and then select { } Select Field.    Select &amp;lt;&amp;gt; Scripted Field from the Select a field list.      Write the script and then select Set. The field list following the script text box contains all the existing fields so that you can easily reference them in your script. For more information on how to write scripts, see Using the Scripting Language.      Using the Scripting LanguageWhen using Scripted Fields, you create the new field by using MoesifFieldScript. MoesifFieldScript, also referred to as MSF, is a domain-specific language designed to perform custom computations on field values from events within the Moesif platform. This language provides the ability to evaluate logical, comparison, arithmetic, and functional expressions on event fields. Additionally, it supports accessing specific keys from the event data and provides default values if the specified key is not found.Supported Constants, Operators, and FunctionsMoesifFieldScript supports a variety of different mathematical constants, operators, and functions that can be used to create a value for a custom field. Below is list of currently supported entities.Constants            type      values                  Numeric Constants      Any whole number or decimal like 123, 4.56              Boolean Constants      true or false      OperatorsArithmetic Operators            symbol      operator name/function                  +      Addition              -      Subtraction              *      Multiplication              /      Division      Comparison Operators            symbol      operator name/function                  ==      Equals              !=      Not Equals              &amp;lt;      Less Than              &amp;lt;=      Less Than or Equal              &amp;gt;      Greater Than              &amp;gt;=      Greater Than or Equal      Logical Operators            symbol      operator name/function                  and      Logical AND              or      Logical OR      FunctionsNumeric Functions            symbol      function name/functionality                  round      Rounds a number              ceil      Rounds a number up              floor      Rounds a number down              abs      Absolute value of a number              min      Minimum of numbers              max      Maximum of numbers              avg      Average of numbers              exp      Exponential function              log      Natural logarithm              pow      Power of a number              sqrt      Square root      String Functions            symbol      function name/functionality                  countSubstrings      Count of substrings in a string      ExamplesBelow are some examples of how these operators and functions can be used within a MSF expression.      To check if the value in a field, such as age, is less than 18:     [age] &amp;lt; 18            To sum the value of two fields, such as price and tax:     [price] + [tax]            To get the maximum of two fields, such as score1 and score2:     max([score1], [score2])            As a conditional expression, such as to check if status is active and return 1, otherwise 0:     if [status] == &quot;active&quot; then 1 else 0 end      Referencing One Or More Fields in The EventIn Moesif, every API event is structured as an event document with various fields, including details about the request, response, and other associated metadata. When writing expressions in MoesifFieldScript, you can access these fields using a key path. This key path is a flattened representation of the JSON structure that omits array indices and focuses only on the names of JSON keys.The schema of the event document is the same as what is provided in the event collector API. For more information on the schema, check out the API Call docsTo access specific values from the event data in MoesifFieldScript, you can use the following ways to access the value within a specific field using the fields key:  [keyName]: Accesses the value of the key keyName.  [key1.key2]: Accesses nested keys.  [keyName|defaultValue]: Accesses the key keyName and if not found, uses defaultValue.Note: Special characters in key names should be escaped with a backslash (e.g. [ or ).Accessing Top-Level FieldsIn Moesif, certain fields at the top level (those not contained in the request or response themselves), can also be accessed. For top-level fields in the event schema, such as time, user_id, and direction, MoesifFieldScript can access them directly by using their respective names. Below are two examples of such fields:  [time]: Accesses the timestamp of the request.  [user_id]: Accesses the associated user of the API call.Accessing Request and Response Body FieldsDepending on how Moesif is configured, you may be able to use request and response body fields within your  Scripted Field. For fields inside the body of the request and response objects, you can use the flattened JSON key path to access them. For example, consider an API event with the following request body:{  &quot;request&quot;: {    &quot;body&quot;: {      &quot;fields&quot;: {        &quot;name&quot;: &quot;John&quot;,        &quot;address&quot;: {          &quot;city&quot;: &quot;San Francisco&quot;,          &quot;state&quot;: &quot;CA&quot;        }      }    }  }}To access the name field in MoesifFieldScript, you could use the following:[request.body.fields.name]To access the city inside the address object, you could use the following:[request.body.fields.address.city]Accessing Fields Within an ArrayIf there are arrays within the JSON structure, the flattened key path omits array indices. Instead, it focuses on accessing the nested keys directly. This simplifies access to fields and ensures consistency in expression writing. For example, Consider an API event with this request body:{  &quot;request&quot;: {    &quot;body&quot;: {      &quot;fields&quot;: {        &quot;users&quot;: [          {&quot;id&quot;: 1, &quot;name&quot;: &quot;John&quot;},          {&quot;id&quot;: 2, &quot;name&quot;: &quot;Jane&quot;}        ]      }    }  }}To access the name of the second user, you would not use an array index. Instead, you’d access it as:[request.body.fields.users.name]It’s important to note that without array indices, this method can only access fields when the structure is known and consistent. If you need to access specific array elements, additional methods or processing might be required outside of MoesifFieldScriptWorking With DatesIn MoesifFieldScript, date values are represented as the number of milliseconds that have elapsed since the Unix epoch (January 1, 1970, 00:00:00 GMT). This numeric representation allows for easy date comparison and arithmetic operations. Below are some examples of how dates can be used within a Scripted Field.Checking If a Date is Before a Specific TimeTo check if the date in the field fields.example.date is before January 2, 1970, 00:00:01 GMT (the Unix Epoch) or the value 1000, the timestamp for this specific time in milliseconds since epoch is 1000, the expression would be:[fields.example.date] &amp;lt; 1000Calculating The Difference Between Two Date FieldsIf you have two date fields you’d like to find the difference between, you can simply use an equation in the expression to do so. For example, to find the difference in milliseconds between startDate and endDate fields, the expression would be:[endDate] - [startDate]Checking If an Event Occurred Within a Given Time PeriodTo return a boolean value of whether an event occurred within a given time period, you can calculate the difference between the current time and the event date and see if it is less than the time period you are concerned with. For example, given that there are 86,400,000 milliseconds in a day, to check if an event with the field eventDate occurred in the last 24 hours you could use the following expression:[currentTime] - [eventDate] &amp;lt;= 86400000Where currentTime is the current timestamp.Adding Days/Time to a DateIt is also possible to add days and time to a given date. For example, to add 7 days to a date value in the eventDate field, you can simply add 604800000 (the amount of milliseconds in one week) to the current value. That expression would lok like so:[eventDate] + 604800000Rounding Down to The Nearest DayIf you want to ignore the time component and just consider the date, you can use the following expression to divide the timestamp by the number of milliseconds in a day, round down to get the number of days since the epoch, and then multiply the result by the number of milliseconds in a day to get the timestamp for the start of the day.floor([eventDate] / 86400000) * 86400000Working With StringsCounting Substrings in a StringIf you want to count how many times a substring occurs in a string field, you can use countSubstrings().countSubstrings([response.body.name|&quot;&quot;], &quot;AVG&quot;)Support for ConditionalsIn the scripted field, you will be able to add in conditionals, such as an if-else statement. Below are a few examples of how conditionals can be usedAs a traditional, multi-line if-else statement:if [request.query.billable] != truethen1else2 * [response.body.usage]endor in a single-line statement:if [field.value] == 42 then 2.2 * 31 else if [field.value] &amp;gt; 42 then  1.7 * 31 else 1.2 * 31 end endBoolean operator’s can also be used within the conditional statement:if [field.value] &amp;lt; 42 and [field.value] != 0 then 1 + 2 else 2 * 3 endAnother example is as part of a mathematical function, such as log:log(if [request.body.pi] &amp;gt; 3 then    [field.value]else    1.23end)Default ValuesIf a key being queried in an expression is not found, a default value can be provided. To specify a default value you can use the following syntax:[user.age|25]In this example, if user.age is not defined, the value used will be 25.",
      "url": " /metered-billing/scripted-fields/",
      "author": "Matthew",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-set-up-reporting-only": {
      "title": "Set Up Reporting-Only Billing Meter",
      "content"	 : "This page describes how you can set up a Billing Meter for reporting usages only.OverviewYou can create a billing meter that only reports usage and doesn’t use an existing billing provider integration like Stripe to charge customers. This allows you to use a custom or internal billing solution, where Moesif only tracks, meters, and reports the usage. By combining this with Moesif’s Billing Report Metrics, you can dig deep into analyzing your product usage and the corresponding revenue.Moesif decouples metering and rating from billing providers so you can always analyze usage and how it ties to revenue, irrespective of the billing provider you utilize.Set up Reporting-Only Billing MeterTo set up a reporting-only Billing Meter, first, select Billing Meters menu item in the navigation menu and then select + Add Billing Meter. Alternatively, select + Create New in the navigation menu and then select Billing Meter fromthe API Monetization section.Then follow these steps:Step 1: Select Custom Billing ProviderIn the new Billing Meters screen, enter a name for your Billing Meter and select Custom as the billing provider. Do not select any webhooks.Step 2: Specify Plan and Price DetailsOptionally, select a Plan that Moesif attributes the usage to and the Price that Moesif meters according to. You can select from the available plans and prices, or select Add New Plan or Add New Price to create new ones.Selecting Add New Plan presents a dialog where you you need to fill out the plan details. For more information, see Select or Create a Billing Plan.Selecting Add New Price brings you to the Product Catalog Prices screen. For more information, see Creating a Price.Step 3: Select Subscription Status to Meter ForNext, in Report for Subscriptions in dropdown, select what subscription status you want to meter. For example, you may want to meter usage only for subscriptions that have an Active status. The dropdown menu has the following options:  Active  Future  In Trial  Paused  Non-RenewingStep 4: Define the Filters and MetricsLastly, define your billing criteria.After finishing these steps, select Create to finish creating the billing meter.Analyze Usage and RevenueWith the preceding steps, you now have a Billing Meter that accurately tracks, meters, and reports your product usage. After you have the reporting-only Billing Meter enabled, you can analyze your usage-based revenue according to this Billing Meter through Billing Report Metrics.You can also access the raw usage data a reporting-only Billing Meter meters through Moesif Management API and in CSV file format.Access Usage Data Through APIIn your reporting-only Billing Meter screen, select API/Export and then select Get Via API.The dialog contains the necessary instructions you need to follow to fetch usage data, including the cURL commands.To generate a Management API key for the commands, follow these steps:  In Moesif Portal, select the account icon to bring up the settings menu.  Select API Keys.  From the Management API Key section, select Read scope for events.  Optionally, set the key’s expiration time.  Select Generate Token.Get Usage Data in CSV FormatIn your Billing Meter screen, select API/Export and then select CSV Download. In the dialog that appears, select Proceed to confirm.See Also  Choosing a Billable Metric  Billing Report Metrics  Managing Subscriptions for Custom Billing Providers",
      "url": " /metered-billing/set-up-reporting-only/",
      "author": "Sakib",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-billing-report-metrics": {
      "title": "Billing Report Metrics",
      "content"	 : "Billing Report Metrics gives you aggregated metrics on billing reports history within a specific timeframe of your choice.OverviewBilling Report Metrics gives you a consolidated interface to dig deep into metrics about your existing billing meters and visualize them. It allows you to achieve the following with ease:  Understand aggregated usage and financial flows.  Save time and resource by avoiding manual auditing of meters or companies for a specific piece of information.  Quickly find active meters so you know what meters are reporting data. This allows you to debug faster—for example, reporting issues with specific meters.Access Billing Report MetricsTo access Billing Report Metrics, follow these steps:  Go to your Moesif Web Portal.  Select Billing Meters in the navigation menu.  Select Billing Reports.Alternatively, select + Create New in the navigation menu and then select Billing Reports from the API Monetization section.Specify FiltersIn the Filter pane, filter the reported usage or amount by selecting one or more billing meter data fields.The following table describes the available filters.            Filter name      Description      Example                      Company filters              company.geo_ip      Filters by the company&#39;s geographic location data like city name, timezone, and IP.      New York              company.user_agent      Filters by various user agent data.      Mozilla/5.0              company.metadata      Filters by various company metadata.      industry: SaaS              company.cohort_history      Filters by cohort history data.      SignedUpLast30Days              company.cohort_info      Filters by cohort data.      EnterpriseUsers              company.campaign      Filters by HTTP Referer data and various UTM parameters.      utm_campaign=launch              company.balance      Filters by the company subscription balance.      example.com              company.cohort_ids      Filters by the IDs of the cohorts the company is a member of.      NonEnterprise Customers              company.cohort_names      Filters by the names of the cohorts the company is associated with.      NonEnterprise Customers              company.cohorts      Filters by cohort data.      EarlyAdopters              company.company_domain      Filters by the company&#39;s domain name.      example.com              company.company_id      Filters by company ID.      0NFM-FAB8-O0S9              company.email      Filters by company email.      Quinn.A@github.com              company.initial_ip_address      Filters by the initial IP associated with the customer when they made the very first API call.      47.188.89.92              company.initial_request_route      Filters by the API endpoint the user sent their very first request to.      /api/train/model              company.ip_address      Filters by the associated IP address of the company.      47.188.89.92              company.jwt_token      Filters by JWT token.      eyJhbGciOiJI...              company.name      Filters by the company&#39;s name.      Example Inc.              company.phone      Filters by the company phone.      +1-800-555-1234              company.plan_id      Filters by the company&#39;s plan ID.      ygFVtXL9Q9              company.user_agent_string      Filters by the company user agent string.      python-sdk/1.2.1                  Billing meter filters              billing_meter_id      Filters by the billing meter&#39;s unique identifier.      664fa46e0d3ea057bfb59737              billing_meter.name      Filters by the billing meter&#39;s name.      E-Sign Req Volume - Pro                  Subscription filters              subscription      Filters by various subscription data. Contains nested filters. For example, if you&#39;re using Stripe, you can filter by Stripe Subscription object data fields.                    subscription_id      Filters by the subscription&#39;s unique identifier.      sub_1QvrEMFM2Whj9NlnHy10bBN8              subscription_item_id      Filters by the subscription item&#39;s unique identifier.      si_Ru5ynNkAtVICcA                  Plan filters              plan.id      Filters by the plan&#39;s unique identifier.      prod_ONCjqbqF720nka              plan.name      Filters by the plan&#39;s name.      Premium Plan              plan.provider      Filters by the plan&#39;s provider.      stripe              plan.status      Filters by the plan&#39;s status for the company.      active                  Price filters              price      Filters by various price data. Contains nested filters. For example, if you&#39;re using Stripe, you can filter by Stripe Price object data fields.                        Additional filters              success      Filters by the success status of the billing report.      true              status      Filters by the status of the billing report.      posted              type      Filters by the type of billing report.      usage              meter_metric      Filters by the billing meter metric value.      3              provider      Filters by the billing provider.      Stripe              currency      Filters by the currency used in the billing report.      USD              report_total_usage      Filters by the total usage reported.      5000              subscription_item_id      Filters by the subscription item ID.      si_45678      Create Grouped ChartsIn the Group By pane, you can select billing meter data fields to create a chart that displays values across multiple catagories. For example, you can select provider to break down your metrics across different billing providers like Stripe, Recurly, and so on.Specify the Metric to PlotSelect the metric value you want to plot in the chart in the Metric pane. The following metric types are available:  Metric Value  Amount  Ending Balance  Available Balance  Pending ActivityYou can select from the following aggregators for the metric:  sum  min  max  avgSpecify TimeYou can set the period of time you want the metrics of and the interval in the time control dropdowns.You can select from one of the builtin time spans, for example,Last 7 days or Last week. You can also specify the interval for the time period—for example, daily or hourly. If you want more precise control, use the relative date range or absolute date range options.Change Chart StyleYou can change how Moesif plots billing report metrics charts and toggle from one style to another. This allows you to view the metrics in multiple ways.The following styles are available:  Bar chart  Line chart  TableBar ChartA bar chart represents data with rectangular bars. The height of each bar corresponds to a quantity of the metric data and each bar belongs to a category. The categories come from the grouping you specify and each bar represents a single category.Line ChartA line chart plots your metrics by connecting the data points with lines. Each data point represents a value of the metric at a specific time period. Line charts help you visualize and understand how metrics change over time.TableThe table view shows the metrics data in a tabular format, similar to a spreadsheet.Save ChartOnce you’ve finished defining your chart settings, select Save to save your Billing Report Metrics chart.Export Chart DataYou can export the raw data of your billing report metrics chart in JSON and CSV formats by selecting Export and then selecting As JSON or As CSV. The export adheres to any filters and settings that you have applied to your chart. Therefore, make sure you’ve applied the changes you require before exporting.For example, here we define a report with the following settings:Exporting its data as JSON gives an output similar to the following:{  &quot;group_by&quot;: [    {      &quot;key&quot;: &quot;ZPW1-OL8K-4EKB&quot;,      &quot;buckets&quot;: [        {          &quot;start&quot;: &quot;2025-01-27T00:00:00.000+0600&quot;,          &quot;metric&quot;: 2,          &quot;amounts&quot;: {            &quot;USD&quot;: 0          },          &quot;ending_balance&quot;: {            &quot;current_balance&quot;: -8,            &quot;pending_activity&quot;: 0,            &quot;available_balance&quot;: -8          }        }      ]    },    {      &quot;key&quot;: &quot;8UEV-NT64-EXR3&quot;,      &quot;buckets&quot;: [        {          &quot;start&quot;: &quot;2025-01-27T00:00:00.000+0600&quot;,          &quot;metric&quot;: 6,          &quot;amounts&quot;: {            &quot;USD&quot;: 0          },          &quot;ending_balance&quot;: {            &quot;current_balance&quot;: -24,            &quot;pending_activity&quot;: 0,            &quot;available_balance&quot;: -24          }        },        {          &quot;start&quot;: &quot;2025-01-28T00:00:00.000+0600&quot;,          &quot;metric&quot;: 1,          &quot;amounts&quot;: {            &quot;USD&quot;: 0          },          &quot;ending_balance&quot;: {            &quot;current_balance&quot;: -4,            &quot;pending_activity&quot;: 0,            &quot;available_balance&quot;: -4          }        }      ]    }  ]}",
      "url": " /metered-billing/billing-report-metrics/",
      "author": "Sakib",
      "categories": "Billing"
    }
    ,
  

    "metered-billing-managing-custom-subscriptions": {
      "title": "Managing Subscriptions for Custom Billing Providers",
      "content"	 : "This document describes how you can create and manage subscriptions for custom billing providers.Subscription MetadataYou can attach subscription demographics or any custom properties that you want to relate to a subscription by storing them in a metadata object.{    &quot;subscription_id&quot;: &quot;12345&quot;,    &quot;company_id&quot;: &quot;67890&quot;,    &quot;current_period_start&quot;: &quot;2024-10-21T17:32:28.000Z&quot;,    &quot;current_period_end&quot;: &quot;2024-11-21T17:32:28.000Z&quot;,    &quot;status&quot;: &quot;active&quot;,    &quot;items&quot;: [{      &quot;plan_id&quot;: &quot;my_custom_plan_id&quot;    }],    &quot;metadata&quot;: {        &quot;subscription_type&quot;: &quot;PAYG&quot;,        &quot;subscription_tier&quot;: &quot;Pro&quot;,        &quot;quota&quot;: {            &quot;quota_limit&quot;: 1000000,            &quot;quota_period&quot;: &quot;Year&quot;        }    }}In the preceding Subscriptions object, the metadata field contains information about the specific type and tier of subscription the company has subscribed to. It also contains information about the allowed quota for that specific subscription type and tier.For more information about the Subscription fields, see the Subscriptions API documentation.Overview of API CallsMoesif Subscriptions (/v1/subscriptions) API allows you to manage your subscriptions by creating and updating them one at a time or in a batch.PrerequisitesTo use Moesif Subscriptions API, you must set your Moesif Application ID as the valueof a X-Moesif-Application-Id HTTP header when sending requests to the /v1/subscriptionsendpoints.After you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:  Select the account icon to bring up the settings menu.  Select Installation or API Keys.  Copy your Moesif Application ID from the Collector Application ID field.Endpoints  POST https://api.moesif.net/v1/subscriptions  POST https://api.moesif.net/v1/subscriptions/batchCreate or Update a SubscriptionTo create or update a single subscription, send POST request to the endpointhttps://api.moesif.net/v1/subscriptions. For example:curl --location &#39;https://api.moesif.net/v1/subscriptions&#39; --header &#39;X-Moesif-Application-Id: YOUR_COLLECTOR_APPLICATION_ID&#39; --header &#39;Content-Type: application/json&#39; --data &#39;{    &quot;subscription_id&quot;: &quot;12345&quot;,    &quot;company_id&quot;: &quot;67890&quot;,    &quot;current_period_start&quot;: &quot;2024-10-21T17:32:28.000Z&quot;,    &quot;current_period_end&quot;: &quot;2024-11-21T17:32:28.000Z&quot;,    &quot;status&quot;: &quot;active&quot;,    &quot;items&quot;: [{      &quot;plan_id&quot;: &quot;my_custom_plan_id&quot;    }],    &quot;metadata&quot;: {        &quot;subscription_type&quot;: &quot;PAYG&quot;,        &quot;subscription_tier&quot;: &quot;Pro&quot;,        &quot;quota&quot;: {            &quot;quota_limit&quot;: 1000000,            &quot;quota_period&quot;: &quot;YEAR&quot;        }    }}&#39;Replace YOUR_COLLECTOR_APPLICATION_ID with your Moesif Application ID.If the subscription doesn’t exist, Moesif creates a new one.If a subscription exists, Moesif merges the new subscription properties with the existing properties recursively. Therefore, you don’t need to resend the entire Subscription object if you only mean to update a single field.Create or Update Subscription in BatchTo create or update multiple subscriptions in a batch, send POST request to the endpoint https://api.moesif.net/v1/subscriptions/batch. For example:# You can also use wgetcurl --location &#39;https://api.moesif.net/v1/subscriptions/batch&#39; --header &#39;X-Moesif-Application-Id: YOUR_COLLECTOR_APPLICATION_ID&#39; --header &#39;Content-Type: application/json&#39; --data &#39;[{    &quot;subscription_id&quot;: &quot;12345&quot;,    &quot;company_id&quot;: &quot;67890&quot;,    &quot;current_period_start&quot;: &quot;2024-10-21T17:32:28.000Z&quot;,    &quot;current_period_end&quot;: &quot;2024-11-21T17:32:28.000Z&quot;,    &quot;status&quot;: &quot;active&quot;,    &quot;items&quot;: [{      &quot;plan_id&quot;: &quot;my_custom_plan_id&quot;    }],    &quot;metadata&quot;: {        &quot;subscription_type&quot;: &quot;PAYG&quot;,        &quot;subscription_tier&quot;: &quot;Pro&quot;,        &quot;quota&quot;: {            &quot;quota_limit&quot;: 1000000,            &quot;quota_period&quot;: &quot;YEAR&quot;        }    }}]&#39;Replace YOUR_COLLECTOR_APPLICATION_ID with your Moesif Application ID.If a subscription doesn’t exist, Moesif creates a new one.If a subscription exists, Moesif merges the new subscription properties with theexisting properties recursively. Therefore, you don’t need to resend the entire Subscription object if you only mean to update a single field.",
      "url": " /metered-billing/managing-custom-subscriptions/",
      "author": "Sakib",
      "categories": "Billing, Subscriptions"
    }
    ,
  

    "credit-tracking": {
      "title": "Introduction to Usage Credit Tracking &amp; Consumption",
      "content"	 : "As part of Moesif’s API Monetization features, Moesif can internally track credit balances and usages.Many billing platforms have hard limits on how often usage can be reported, meaning that we encounter a delay when pre-paid credits burn down. This makes real-time credit tracking almost impossible, especially for high-volume APIs. However, Moesif can update the API users’ balance in real time since Moesif receives traffic in near real time. Moesif can also calculate the cost of each API call based on a Billing Meter and automatically decrease the corresponding amount from the users’ remaining balance.This allows you to still use platforms like Stripe or Zuora to process payments, do financial reporting, and so on. At the same time, you can leverage Moesif to allow or disallow access to an API in real time based on a user’s actual available balance. You to get the best of both worlds:  Handle the financial aspects of API monetization on your favorite billing platform  Enable consistent and dependable pre-paid API monetization through Moesif’s Credit Tracking feature.Implementation NotesThee balance ledger in Moesif differs from that of the billing provider. Therefore,if a user has topped up their account balance in a platform like Stripe, it doesn’t automatically updates in Moesif. This allows the maximum flexibility and users to customize their monetization approach as much as possible.There are ways to automate this process so that top-up amounts added within the billing provider will be automatically added to the Moesif balance. This can be done via API and the exact mechanisms are covered on the Managing Credits docs page. To guide users towards a few ways they can do this, we have created an example with Stripe that shows users three distinct ways they can automate this process. These include:  Using Stripe’s Webhook functionality to intercept a payment_intent.succeeded event and calling the Moesif Credit Tracking API to add the top-up balance on the Moesif side.  Creating a /top-up endpoint that takes a Stripe Customer ID and a top-up amount. The endpoint will create a payment intent, process it on the Stripe side, and then add this balance to Moesif.  A final example showing how to use an API for the top-up in Stripe (using a payment intent) and a webhook to asynchronously add the credits to Moesif when the payment intent has succeeded.Navigating to Credit Tracking ScreensTo use the Credit Tracking functionality, simply go to the Company Profile page for the company you would like to manage or report on. You will then see that the company’s profile will allow you to manage their credits:And it will also allow you to report on their consumption.For more info on managing and reporting on credit consumption, check out the docs pages on both subjects.",
      "url": " /credit-tracking/",
      "author": "Matthew",
      "categories": "Billing, Credit Tracking"
    }
    ,
  

    "credit-tracking-managing-credits": {
      "title": "Managing Usage Credits",
      "content"	 : "Managing credits in Moesif is easy to do and can be done through the Moesif UI, via a Company Profile, or through Moesif’s API. Unlike many billing providers, which manage an available balance at the customer level, Moesif can segregate available funds based on subscription.For instance, a company may be subscribed to two pay-as-you-go plans. They would like to add $100 to plan A and $1000 to plan B. Traditionally, when managed at the billing provider level, this would just be shown as an available balance of $1100 at the customer level that could be freely spent between subscriptions. This makes it hard to control spending for a specific subscription if you have multiple. With Moesif, you can add the balance to each specific subscription to ensure that spending is controlled at the subscription (or service) level.Usage Credit FieldsWhen managing your customer’s balances in Moesif, there are three fields and values that a company’s profile contains to be aware of.Current BalanceThis value is the current balance without factoring in any pending activity/transactions that have not been processed yet.Pending ActivityThis is the activity/transactions (credits or debits) that have not yet been posted. This value is mutable and the value can change up until the transaction is posted. Once posted, this will be reflected in the updated Current Balance field and removed from the amount under Pending Activity.For example, if there is API usage or credits that have been added to an account, you will see the corresponding amount here until it has been posted.Available BalanceFrom a usage perspective, this amount is the most important as it dictates what credits a user has left to spend, in a pre-paid scenario. This value is the amount of credits/$ that are left for the user to consume. This amount is equal to (Current Balance + (plus) Pending Activity).For example, if my current balance is $1000 and I have a $250 debit transaction pending, my available balance will be $750. Below is a table to demonstrate this:            Field      Value                  Current Balance      $1000              Pending Activity      $250              Available Balance      $750      Credit Balance BehaviorStripe doesn’t support prepaid subscriptions. To help you implement prepaid credits-based systems easily with Stripe, Moesif supports automatic application of credits to Stripe invoices. It builds on top of Moesif’s real-time credits consumption and usage tracking system.Key Features  Automatically apply credits to Stripe invoices.  Customize behavior for zero credit balance.Limitations  Only supported for Stripe.  Only supported for per-unit and package pricing.How It WorksThis feature automatically applies credits to Stripe invoices.When creating a Billing Meter, you can choose between these options to control how Moesif applies credits:Bill Customer (Default)This option creates Stripe credits for the customer if a positive subscription balance  exists in Moesif. Specifically, the Available Balance must have a positive amount.Stripe credits the customer’s credit balance by the specific usage amount it receives from Moesif. The credit adjustment amount can go up to the amount of subscription balance you have. After the adjustment, Stripe then applies the remaining balance to the finalized invoice.Here’s an example that walks you through how this option works:  You have $20 as Available Balance in Moesif. You also have an active subscripiton that expires at a certain time.  While your subscription is active, Moesif tracks a $12 usage for your subscription. It meters the usage and sends the usage details to Stripe.  Stripe creates an invoice for the usage.          Assume that the positive $20 Available Balance still exists at the time Moesif sends the usage.                  Stripe performs a credit adjustment of $12 against the credit balance. Your remaining balance comes down to ($20-$12) = $8.          Stripe finalizes the invoice for $0.                    If the subscription balance goes to $0, or below $0, or no balance exists, Stripe doesn’t apply any credits. Rather, it invoices the customer for the full usage amount $12.      The following table shows some more example scenarios with different amounts:            Available Balance      Usage      Stripe credits      Invoice                  $20      $5      $5      $0              $20      $20      $20      $0              $20      $27      $20      $7              $0      $27      $0      $27              -$5      $27      $0      $27      Example Use CaseA hybrid model where customer can pay in advance for credits, but you want to bill overage charges in a postpaid manner. In addition, the postpaid amount can differfrom the discount for prepaid credits.Zero Out InvoicesThis option always creates Stripe credits to balance usage. Moesif sends the usage amounts as usual, but invoices will be zeroed out with credits. This option allows you to invoice customers manually or through another system. Choose this option if you want to use Stripe for usage monitoring only and use an alternative method for billing or invoicing.This option works the same way as Bill Customer, except that the amount of credits always equals the usage amount. Here’s a table showing some example scenarios:            Available Balance      Usage      Stripe credits      Invoice                  $20      $5      $5      $0              $20      $20      $20      $0              $20      $27      $27      $0              $0      $27      $27      $0              -$5      $27      $27      $0      Example Use CaseIf your sales team negotiates with customers for upgrades or custom pricing, you may not want to automatically bill them for overages or cancel their subscription due to insufficient credits. Once you reach an agreement for an upgrade, you manage credits directly.Invoice Credit BehaviorFor per-unit and package-based pricing in Stripe, you can control whether Moesif automatically applies prepaid credits to Stripe invoices through the Invoice Credit Behavior options in a billing meter.  Auto Credit  Default. Moesif applies credits to Stripe invoices according to the option selected in Credit Balance Behavior.  Track Only  Disables automatic application of credits. Moesif only tracks credit balances internally and does not apply Stripe credits to Stripe invoices. Usage still burns down credits; governance rules, like blocking customers at zero balances, continue to apply.The Track Only option allows you to track Moesif balance ledger as it depletes with consumption, providing a means to track usage and revenue in prepaid pricing schemes without having to affect or modify Stripe invoices.",
      "url": " /credit-tracking/managing-credits/",
      "author": "Matthew",
      "categories": "Billing, Credit Tracking"
    }
    ,
  

    "credit-tracking-credit-usage-reporting": {
      "title": "Credit Usage Metrics &amp; Reporting",
      "content"	 : "Within every company profile in Moesif are multiple charts that can help with analyzing and reporting on credit usage and transactions. To access these reports, navigate to the company’s profile (either by clicking on the Company’s ID within a report in Moesif or by going through the Company Lookup screen).On the company profile, underneath the profile fields display, click on Billing Usage. This area will show multiple charts that can help you to understand billing usage for this particular account. By default, the screen will show the Billing Usage and Subscription Balance time series reports.You can also toggle between chart styles by using the chart-type selector at the top of the chart. By clicking the table view button, you will then be presented with a table outlining all transactions. Clicking the graph view button will bring you back to the Time Series charts originally displayed.Billing Usage Report (Time Series)The Billing Usage report shows usage per Billing Meter across all subscriptions that a company has. In the top left of the pane, use the Meter menu to choose the meter that you would like to report on. The output of this chart is a time series report that shows Reported Usage (the actual events that have been recorded by the meter) and Amount (the $ value of the events, as calculated by the meter).The time series Billing Usage report also allows the following actions through thhe charg utilities::  View the associated event logs by selecting View Events.  Filter by billing report status by selecting Filters.  Choose the aggregation operator for the usage data.Billing Usage Report (Table View)In the table view of the Billing Usage report, you will be able to view all transactions in a nicely laid out table. This will show every transaction in detail and can also be filtered by Meter and Subscription using the dropdowns at the top of the report.At the bottom of the table, you can see aggregation data about usage:You can customize how the table view displays data and access further information by using the following utilities:  View the associated event logs by selecting View Events.  Filter by billing report status by selecting Filters.  Select what fields to display in the table view by selecting Edit Columns.  Choose the aggregation operator for the usage data.Subscription Balance ReportThe Subscription Balance report shows usage across all Billing Meters for a particular subscription that a company has. To view the subscription balance report, select the time series view of billing usage report.In the top left of the pane, under Subscription, you can choose the subscription that you would like to report on. The output of this chart is a time series report that shows the three balance factors within the Moesif ledger: Current Balance, Pending Activity, and Available Balance.",
      "url": " /credit-tracking/credit-usage-reporting/",
      "author": "Matthew",
      "categories": "Billing, Credit Tracking"
    }
    ,
  

    "credit-tracking-creating-credits": {
      "title": "Creating Usage Credits",
      "content"	 : "This document describes how to create credit transactions in Moesif using Moesif Web Portal and Moesif Management API.OverviewYou can add four types of records to the Moesif credit ledger:  Debits  Credits  Promotions  AdjustmentsDebit records are usually associated with usage. These records draws down the available balance.Credit records are usually associated with top-ups where users have added funds to the system. These records increases the available balance.You can add records either from the Company Profile page in Moesif Web Portal or the Moesif Management API. The UI gives users a way to manually add in credits while the API can help with those who are looking for audtomation, such as automatically adding credits to the Moesif ledger when a transaction happens on the billing provider side. For instance, if $10 in credits is added using Stripe, you could detect this, likely using Stripe’s webhook, and use the Moesif API to automatically add the $10 to Moesif’s ledger.Adding a Transaction Record using Moesif Web Portal UITo add a Credit record for a subscription, navigate to the Company’s profile. You can do this by clicking on the Company ID throughout various reports or by looking the company up through Company Lookup and going to their profile.In the company’s profile beside the Current Balance field, click on the pencil/edit icon.This will bring up the Add Transaction modal.The following table describes the information this modal contains:            Field Name      Description                  Subscription Id      The subscription you would like to apply the transaction towards. This dropdown will contain all of the subscriptions that the company is subscribed to.              Type      The type of transaction you want to post to the account. This value, selected from the dropdown, can be either Credit, Debit, Promotion, or    Adjustment.              Transaction Id      A unique ID that Moesif will use to deduplicate any transactions. You can either use the value provided or enter your own. An example of a custom ID here may be using the Stripe Payment Intend ID of the transaction that you handled in Stripe.              Active at (Optional)      An optional field for a credit transaction. Moesif applies the credits to the subscription balance after the time you specify here. Note that the subscription balance itself does not automatically update after the activation time. It updates when Moesifi sends more usage or after you create another balance transaction.              Expire at (Optional)      An optional field for a credit transaction. It specifies when the credits expire. Any remaining credits become unusuable. Based on your usage amount, Moesif creates a new balance transaction to subtract the remaining credits from the subscription balance. If no usage occurs before the expiration date, Moesif subtracts the full credit amount. Otherwise, Moesif subtracts the remaining credits. For example, assume that you’ve created a balance transaction of $100 credits that expire sometime in the future. Before the expiration date, Moesif tracks and meters a usage of $4. When the credits expire, Moesif subtracts the remaining $96 credits from the balance.              Amount              The amount of the transaction in major currency units, for example, dollars instead of cents. The amount can be positive or negative depending on the  Type:                   For Credit type, the amount is positive.          For Debit type, the amount is negative.          For Promotion type, the amount is positive.          For Adjustment type, the amount can be either positive or negative.                            Description (Optional)      An optional field where you can add a description for the transaction. This will only be stored internally but can be useful for audit purposes.      Once you have added this info, you will see how the transaction will affect the company’s balance in the Balance Preview. Here you will be able to see the results of the transaction on the company’s Available Balance.To add this transaction, click the Add Transaction button.Add a Transaction Record using APITransactions can also be added via API. This can be done using the Moesif Management API’s /billing/reports/balance_transactions endpoint. More details on the API can be found within the API Docs for the endpoint.A Moesif Management API token is required for this action that includes the following scopes:  create:billing_meters  create:billing_reportsBelow is an example of how the API could be used within a Node application.const body = {  company_id: &quot;cus_1234abc&quot;, // The Company ID within Moesif  amount: 100.0, // amount in dollars (i.e. major currency unit)  expire_at: &quot;2025-01-09T17:18:58.560Z&quot;, // credit expiration date  active_at: &quot;2025-01-09T17:18:58.560Z&quot;, // the activation time for the credit transaction   type: &quot;credit&quot;, // transaction type (credit, debit, promotion, etc.)  subscription_id: &quot;sub_456def&quot;, // Subscription ID within Moesif  transaction_id: uuidv4().toString(), // random transaction ID or external/custom one  description: &quot;top up from API, post Stripe top-up event&quot;, // optional, description of the transaction};try {  const response = await fetch(    &quot;https://api.moesif.com/~/billing/reports/balance_transactions&quot;, // API URL    {      method: &quot;POST&quot;,      headers: {        &quot;Content-Type&quot;: &quot;application/json&quot;,        Authorization: &quot;bearer ey13aDfgT567...&quot;, // Moesif Management API Token, including scope for create:billing_meters, create:billing_reports      },      body: JSON.stringify(body),    }  );  if (response.ok) {    console.log(&quot;Balance transaction created successfully&quot;);  } else {    console.error(      &quot;Failed to create balance transaction!&quot;,      response.status,      response.statusText,      await response.json()    );  }} catch (error) {  console.error(&quot;An error occurred while creating balance transaction:&quot;, error);}This API call creates the same transaction as the UI does but you can use the API approach to automate processes that leverage the Moesif credit ledger.For debit notes, an example body is shown below:const body = {  company_id: &quot;cus_1234abc&quot;, // The Company ID within Moesif  amount: -100, // amount in dollars (i.e. major currency unit)  type: &quot;debit&quot;, // transaction type (credit, debit, promotion, etc.)  subscription_id: &quot;sub_456def&quot;, // Subscription ID within Moesif  transaction_id: uuidv4().toString(), // random transaction ID or external/custom one  description: &quot;monthly fee&quot;, // optional, description of the transaction};",
      "url": " /credit-tracking/creating-credits/",
      "author": "Sakib",
      "categories": "Billing, Credit Tracking"
    }
    ,
  

    "behavioral-emails": {
      "title": "Introduction to Behavioral Emails",
      "content"	 : "Moesif’s Behavioral Emails gives you smart email automation easily. Behavioral Emails enable you to notify your customers when they meet certain criteria. For example, exceeding quota limits, billing notifications, running into integration errors, and so on.Powered by our Behavioral Cohorts feature, you can easily create dynamic email lists and even recurring email workflows. You can design customer emails within our HTML email template editor and pick which cohorts of users receive your email.To access Moesif’s Behavioral Email feature, select the Behavioral Emails menu item from the navigation menu.Alternatively, select + Create  New and then select Behavioral Email from the User Guidance &amp;amp; Alerts section.Benefits and Use CasesBehavioral Emails works as a great complimentary feature of Moesif as an API analytics platform. It offers you a unified interface where you can be proactive about user experiences based on product statistics, without the need to jump into another platform for smart email automation.Since Behavioral Emails are powered by Behavioral Cohorts, you can accurately track your customer’s journey as they use your product by targeting their behavior and usage patterns.Moesif itself doesn’t enforce any sending restrictions for Behavioral Emails. You can create and configure as many email templates as you want for different use cases and manage them from the same place. Behavioral Emails works out-of-the-box with SMTP-compatible email providers like SendGrid and AWS SES, allowing you to reuse your same DomainKeys Identified Mail (DKIM) authentication and unsubscribe lists.You can create beautifully designed and responsive email templates using the components and modules available in the email editor. We have extensively tested with Litmus and Email On Acid to ensure proper rendering in different email clients. You can also preview your emails and how they look on desktop and mobile screens.Behavioral Emails can serve different use cases for you without any manual work and investment in heavy engineering resources. For example:  Automatically notify customers of important API issues like approaching rate limits, exceeding plan quotas, using deprecated endpoints, and so on.  Create beautiful HTML templates with compelling UI that grab your customers’ attention.  Use recurring workflows and re-enrollment to avoid spam and be consistent with important updates. For example, exceeded quota warnings and monthly billing reminders.How Behavioral Emails WorkThe Behavioral Emails workflow follows this pattern:  Behavioral Emails is powered by Moesif’s Saved Cohorts. A saved cohort defines a dynamic list of users that matches specific criteria. When a user is added or removed from a cohort according to the specified criteria, it triggers an automated email workflow.  Moesif generates an HTML-based email. To populate the email with relevant information, Moesif uses an email template that the user has defined.  Next, Moesif forwards the actual email to your email service provider (ESP).Moesif allows you to use your existing email provider (ESP) such as SendGrid, Amazon SES, or Mailgun to send emails while maintaining your existing deliverability rates. By using your existing provider, you can maintain your existing DNS configurations, dedicated IP addresses, unsubscribe lists, and other settings.Moesif sends emails through your email provider using your SMTP credentials. Most providers provide SMTP credentials to their users in their documentation.Alternative to Behavioral EmailsAlternatively, you can connect to an existing marketing tool like HubSpot or Pendo. This enables you to sync any data in Moesif users or companies to their respective entity in the CRM or marketing tool. Keep in mind that since most marketing tools cannot handle event data, Moesif provides a way to save cohorts of users based on their behavior. For example, users who have made over a hundred API calls in the last five days. Moesif also synchronizes changes to the marketing tool for easier targeting.You can also leverage embedded dashboards to guide your customers. This allows you to embed API logs, SLA metrics, and other charts in your customer-facing portal. Your Moesif account powers all the data, meaning you can save on cloud costs along with development time.Related ArticlesFrom Moesif  How To Set Up Sendgrid with Moesif - Tutorial  How To Set Up Mailgun with Moesif - Tutorial",
      "url": " /behavioral-emails/",
      "author": "Derric",
      "categories": "Communication"
    }
    ,
  

    "behavioral-emails-setup-smtp-authorization": {
      "title": "Set up SMTP",
      "content"	 : "To send emails using Behavioral Emails, you must first add an email server for your email service provider (ESP). This involves specifying the Simple Mail Transfer Protocol (SMTP) credentials for your ESP.Configuring Your SMTP SettingsTo add an email server, follow these steps:  Select Behavioral Emails menu item from the navigation menu.  Select Edit Email Server.  Fill in the SMTP credential fields.  Select Save.You can edit these settings anytime you want by selecting Edit Email Server again from the Behavioral Emails screen.Most email service providers provide credentials to enable access to their API using SMTP. For more information, see your email service provider’s documentation.If you have a Gmail for Business account, you can also test with those SMTP credentials. However, we don’t recommend it for high volume email.Testing Your SMTP ConfigurationBefore you can create a new email template, you must already have a saved behavioral cohort.To test your SMTP configuration, follow these steps to make sure that you can send emails successfully:  Select Behavioral Emails menu item from the navigation menu.  Select + Create Template.  Select a blank or pre-configured template.  Enter the necessary details and select a behavioral cohort from the Send To list.  Select Test and then specify the email address you want to send the test email to.  Select Send.For more information about creating email templates, see Create an Email Template.Related ArticlesFrom Moesif  Saved Cohorts - Documentation  Creating Saved Cohorts in Moesif - TutorialOther  Obtaining SMTP Credentials from Mailchimp - Documentation  Obtaining SMTP Credentials from Amazon SES - Documentation",
      "url": " /behavioral-emails/setup-smtp-authorization/",
      "author": "Dylan",
      "categories": "Communication"
    }
    ,
  

    "behavioral-emails-setup-behavioral-emails": {
      "title": "Set up Behavioral Emails",
      "content"	 : "This document explains how to create behavioral emails by defining your email template settings and using the email editor to build beautiful, responsive email designs.PrerequisitesBefore you can create a new email template, you must already have a saved behavioral cohort.Create an Email Template  Select Behavioral Emails menu item in the navigation menu and then select + Create Template.    Alternatively, select + Create New from the navigation menu and then select Behavioral Emails from the User Guidance &amp;amp; Alerts section.  Select + Create Template.      You have the option to start from blank or choose from a set of predefined templates for different use cases. Select the one that suits you.    If you select a predefined template, Moesif asks for your confirmation to create the suitable user cohort for that email template. The cohort defines the audience to send emails to. Select Continue to confirm.  If you choose to start from blank, you must create the user cohort by yourself.Each email template is disabled by default when you first create them. To enable them, select the On | Off toggle to the on position.Define Email Template SettingsIn the template editor, fill in the necessary information to define your email template.Template NameYou must specify a name for your email template in the Email Template Name field.RecipientYou must specify who you want to send emails to by selecting one or more saved user cohorts from the Send To list. If you choose a predefined email template, Moesif creates the appropriate cohort for you.A saved user cohort is a dynamic group of users that matches one or more criteria. For example, a cohort can represent users who’ve made over a hundred API calls in the last five days from Node.js.The email will be triggered when the user is added to the cohort.Subject LineYou must specify your email subject line in the Subject Line field.Sender Address and NameIn the From Address field, you must specify the email address who you want to send email as. To ensure the best email deliverability, configure your domain correctly for DomainKeys Identified Mail (DKIM) and Sender Policy Framework (SPF) email authentication methods in your email provider.Optimally, specify a user-friendly name that your recipients see when they receive emails from you in the From Name field.Cc and BccYou can also add Cc and Bcc addresses in the CC and BCC fields respectively. Many CRMs provide a Bcc address so you can log any customer communication right in your CRM.Recurring WorkflowNormally, a user can only receive the same email once. However, you can make the template recurring by selecting the Recurring Workflow checkbox.You can re-enroll users who will again meet your cohort criteria into this email workflow. Recurring workflows can help you in different situations—for example, exceeded quota warnings, monthly billing reminders, and so on.If you set the workflow as recurring, you must define the time period that must pass before a user becomes eligible for receiving email again. Re-enrollment happens when a user is added to the cohort again after the specified time period has elapsed. For example, if you want to create a workflow that sends warning emails to any customer who has exceeded their subscription quota. you can define the re-enrollment period as 15 days. The user will receive another email if they are added to the cohort again after that 15-day period has passed.The Email EditorThe Email Editor allows you to build beautiful and responsive emails using drag and drop modules and components. We have tested the templates extensively with Litmus and Email On Acid to ensure rendering in a variety of email clients.The following sections discuss the features of the email editor.Content ModuleThe components in the Content module contain several options to design the content of your emails.The following components are available:  Columns  Buttons  Divider  Heading  HTML  Image  Menu  TextWhen you select a component, you can customize the look and feel of the component for desktop and mobile screens from the Desktop and Mobile tabs.ColumnsUsing the Columns component, you can add columns in your email for better design arrangement. This component contains the following customization options:  Columns  How many columns you want in a specific row.  Column Properties  The background color, padding, and border of columns.  Row Properties  Allows customization of the following row properties:          Background color      Content background color      Background image      Padding        Responsive Design  A toggle to show or hide the column in a row on desktop screens.ButtonsThe Buttons component allows you to add buttons to your emails. It contains the following customization options:  Smart Buttons  AI to generate helpful suggestions to make buttons more effective for different use cases.  Action  The type of action the button performs. For example, opening a new URL, sending email, and calling a phone number.    Select the action from the Action Type list and fill in the necessary details of the action. For example, if you choose Send Email, specify the recipient email address, email subject, and email body.    Columns  How many columns you want in a specific row.  Button Options  Allows customization of the following button properties:          Text color      Background color      Font family      Font weight      Font size      Alignment      Width        Spacing  Line height, padding, and border of a button.  General  The padding of a button’s container.  Responsive Design  A toggle to show or hide a button on desktop screens.DividerThe Divider component lets you add spacing between components of your email. It’s equivalent to the &amp;lt;hr&amp;gt; HTML horizontal rule element. This component contains the following customization options:  Line  Allows customization of the following properties:          Width      Line type and thickness      Alignment        General  The padding of the divider’s container.  Responsive Design  A toggle to show or hide a divider on desktop screens.HeadingThe Heading component lets you add four levels of section headings. It’s equivalent to the &amp;lt;h1&amp;gt; to &amp;lt;h4&amp;gt; HTML heading elements. This component supports the following customization options:  Smart Headings  AI to generate helpful suggestions to make headings more effective for different use cases.  Text  The heading text. You can customize the following text properties:          Heading level from H1to H4      Font family      Font weight      Font size      Color      Text align      Line height        Links  Allows you to customize the appearance of a hyperlink in a heading. Turn off the Inherit Body Styles toggle to apply your custom styling.  General  The padding of a heading’s container.  Responsive Design  A toggle to show or hide a heading on desktop screens.HTMLThe HTML component lets you add custom HTML to further customize the design beyond what you can do with the other tools. This component has the following options:  HTML  The textarea to type in custom HTML.  General  The padding of the container.  Responsive Design  A toggle to show or hide the HTML on desktop screens.ImageThe Image component allows you to add images in your emails. It supports the following options:  Magic Image  Use AI to generate custom images.  Image      Lets you add images from different sources:          Your local machine      Image URL      Stock photos from providers such as Unsplash, Pexels, and Pixabay        Action  You can make an image interactive like a button and have it perform an action when a user interacts with it. For example, opening a new URL, sending email, and calling a phone number.    Select the action from the Action Type list and fill in the necessary details of the action. For example, if you choose Send Email, specify the recipient email address, email subject, and email body.    General  The padding of the container.  Responsive Design  A toggle to show or hide an image on desktop screens.MenuThe Menu component lets you add navigation menus. It contains the following options for customization:  Menu Items  The menu items in a menu.    Select Add New Item to add a menu item. For each menu item, you can select the menu text and the action it performs when a user interacts with it. For example, opening a new URL, sending email, and calling a phone number.    Select the action from the Action Type list and fill in the necessary details of the action. For example, if you choose Send Email, specify the recipient email address, email subject, and email body.    You can also change the order of menu items by drag and drop. To delete a menu item, select Delete.    Styles  Lets you customize the following properties of the menu:          Font family      Font weight      Font size      Text color      Link color      Alignment      Layout      Padding        General  The padding of the container.  Responsive Design  A toggle to show or hide a menu on desktop screens.TextThe Text component lets you add text with a full suite of different styling options. The following options are available:  Text  Lets you customize the following text properties:          Font family      Font weight      Font size      Text color      Text align      Line height        Links  Allows you to customize the appearance of a hyperlink in your text. Turn off the Inherit Body Styles toggle to apply your custom styling.  General  The padding of the container.  Responsive Design  A toggle to show or hide text on desktop screens.Layout BlocksThe Blocks component can help you structure your email template. They are containers that can hold content components and make designing a layout easier—for example, defining a layout that uses multiple columns with varying widths.BodyThe Body component provides general configuration and styling options for your email templates. For example, defining the link color, text alignment, and content width. The options you specify here apply globally. You can override any property of an individual component using the component’s available options.The following options are available:  General  Lets you customize the following properties:          Text color      Background color      Content width      Content alignment      Font family      Font weight        Email Settings  Lets you add email preheader text. A preheader is the short summary text that follows the subject line when a user views an email in their inbox.  Links  Lets you customize the appearance of links.ImagesThe Images component lets you search for images across sources like Unsplash, Pexels, and Pixabay. You can also generate images using AI.After you find an image, drag and drop the image into an image component to add it to your email template.Merge TagsMerge tags lets you personalize email for each user. You can insert merge tags into a block of text by selecting Merge Tags from the text editor menu bar.You can insert analytics field, including custom metadata, into the email such as the name of the user or their plan. The following predefined event metrics are available in Merge Tags &amp;gt; Cohort Metrics:  Event Count  Avg Elapsed Time  Top Request Routes  Top Response Status Codes  Top User-Agent NamesYou can also add custom usage metrics using merge tags.Adding Custom Metrics with Merge TagsYou can add aggregated event metrics into the email body using merge tags. These custom metrics can help with sending emails that have tailored quota and usage content.Depending on the data type within the field, you can access certain operations or aggregations.The following table summarizes the available aggregator types for different data types:            Operation      Result      Applicable Data Type(s)                  Top Terms      returns an array of the top terms within the aggregated events      string              Min      returns the min value from the aggregated events      number, date              Max      returns the max value from the aggregated events      number, date              Average      returns the average value from the aggregated events      number, date              Sum      returns the sum of the value from the aggregated events      number, date      LimitationsCustom metric tags have the following limitations you need to keep in mind:  The target cohort must have a behavioral criteria defined in the Who Performed filter.  The email can have only one target cohort as the email’s destination.  You can define only five custom metrics. If you define a metric but don’t use it in the email as a merge tag, Moesif doesn’t save that particular metric.  Custom metrics do not support aggregating request or response body.Create a Custom Metric Merge TagTo add custom metrics within an email, you must first define the custom metric merge tags:  Select Define Custom Metric Merge Tags.    In the dialog that appears, select the custom metric field and the aggregator function. The aggregator functions you have access to for each merge tag depends on the data type of the associated metric field. For example, for numeric metric fields, the following aggregator functions are available:          Min      Max      Average (Unweighted)      Sum (Unweighted)        You can add up to five custom metric merge tags.    Select Set Merge Tags.Now you can reference reference the merge tags in the email body. In the email editor, select your custom merge tags by going into the text editor, clicking in a text area, and selecting the custom merge tag from the Merge Tags &amp;gt; Cohort Metrics dropdown menu.Related ArticlesFrom Moesif  Saved Cohorts - Documentation  Creating Saved Cohorts in Moesif - TutorialOther  Unlayer Email Builder - Documentation",
      "url": " /behavioral-emails/setup-behavioral-emails/",
      "author": "Derric",
      "categories": "Communication"
    }
    ,
  

    "behavioral-emails-manage-behavioral-emails": {
      "title": "Manage Behavioral Emails",
      "content"	 : "The Behavioral Emails screen allows you to manage all your existing behavioral email templates. To access the screen, select the Behavioral Emails menu item from the navigation menu.The Behavioral Emails screen shows you a list of all behavioral email templates that you have created.It shows the following details for each email template:  The template name  The one or more saved user cohorts that receive the email  The email subject  The sender email address  Last modification date and time  Creation date and timeThe ⋯ Actions menu allows you to clone, test, and delete an email template.Edit and Update Existing Emails  Select Behavioral Emails from the navigation menu.  Select the name of the email template you want to update.  Make your edits.  Select Save.Clone an EmailTo make a copy of an existing email template, follow these steps:  Select Behavioral Emails from the navigation menu.  For the email template you want to make a copy of, select ⋯ Actions and then select Clone.Send Test EmailTo test an email, you can manually trigger sending a test email with these steps:  Select Behavioral Emails from the navigation menu.  For the email template you want to test, select ⋯ Actions and then select Test.  Specify the email address where you want to send the test email to.  Select Send.Delete an Email  Select Behavioral Emails from the navigation menu.  For the email template you want to delete, select ⋯ Actions and then select Delete.  Select Delete again to confirm your choice.Enable and Disable EmailsTo enable or disable an email template, use the On | Off toggle in the Is Active column.",
      "url": " /behavioral-emails/manage-behavioral-emails/",
      "author": "Sakib",
      "categories": "Communication"
    }
    ,
  

    "embedded-templates": {
      "title": "Introduction to Embedded Templates",
      "content"	 : "This document explains how to use Moesif’s Embedded Templates to embed API logs and charts into customer-facing solutions.This document assumes you are familiar with Dashboards and Workspaces.What is an Embedded Metric?Moesif lets you analyze your API in many ways that can unlock valuable business insights and monetization opportunities. In some scenarios, you may want to embed those metrics Moesif generates into custom or third-party solutions to progress further in your business requirements. Embedded metrics offer secure, customizable, and flexible approaches to share or embed your metrics for various use cases.Why Use Embedded Metrics?Embedded metrics let you integrate Moesif-generated analytics data and visualizations into enterprise applications and custom workflows. In cases where charts and reports in Moesif seem valuable to other team members who don’t have or require access to Moesif, you can still share those data.The benefits of embedded metrics can span multiple domains and use cases:  Enhancing the portability of your business metrics and making them accessible to teams across and outside your company. This results in faster decision making and better proactivity.  Building consumer-facing applications that allow users to access and view their data and charts securely.  Delivering customized content improves user experience. This includes UI/UX components, filters, and chart elements.  Building custom dashboards, reports, and visualizations for consumption outside of Moesif.",
      "url": " /embedded-templates/",
      "author": "Derric",
      "categories": "Embed-Template"
    }
    ,
  

    "embedded-templates-creating-and-using-templates": {
      "title": "Creating and Using Templates",
      "content"	 : "This guide assumes you are familiar with Dashboards and Workspaces. Before following the instructions for each of the integration types, make sure you have a chart ready to embed.Integration TypesTo embed charts and metrics that Moesif generates for your API, consider your use case and choose a suitable integration type. To tailor to different requirements, Moesif supports the following integration types for embedding metrics:  Static Embed  Embed Template  Search APIStatic EmbedStatic Embed allows you to embed charts in any HTML page, user-facing applications, and internal tools like PowerBI or Tableau with just a single code snippet. Static Embed generates public links in the following formats:  An &amp;lt;iframe&amp;gt; element that you can insert in HTML pages.  A secure public link that you can share with anyone.  A passcode-protected link.The public links make it trivial to embed metrics in your website and other applications. However, the sandbox policy has some limitations since the static nature of the embed requires that Moesif knows the filters ahead of time. The charts in a static embed don’t support dynamic filters. When the metric or filter remains consistent in your use case, a static-embedded chart using a public link may work better for these cases.To use Static Embed, you must first set your chart’s sharing type to public.For instructions on how to use Static Embed, see Use Static Embed.Embed TemplateContrary to Static Embed, Embed Template is dynamic and contains dynamic fields you can programmatically fill in. This allows a more customized approach to rendering charts and metrics where the chart can accurately represent users based on each user or company’s corresponding set of dynamic properties. For example, when a user logs in, the associated user ID can work as the dynamic property for rendering the chart, ensuring that the user sees only the data that applies to them. This enables secure sandboxing and more isolation between user data.Integrating an embedded template requires implementing a backend component that can securely communicate with Moesif and generate links to embed charts using the dynamic properties. For instructions on how to use embedded templates, see Use Embed TemplateSearch APISearch API gives you access to your chart’s data using Moesif’s Management API. You send a POST request to the Management API with your Management API key as the Bearer token and the search definition for the data you want to extract. This returns a JSON object containing the chart data that you can display in a more customized format. The search definition uses the Elasticsearch Query DSL.Search API allows you to build custom solutions using your data, such as custom dashboards, reports, analytics, and so on. For instructions on how to use Search API, see Use Search API.Choose The Right Integration TypeThe following table summarizes the different aspects of the three integration types to help you choose the right one for your use case:                   Static Embed      Embed Template      Search API                  Type      Static in nature without any dynamic properties.      Contains dynamic properties that uniquely associate with each embed.      Provides access to raw chart data through API.              Shareable link      Yes.      No.      No. However, anyone can access the chart data with proper authentication credentials and authorization scopes.              Integration complexity      Very minimal as the frontend can integrate the embed using the generated links directly.      Integration requires work on both frontend and backend.      Depends on the use case of the chart data.              Sandboxing      Static and predefined.      Dynamic and programmatically adjusted during rendering.      Dependent on the search query and Management API key scopes              Use case      Embedding static charts for internal dashboards and presentations.      Securely embedding charts with dynamic or unknown criteria in customer-facing applications.      Building custom UI like dashboards, analytics pipelines, and visualization reports.      Use Static EmbedTo embed a chart using Static Embed, follow these steps from the chart window you want to embed:  Select Embed / API from the chart header.  Then select Static Embed.  In the Confirm Settings section, confirm the settings of your embed. Remember that you must set your chart’s sharing type to Public to embed using Static Embed.  The generated links are displayed in the right-hand pane under the three tabs HTML, Link, and Passcode. Select the tab you want and then select Copy or Copy Embed Code.Configuring the Sandbox PolicyThe sandbox policy dictates what criteria users can search within the chart. Any filters you have in place in your chart carry over to the static embed as constraints. To change this policy, return to the chart and configure it with the settings you want to set the sandbox policy with.Use Embed TemplateTo use embedded templates, follow these steps:  Select Embed / API from your chart window.  Then select &amp;lt;&amp;gt; Embed Template.      Fill in the necessary details in the Confirm Settings section.    a. Enter a name for your new template.    b. Select your dynamic criteria.    c. You can choose to expose header and body keys of your API requests with the Expose Header and Body Keys toggle.    Select Get Embed Code and confirm.  The next dialog shows the instructions for integrating your new embedded template into your application. The following sections discuss these steps in detail.For a step-by-step guide on how to use an embedded template using Node.js and Express, see Creating and Using Embedded Templates.Generate Workspace TokensCreate a new endpoint in your backend that programmatically sends requests to Moesif Management API for new workspace URLs using your dynamic values. For an example, see the server implementation in Moesif API dashboard embed example on GitHub.Moesif generates a cURL command for you after selecting Get Embed Code. You can use this command to send a request to the Moesif workspace API with your dynamic values.curl -X POST &#39;https://api.moesif.com/v1/portal/~/workspaces/WORKSPACE_ID/access_token?expiration=2025-01-28T10:16:15.762Z&#39; -H &#39;Authorization: Bearer &#39;MANAGEMENT_API_KEY&#39; -H &#39;Content-Type: application/json&#39; --data-binary @- &amp;lt;&amp;lt; EOF{ &quot;template&quot;: {  &quot;values&quot;: {   &quot;user_id&quot;: &quot;USER_ID&quot;  &quot;company_id&quot;: &quot;COMPANY_ID&quot;  } }}EOFThis command specifies two dynamic property values: a user_id and a company_id.The workspace API returns a workspace access token scoped to the dynamic values:{  &quot;_id&quot;: &quot;WORKSPACE_ID&quot;,  &quot;token&quot;: &quot;WORKSPACE_ACCESS_TOKEN&quot;,  &quot;url&quot;: &quot;WORKSPACE_URL&quot;}The response also contains your template workspace ID and the workspace URL.Display the ChartUse the workspace URL Moesif sends you in the preceding step to display the chart in your application UI. Since the dynamic properties scope the workspace access token and workspace URL, the user is authenticated and can access the chart safely. For example, the following snippet uses HTML and the &amp;lt;iframe&amp;gt; element to display the chart, setting the src attribute to the workspace URL:&amp;lt;iframe  id=&quot;preview-frame&quot;src=&quot;https://www.moesif.com/public/WORKSPACE_ACCESS_TOKEN/ws/WORKSPACE_ID?embed=true&quot;  name=&quot;preview-frame&quot;  frameborder=&quot;0&quot;  noresize=&quot;noresize&quot;&amp;gt;&amp;lt;/iframe&amp;gt;Replace WORKSPACE_ACCESS_TOKEN and WORKSPACE_ID with your workspace access token and workspace ID respectively.Configuring the Sandbox PolicyThe sandbox policy dictates what criteria users can search within the chart. For an embedded template, the sandbox policy consists of the following elements:  Any filters you have in place in your chart. They carry over to the embedded template as constraints.  Any dynamic field you set when creating the embedded template.Configuring Dynamic CriteriaTo create an embedded template, you must specify at least one dynamic property.Moesif offers two builtin dynamic properties that you can use when creating the template:  Dynamic user ID  Dynamic company IDYou can also add custom dynamic fields by selecting Add Custom Dynamic Field.Moesif always sets the request time constraint as part of the sandbox policy. You can choose to make it dynamic with the Dynamic toggle. If you set the Request Time constraint to Dynamic, the Values column shows two values from and to that Moesif expects. These correspond to the request time period in ISO 8601 format. You must specify these values when you generate workspace tokens in your backend. For example, with cURL:curl -X POST -H &#39;Authorization: Bearer MANAGEMENT_API_KEY&#39; -H &#39;Content-Type: application/json&#39; -i &#39;https://api.moesif.com/v1/portal/~/workspaces/WORKSPACE_ID/access_token&#39;  -d &#39;{  &quot;template&quot;: {    &quot;values&quot;: {      &quot;user_id&quot;: &quot;USER_ID&quot;    }    &quot;from&quot;: &quot;2023-07-16T02:52:39Z&quot;,    &quot;to&quot;: &quot;2023-07-16T02:52:39Z&quot;  }}&#39;For a Node.js implementation of it using Express, see the Moesif API dashboard embed example on GitHub.If you set a dynamic field, you cannot use the same field as a filter in the embedded chart. For example, let’s say you’ve added the Request.User Agent field as a custom dynamic field. Using that dynamic field value, Moesif now expects to generate workspace URLs and tokens to render your embedded chart. Therefore, Moesif doesn’t allow you to use the Request.User Agent field as a filter in the embedded chart.Adding Custom Dynamic FieldsTo add a custom dynamic field, select + Add Custom Dynamic Field. From the menu, select the property you want. The Values column shows you the value Moesif expects for a custom dynamic property. Specify this value when you generate workspace tokens in your backend.Exposing Header and Body KeysBy default, header and body keys remain hidden for privacy and security. Enable this option if you want users to filter on the header and body keys of API requests. Keep in mind that all users see the same keys.Display OptionsFor embedding charts in a customer-facing portal, the default options can prove sufficient. For more information, contact Moesif support.You can add the following URL parameters to the &amp;lt;iframe&amp;gt; element to customize for a look that fits your business requirements. The following example specifies the embed and hide_header display options as query parameters in the src attribute’s URL.&amp;lt;iframe  id=&quot;preview-frame&quot;  src=&quot;https://www.moesif.com/public/em/ws/{WORKSPACE_ID}?embed=true&amp;amp;hide_header=true#{WORKSPACE_ACCESS_TOKEN}&quot;  name=&quot;preview-frame&quot;  frameborder=&quot;0&quot;  noresize=&quot;noresize&quot;&amp;gt;&amp;lt;/iframe&amp;gt;The following table explains the different display options available:            Name      Type      description                  embed      boolean      When set to true, enables embed mode. This adjusts to an embed-friendly layout. Always set this to true when embedding a chart in an &amp;lt;iframe&amp;gt; except for rare cases.              hide_header      boolean      By default, embed mode includes a small header containing filter dropdowns and chart name. To hide all elements besides the chart itself, set this to true. Since the filters are hidden, make sure any filters are added when you initially create the template.              show_daterange      boolean      If you set hide_header to true, but you still wish to show the date range select that was part of the header, set this to true.              show_metadata      boolean      By default, embed mode hides the event metadata. You can override this behavior to show event metadata by setting this to true.              show_users      boolean      By default, embed mode hides the user information. You can override this behavior to show the user information by setting this to true.  For example, if you have a use case where your customers want metrics on their end users, you can set show_users and show_user_filters to true while keeping show_companies and show_company_filters at false.              show_companies      boolean      By default, embed mode hides the user filters. You can override this behavior to show user filters by setting this option to true.              show_user_filters      boolean      By default, embed mode hides the user filters. You can override this behavior to show user filters by setting this option to true.              show_company_filters      boolean      By default, embed mode hides the company filters. You can override this behavior to show company filters by setting this option to true.              primary_color      string      You can set the primary_color parameter to a URL encoded hex value that matches your brand colors—for example, ?primary_color=%2332CD32. The primary color controls any brand-colored buttons, links, the color of the first metric in the chart, among other elements.              color_array      array      When your chart plots multiple metrics such as due to a group by, color_array defines the secondary colors for the chart. This is a URL encoded string that contains a comma separated array of color hashes. The first index specifies the color for first metric in the chart, the second index specifies the color for the second metric in the chart, and so on. For example, if you want the following color hashes: #ff0000, #00ff00, #0000ff in this order, set color_array to ?color_array=%23ff0000%2C%2300ff00%2C%230000ff. This also controls the color of status codes in the event logs. 1xx errors have the first index’s color, 2xx errors have the second index’s color, and so on.              chart_font_color      string      You can set the chart_font_color parameter to a URL encoded hex value that matches your brand colors such as ?primary_color=%2332CD32. This modifies the colors of the chart axis labels and chart axis ticks.              chart_font_family      string      Specifies the font family for the chart scale label, and ticks. It follows CSS font-family options. If a font is not available, the chart uses the default font family.              chart_axis_font_size      boolean      Font size in pixel values (px) for both X-axis and Y-axis ticks.              chart_label_font_size      boolean      Font size in pixel values (px) for both X-axis and Y-axis labels.              chart_x_axis_label      string      The text for the title of the X-axis. For example, # of People or Response Choices.              chart_y_axis_label      string      The text for the title of the y-axis. For example, Percentage or Count.              hide_chart_axis_label      boolean      If true, hides both X-axis and Y-axis labels.              hide_chart_legend      boolean      If true, hides chart legend.              hide_event_selection      boolean      For Event Log view only. If true, hides the checkboxes for selecting events and any buttons that act upon selected events.              drawing      object      If the embedded view is a Time Series chart or Segmentation chart, you can add an additional line to represent a threshold. For more information, see Drawing.              time_zone      string      Customize time zone for the chart. For example, to set to America/New_York, set url query param (url encoded) like this: time_zone=America%2FNew_York. Most IANA time zone names are supported. To see full list, print this out in Javascript: console.log(Intl.supportedValuesOf(&#39;timeZone&#39;));      Tip on controlling iframe sizeBy default, iframe’s height is only 150px, so that is typically too short. We leave to the customer to control the iframe size, as there are many approaches and needs. Below is one technique: creating a wrapper for the iframe to use css to control the aspect ratio.&amp;lt;div class=&quot;iframe-wrapper&quot; style=&quot;position: relative; width: 100%; padding-bottom: 56.25%; /* 16:9 aspect ratio */&quot;&amp;gt;    &amp;lt;iframe src=&quot;url&quot; style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/div&amp;gt;You can adjust either width, padding-right, or padding-bottom values of the iframe-wrapper.DrawingYou can add static markers to your chart to represent a plan quota or SLA agreement. For example, a line across the chart at a specific threshold so that users can trace their usage against their quota.Use the drawing parameter to draw a static marker. You must define and format the options for the drawing as a query parameter. You must attach it to the embed URL in the same way you attach the display options.For example, the following JavaScript code shows how to add a line to a time series showing a threshold:import qs from &#39;qs&#39;;const queryParams = {  drawing: {    value: number, // required    name: &#39;name of the label&#39;, // required.    // below are optional:    type: &#39;line&#39;,    borderWidth: 5,    borderColor: &#39;rgba(255, 51, 181, 0.3)&#39;,    backgroundColor: &#39;rgba(255, 51, 181, 0.3)&#39;,    pointRadius: 0,  }}// format it into query stringqs.stringify(queryParams, { format: &#39;index&#39; });// and append to the embed url.Use Search APITo use Search API, from the chart you want to access through the Search API, follow these steps:  Select Embed / API from the chart header.      Select Search API.    Moesif generates a cURL command for your workspace criteria that you can use immediately to access the chart data. Moesif also gives you the HTTP request details so you can use HTTP clients like Postman.    Select the Curl Command tab for the cURL command and the HTTP Details tab for the HTTP request details.Search DefinitionThe search definition Moesif generates uses the Elasticsearch Query DSL. To access the search definition, see the HTTP request body from the HTTP Details tab or the generated cURL command’s -d (or --data)  argument value.This search definition accurately represents your desired report according to your chart’s filters and settings. You can quickly go back to your chart window, reconfigure, select Embed / API, and then select Search API to update your search. If you need help building a query for your business requirements, contact us.The Search API sends your request to the Management API’s events search endpoint. For more information, see the Management API searchEvents documentation.",
      "url": " /embedded-templates/creating-and-using-templates/",
      "author": "Derric",
      "categories": "Embed-Template"
    }
    ,
  

    "embedded-templates-managing-embedded-templates": {
      "title": "Managing Embedded Templates",
      "content"	 : "The Embed Templates screen allows you to manage all your existing embedded templates. Select the Embed Templates menu item from the navigation menu to access the screen.The Embed Templates screen shows a list of all embedded templates that you have created. You can see the various settings of each template, as well as the view count and the corresponding chart type of each template. As the templates get views, the view counts increase.Any template with zero views may no longer be used since no one has accessed it.Access the Embed InstructionsWhen you create an embedded metric, you can see the embed instructions after selecting Get Embed Code. You can access those instructions anytime by selecting Embed Templates and then selecting Show Embed Instructions in a template.Edit a TemplateMoesif allows you to change almost every aspect of a template, including the chart’s filter, dynamic fields, and settings. For example, you can hide or expose header and body keys.Rename a TemplateTo rename a template, select Show Embed Instructions from the Embed Templates screen in the template you want to rename. Type the new name in the Name field. Then select X.Moesif automatically saves the new name when you exit. You don’t need to manually save it.Edit ChartTo edit your template’s chart, from the Embed Templates screen, select Show Embed Instructions and then select Edit Chart. After making your edits, select Save.It takes some time for the changes to take effect and become visible. If you change any dynamic fields, make sure that you update the corresponding application code. Any current embeds that you have of this chart might stop functioning temporarily, and users might need to refresh the browser or application.Edit SettingsTo change the embed settings of your template, from the Embed Templates screen, select Show Embed Instructions and then choose Settings. After making your edits, select Update.It takes some time for the changes to take effect and become visible. If you change any dynamic fields, make sure that you update the corresponding application code. Any current embeds that you have of this chart might stop functioning temporarily, and users might need to refresh the browser or application.Delete a TemplateTo delete an embedded template, hover over the template you want to delete and select X. Then select Delete from the confirmation dialog. Remember that after you delete a template, any embeds you have of this template workspace stop functioning.Secure Access to Embedded MetricsTo maximize the security of your embedded metrics and maintain proper access control, follow these best practices for different embed types:For Static EmbedsFor static embeds, you can use a passcode-protected link. This lets you selectively choose who can access your static embeds with a secure link.The &amp;lt;iframe&amp;gt; HTML element Moesif generates for a static embed contains the same passcode you see in the Passcode tab. You can establish some logic in your application that dynamically requests the passcode from the user before rendering the &amp;lt;iframe&amp;gt; element.Remember that you can always revoke access to your static embed by deleting the corresponding workspace.For Embedded Templates  Set dynamic properties like user and company IDs to sandbox data and access. You can add as many dynamic properties as you want. For secure generation of IDs, use a library like Nano ID.  Maintain caution when you expose the header and body keys of your API requests. Moesif disables this feature by default.  Set an expiration date for the generated workspace token. For an example, see Creating an Endpoint in our embedded templates guide.  If necessary, manually generate a Management API key with an expiration date.  Use environment variables to store secrets like your Moesif Management API key and workspace ID.For Search APIThe Search API only requires the Management API key for a valid request to Moesif’s Management API. Therefore, follow best practices to keep your API keys secure. For example, instead of hard-coding API keys, use environment variables or key stores. You can also manually generate Management API keys with custom expiration dates.Management API keysYou can manually generate Management API keys with custom expiration and authorization scopes. This allows you to add another layer of security over embedded metrics that require Management API keys like embedded templates and the Search API.To generate a Management API key manually, follow these steps:  Select the account icon to bring up the settings menu.  Select API Keys.   From the Management API Key section, select the authorization scopes you need and set the key’s expiration time.   Select Generate Token.",
      "url": " /embedded-templates/managing-embedded-templates/",
      "author": "Sakib",
      "categories": "Embed-Template"
    }
    ,
  

    "api-governance-rules": {
      "title": "Introduction to Quotas and Governance",
      "content"	 : "Moesif’s Governance Rules feature allows you to automatically enforce quotas or restrict access to your APIs based on user behavior or specific account conditions, such as a user having no pre-paid credits left for a monetized API. Governance rules can help your company adopt a robust API governance policy that complements business growth and improves user experiences through proper regulation and feature optimization.Governance rules work by interacting with your Moesif server integration to block or modify the response on the fly, or both.For governance rules to work, you only need to install a Moesif server integration. This includes user and company tracking, depending on the rules you require. A governance rule can make decisions from not only API requests, but you can add governance rules based on any customer demographics or behavior that Moesif can track—for example, blocking customers with overdue invoices or adding paywalls to your API.Use Cases and BenefitsMoesif’s governance rules allow you to enforce various policies and business logic for different scenarios. They can help you maintain sustainable growth and improve your business model by extending quotas and governance from a business level to complement the engineering-level governance that most API gateways and management platforms provide.The following examples illustrate some common use cases that companies leverage governance rules for:  If you monetize your API with a prepaid billing model, you can create a governance rule to block customers once they run out of credits or have a negative account balance.  Enforce various security and business policies to protect your API, such as blocking bad actors from scraping an abnormally large amount of data.  Leverage governance rules to add custom HTTP headers. For example, deprecation warning headers when your customers access an older version of your API.  Implement various subscription policies according to your business model. For example, it automatically grants and revokes access for different subscription tiers, enforces quotas and limits for users of different tiers, and so on.When to Use Moesif Governance RulesNot for Traditional Rate LimitingMoesif Governance Rules is not designed as a replacement for traditional rate limiting or request-per-minute (RPM) blocking that API gateways typically handle. If your primary need is to block users who exceed a certain number of requests per second or minute, traditional API gateways or middleware solutions are more appropriate tools for this purpose.Designed for Longer-Term and Complex GovernanceInstead, Moesif Governance Rules excels at:  Longer-term quotas: Enforcing limits over days, weeks, or months rather than seconds or minutes  Complex business rules: Implementing sophisticated logic based on customer behavior, demographics, or usage patterns  Multi-dimensional governance: Making decisions based on combinations of factors beyond simple request countingFor example, while an API gateway might block a user who makes more than 100 requests per minute (a technical constraint), Moesif can block users who have consumed their monthly API quota of 10,000 requests, or who have accessed premium endpoints without the appropriate subscription tier (business constraints).Complex Abuse DetectionMoesif is particularly powerful for detecting and preventing complex abuse scenarios that simple RPM controls cannot address:  Blocking users who show unusual access patterns across multiple endpoints  Identifying and restricting access when a user’s behavior indicates data scraping or intellectual property theft  Enforcing sophisticated fair-use policies that consider the value or computational cost of different endpointsIn a layered API security strategy, API gateways handle the immediate, high-frequency technical constraints while Moesif Governance Rules manages the business-aligned, longer-term, and more complex governance needs.",
      "url": " /api-governance-rules/",
      "author": "Derric",
      "categories": "Governance"
    }
    ,
  

    "api-governance-rules-creating-governance-rules": {
      "title": "Creating Governance Rules",
      "content"	 : "This document explains different types of governance rules and how to create them.For a general overview on governance rules and its use cases, see Introduction to Quotas and Governance. To know how to manage your existing governance rules, see Managing Governance Rules.Types of RulesMoesif supports two kinds of governance rules, both suited to a specific use case. These types include:  Behavior Rules  Quota RulesGovernance is incompatible with the Tyk and Azure APIM integrations. Check with your customer success representative if governance is supported for your server integration.Behavior RulesA Behavior Rule allows you to target specific populations based on certain criteria. In general, defining a Behavior Rule involves two steps:  Define your target user segment using a user or company cohort.  Define the governance rule you want to enforce on the target user segment.Each behavioral governance rule can only target one type of cohort at a time. You cannot define a behavioral governance rule that targets both a user cohort and a company cohort. Rules without any cohorts apply to all users and companies.By default, Moesif restricts all kinds of access to your API from users or companies that match the governance rule. To refine what you want to block, use regular expressions. This allows you to define regular expressions on API requests so that you can block only parts of your API.For instructions on how to define behavior rules, see Create Behavior Rules.Quota RulesWith Quota Rules, you can restrict customers based on subscription plans and prices. Quota Rules allow you to define quotas and limits under a subscription scheme. When subscribers exceed a quota, Moesif enforces the rule on them and restricts access to your API.Similar to Behavior Rules, Moesif, by default, restricts all kinds of access to your API from subscribers who match the rule. To refine what you want to block, use regular expressions to define regular expressions on API requests so that you can block only parts of your API.For instructions on how to define quota rules, see Create Quota Rules.Create Behavior Rules  Select Quotas &amp;amp; Governance from the navigation menu and then select + Add New. Alternatively, select + Create New and then select Gov Rule/Quota.   Select Start from Blank Behavior Rule.  Specify a name for your rule in the Governance Rule Name field.  Select one or more cohorts to which you want to apply the rule. The Select cohorts to apply rule list shows existing user and company cohorts. You can create a new cohort by selecting + Create a New User Cohort or + Create a New Company Cohort from the list.  Optionally, select Block What and specify regular expressions to tune further what you want to block.  In the Respond With pane, specify overrides for response status and body. You can optionally also override response headers. You must override the response status and body for a blocking rule.  Optionally, set the priority for your rule.  Select Create.For example, the following shows a user rule to block API access to users with overdue invoices. The rule also lets them know that the reason for blocking is paused subscription.Choose How To Apply a Rule to a CohortWhen defining a behavior rule, you can apply the rule inclusively or exclusively to the one or more cohorts you select. You can set this by choosing the are or are not filter when you select the user or company cohort for your rule.If you choose the are filter, the rule applies whenever a user or company belongs to the specified cohort. For example, you may create a rule that blocks all users on a specific subscription tier if they exceed their quota.If you choose the are not filter, the rule applies to every user or company not belonging to the specified cohort. For example, you want to block every user who does not have an active subscription from accessing your APIs. Therefore, you may have a cohort named “Users With Active Subscriptions” containing all users with valid subscriptions. If you choose this cohort when defining your rule and select the are not filter, the criteria becomes Apply to Customer that are not members of Users cohorts below. Then, Moesif blocks every user without an active subscription from accessing your APIs.Apply Cohort to Unidentified UsersYou can choose to apply a cohort for events that don’t have associated user IDs by selecting Apply to Unidentified Users. For example, consider a user with user ID 1234 who is in the cohort “Users With Active Subscriptions”. With thisoption disabled, Moesif applies the cohort only for events that has the associated user ID 1234. If you enable this option, then Moesif applies the cohort evenfor events that don’t have any associated user IDs.Blocking and Non-blockingA blocking rule means Moesif actively blocks the customer’s requests before they reach your upstream service. Moesif also overrides the response HTTP status and body according to your rule configuration. To set a rule to block, select the Blocking further access checkbox.For a non-blocking rule, the request continues to your upstream service. Moesif only overrides any HTTP response headers but doesn’t change the HTTP body and status code. To set a rule to non-blocking, clear the Blocking further access checkbox.For a blocking rule, you must override the HTTP status and body.Override Response StatusFor a blocking rule, you must override the HTTP response status code by selecting a status from the Response Status Override list. The “Block Users With Unpaid Invoices” rule sets the status to 402 Payment Required.Override Response HeadersYou can override any number of HTTP response headers by selecting Add Header. If the upstream service has already set a header, Moesif overrides the existing one. Otherwise, Moesif adds new headers.Override Response BodyFor a blocking rule, you must override the HTTP response body that the client receives in the Response Body Override field. This supports merge tags from the user or company profile. The “Block Users With Unpaid Invoices” rule adds an error message explaining to the user why they are blocked. The rule also mentions the user’s subscription plan that has overdue invoices.Set rule priorityYou can optionally set a priority for your rule in the Priority field. User cohort rules take higher priority than company cohort rules. However, within a group of user rules, you can prioritize between 0 and 100. A lower number means higher priority.Create Quota RulesTo create a Quota Rule, follow these steps:  Select Quotas &amp;amp; Governance from the navigation menu and then select + Add New. Alternatively, select + New and then select Gov Rule/Quota.   Select Start from Blank Quota Rule.  Specify a name for your rule in the Governance Rule Name field.  Specify the subscription provider, plan, and price.  In the Block When pane, specify the quota.  Optionally, select Block What and specify regular expressions to tune further what you want to block.  In the Response When Blocking pane, specify overrides for response status and body. Quota rules are always blocking so you must override the response status and body. Optionally, you can also override response headers.  Optionally, set the priority for your rule.  Select Create.Specify QuotaWhen you create a quota rule, you must specify a subscription provider, plan, and optional price. After that, open the Show matching subscribers pane. This pane shows the matching subscribers in tabular format. The table shows each matching subscriber’s company ID, subscription ID, and last seen time.After narrowing down your target subscribers, specify the quota you want to enforce. For example, you can define a quota that blocks subscribers after they exceed 10,000 API calls in the current billing month.To define a quota, follow these steps:      In the Block When pane, specify the API event details you want Moesif to monitor. Moesif blocks subscribers from accessing your API whenever their behavior matches the event details you specify. For example, to block subscribers in the current plan after they exceed 10,000 API calls, do the following:    a. Select API Call as the event type.    b. Specify 10000 as the event count.    c. Select Calendar Month as the event period.        Open the Show subscribers over quota pane. It shows the company ID, subscription ID, and last seen time for each matching subscriber who has exceeded the quota.  Blocking and Non-blockingA blocking rule means Moesif actively blocks the customer’s requests before they reach your upstream service. Moesif also overrides the response HTTP status and body according to your rule configuration. Quota rules are always blocking, so you must override the HTTP response status and body.Override Response StatusYou must override the HTTP response status code for each quota rule by selecting a status from the Response Status Override list.Override Response HeadersYou can override any number of HTTP response headers by selecting Add Header. If the upstream service has already set a header, Moesif overrides the existing one. Otherwise, Moesif adds new headers.Override Response BodyFor each quota rule, you must override the HTTP response body that the client receives in the Response Body Override field. This supports merge tags from the user or company profile.Set rule priorityYou can optionally set a priority for your rule in the Priority field. User cohort rules take higher priority than company cohort rules. However, within a group of user rules, you can prioritize between 0 and 100. A lower number means higher priority.Use Regular ExpressionsBoth behavioral and quota governance rules support regular expressions to define restrictions explicitly. This allows you to control further what parts of your API you want to block.To use regular expressions, follow these steps when you create a governance rule:  Open the Block What pane.  Select the request field you want to apply your regular expression to—for example, Request Verb.  Enter your regular expression criteria. For example, if you choose Request Verb in the preceding step, you can enter post as your regular expression. This causes Moesif to block HTTP POST requests.You can combine multiple regular expressions by selecting Or Group or + Regex Criteria.Create Rules With Governance Rule TemplatesAfter you create a new governance rule, the dialog contains several template rules from which you can start. These allow you to set up governance rules for popular use cases quickly.To create and use a template, select one and then select Continue. Then you can further customize the rule.Moesif includes the following governance rule templates:  Block Zero Prepaid Balance  Block on Unpaid Invoices  Allow Only Active Subscriptions  Block Sending More Than a Hundred Megabytes Per Hour  Block Downloading More Than a Hundred Megabytes Per Hour  Enforce Monthly Subscription QuotaWhen you create a template, it performs the following tasks automatically:  Creates the applicable cohorts to match the rules.  Adds them to a new governance rule.  Configures other parameters in the rule to match the use case. This includes any HTTP status code and JSON response body.Block Zero Prepaid BalanceA behavioral rule that blocks companies who have zero prepaid balance remaining.Block on Unpaid InvoicesA behavioral rule that blocks users trying to access your APIs with any overdue or unpaid invoices from your configured billing providers.Allow Only Active SubscriptionsA behavioral rule that denies users access if they don’t have any active subscriptions.Block Sending More Than a Hundred Megabytes Per HourA behavioral rule that blocks any user who has sent more than 100 MB in the last hour. The calculation follows the sum of the Content-Length header in each request.Block Downloading More Than a Hundred Megabytes Per HourA behavioral rule that blocks any user who has downloaded or received more than 100 MB in the last hour. The calculation follows the sum of the Content-Length header in each request.Enforce Monthly Subscription QuotaA behavioral rule that blocks any user who have exceeded the allowed quota under their currently active subscription.",
      "url": " /api-governance-rules/creating-governance-rules/",
      "author": "Derric",
      "categories": "Governance"
    }
    ,
  

    "api-governance-rules-managing-governance-rules": {
      "title": "Managing Governance Rules",
      "content"	 : "This document explains how to access, edit, update, and delete your existing governance rules from the Quotas &amp;amp; Governance screen.For a general overview on governance rules and its use cases, see Introduction to Quotas and Governance. For instructions on how to create governance rules, see Creating Governance Rules.Access Governance RulesSelect the Quotas &amp;amp; Governance menu item from the navigation menu to access the governance rules screen. To create a new governance rule, do one of the following:  Select + New and then select Gov Rule/Quota.  From the Quotas &amp;amp; Governance screen, select + Add New.The Quotas &amp;amp; Governance screen lists all governance rules you have created.It shows the following details for each rule:  The name of the governance rule  The one or more cohorts the rule applies to  The regular expression criteria  Whether the rule is blocking or non-blocking  The HTTP response status override  Whether the rule is turned on or off  The rule priority  The rule’s date of creationFrom the ⋯ Actions menu, you can also delete a rule.Edit and Update Governance Rules  From the Quotas &amp;amp; Governance screen, select the name of the governance rule you want to update.  Make your edits.  Select Save.Delete Governance Rules  From the Quotas &amp;amp; Governance screen, for the rule you want to delete, select ⋯ Actions and then choose Delete.  Select Delete again to confirm your choice.",
      "url": " /api-governance-rules/managing-governance-rules/",
      "author": "Sakib",
      "categories": "Governance"
    }
    ,
  

    "developer-portal": {
      "title": "Introduction to The Moesif Developer Portal",
      "content"	 : "The Moesif developer portal is an open-source project to help provide a great starting place to quickly build your own developer experience. You can customize and deploy the developer portal without being worried about lock-in or lack of customization. The developer portal is focused on providing a low-friction solution allowing your customers to quickly and easily subscribe and provide authenticated, metered access to your APIs.                    1.                    Configure Identity Provider                    Use an Identity Provider to secure the front-end application and control access.                                        2.                    Configure Payment Provider                    Utilize a Billing Provider to facilitate the checkout process and invoice customers for usage.                                        3.                    Configure Plugins                    Integrate the Developer Portal with a variety of API key provisioning plugins to integrate with your current solution.            Supported SolutionsBelow are the currently supported solutions in the developer portal. They may be used in any combination and we are continuing to add support for additional platforms regularly.Identity / Access Management                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Auth0                                                                                                                                                                                                        Okta                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Payment Providers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Stripe                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                API Key Provisioning Plugins                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Auth0 M2M                                                                                                                                                                                                              JWT                                                                                                                                                                                                              Kong Gateway                                                                                                                                                                                                              Kong Konnect                                                                                                                                                                                                              Tyk Gateway                                                                                                                                                                                                                                                                                                                                                                                                                                                  PrerequisitesTo set up and use the Moesif Developer Portal, you will need the following:  An active Moesif account  A running APIM / Gateway instance  An active Identity / Access Management platform account  An active billing provider accountProduction ReadinessThis portal is a pre-release project in preview and actively being developed. Before going to production, a few things should be done:  Ensure APIs are secured using HTTPS and an authentication layer  Ensuring all keys are stored securely in a Keystore  Customize the CSS for your brandWe’ve built a step-by-step guide on how to set up the Moesif Developer Portal. Since there are a lot of moving parts, it’s suggested that you follow each step carefully and in the order that they are presented.",
      "url": " /developer-portal/",
      "author": "Matthew",
      "categories": "Developer Portal"
    }
    ,
  

    "developer-portal-developer-portal-overview": {
      "title": "Developer Portal Overview",
      "content"	 : "Moesif Developer PortalThe Moesif developer portal is an open-source app that you can deploy to provide a self-service experience for customers to subscribe and pay for your APIs. The developer portal is for API product owners looking to productize and monetize APIs.As an open-source project, you can customize the brand and user experience to meet your requirements without fear of vendor lock-in.OverviewThere are two main components  my-dev-portal is a React based frontend for customers to subscribe to APIs  my-dev-portal-api is a Node.js API to communicate with the Moesif APIs and Billing APIs in a secure environment.  As of December 2024, the Moesif developer portal is now Generally Available and ready for production use. If you are using an early version, we recommend merging the latest changes for production readiness.Production ReadinessBefore going to production, you should confirm a few things:  Ensure APIs are secured using HTTPS  Ensuring all keys stored securely in a keystore  Customize the CSS for your brand  Check assumptions in the DATA-MODEL.md, if your data mapping needs are different, you may want to adjust the code accordingly.Supported SolutionsBelow are the currently supported solutions in the developer portal. They may be used in any combination and we are continuing to add support for additional platforms regularly.Identity / Access Management  Auth0  OktaPayment Provider  StripeAPIM / Key provisioning service  Auth0 Machine2Machine  JWT  AWS API Gateway  Kong  TykPrerequisitesIn order to set up and use the Moesif Developer Portal, you will need the following:  An active Identity Provider account  An active payment provider account  A running APIM / API service to provision keys  An active Moesif accountBelow is a step-by-step guide on how to set up the Moesif Developer Portal. Since there are a lot of moving parts, it’s suggested that you follow each step carefully and in the order that they are presented.Configuring the Developer Portal1. Configuring Identity ProviderIn order for new customers to sign up, you must configure an identity provider. Moesif supports two identity providers:  Configure the portal with Auth0  Configure the portal with Okta2. Configuring Billing ProviderIn order for new customers to purchase paid plans with a credit card, you must configure a billing provider. Currently, Stripe is the only supported billing provider. However, the portal can be modified for alternate checkout flows for custom billing providers.  Configure Stripe as the billing provider  Configure a custom billing provider3. Configuring API Management or Provisioning PluginYou’ll need to configure a service to generate API keys. This enables new sign ups to access your APIs and meter their usage.The developer portal has plugins for many different provisioning flows including popular API gateways like Kong along with standards like Json Web Tokens (JWT)The plugins are available in the ./plugins directory of the repository. Instructions are below:  Configure Auth0 Machine2Machine plugin as the key provisioning service  Configure JWT plugin as the key provisioning service  Configure Kong Gateway plugin as the key provisioning service  Configure Kong Konnect plugin as the key provisioning service  Configure Tyk plugin as the key provisioning serviceBuilding Your Own Provisioning PluginYou can also implement your own logic to generate API keys. For more information, see Build Your Own Key Provisioning Plugin.4. Configure Moesif Management APIs &amp;amp; Embedded DashboardsYou will need to configure Moesif Management API to support getting synced plans/prices from Moesif, and embedded dashboards.  Configure Moesif Management APIs  Configure the Embedded DashboardsRunning the PortalSource Code LayoutWithin the project, you will see two subfolders: my-dev-portal and my-dev-portal-api. For the project to work, both applications must be running.The my-dev-portal folder is a React application that contains the UI and logic for the developer portal. Any additions to the UI, styling or branding changes, and other user-facing changes will be done within this folder/project.The my-dev-portal-api project is where the APIs and various other logic are contained. In this project, you’ll have connectivity to Moesif, Stripe, and Kong through various APIs. For example, the /register endpoint in this project contains the logic used to register a new user in the various systems that are part of the developer portal ecosystem.In addition, the plugins directory contains various plugins to provisions API keys such as for JWT and Kong.The resources directory contains additional files such as for AWS API GatewaySetting up the .env FileEach of the projects in the developer portal, my-dev-portal and my-dev-portal-api, require a .env file to function. In the .env file, various API keys and other credentials are stored. Of course, when moving to production you may want to move these from the .env file and into a more secure secrets management system.In the root of both the my-dev-portal and my-dev-portal-api projects, create a .env file. In each project, there is a .env.template file that shows the variables that you need to add. You can copy and paste these contents into the new .env files created in each of the projects.Starting the Developer PortalNow that everything is configured, it’s time to start up the Developer portal. This will require starting up both the UI and the API projects.First, in a terminal that is pointing to the ./my-dev-portal-api directory in the project, you’ll run:node app.jsThis will start up our API project.Secondly, we will start up our UI project by opening another terminal at the ./my-dev-portal directory and running:npm startOnce it has started, your browser will open up the Developer Portal on http://127.0.0.1:4000. Next, you can move on to testing the Moesif Developer Portal to make sure all parts are working as expected.Testing the Moesif Developer PortalTesting out all of the moving parts of the Developer Portal is crucial to making sure everything is working as intended. A lot is going on across multiple platforms so it makes sense to double-check that nothing was missed during the setup process.To start, navigate to your developer portal in the browser, and at the Home Screen of the Developer Portal click the Sign Up button in the top right. On the form that appears, create your user, select a product, and complete the checkout process, and then you should land in the Dashboard screen of the Developer Portal. At this point, you can confirm a few things that apply to your setup:Running as a Docker ContainerWhile not required, you can also run the portal as a Docker container.There are two docker images available to run:  moesif/dev-portal runs the frontend  moesif/dev-portal-api runs the backendTo run the docker examples, modify the envvars in distribution/docker/docker-compose.yml and then run it as:docker-compose up -dBuilding Docker ImageYou can modify the source code and build your own Docker image if required. The two components (the frontend and the API) from the Docker images available.To build the Docker images:  cd into ./distribution/docker  Run ./build.shYou’ll see two images built. You can then run both via the compose file:docker-compose up -dNext StepsNext, in the Moesif Developer Portal, click on the Keys menu item at the top of the screen and open the Keys screen. On the Keys screen, click the Create Key button and generate an API key. Next, create an API request in Postman or Insomnia and attach the API key to the header. Once the API request is sent and the response is received, we can confirm a few more things:In Moesif, in the Live Event Log, you should see your API call logged. You should also see, to the far right of the request entry, that your user’s Stripe customer ID and subscription ID are attached to the request.Within the next 5 minutes, you should also see in Stripe that API call usage has been attached to the user subscription. This can be done by going to the Customers screen, clicking on the customer, and on the customer profile screen that appears, clicking on the Subscriptions entry for the subscription where the usage will be billed. Inside the subscription details screen, you’ll see under the Pricing header an entry and a link for View usage. This should reflect the API call usage.A last step you can do is also do the Meter Test to ensure that all parts of the billing meter setup are working correctly.Depends on how you deploy the my-dev-portal-api, weather you decides to use API gateway or not, you will want to make sure theseAPIs are protected so that they can only be called by my-dev-portal UI.With all parts of the ecosystem working properly, the Moesif Developer Portal can be released to your users!",
      "url": " /developer-portal/developer-portal-overview/",
      "author": "Matthew",
      "categories": "Developer Portal, RemoveH1"
    }
    ,
  

    "developer-portal-configure-auth0-for-identity": {
      "title": "Configure Auth0 for Identity",
      "content"	 : "The Moesif Developer Portal requires an Identity Provider to secure the front-end application and control access. Below are the steps required to set up Auth0 as an identity provider to work with the Moesif Developer Portal.Creating an Application within Auth0To configure Auth0 for use with the Moesif Developer Portal, you need to create an Auth0 Application. Follow these steps:  Log into Auth0:          From the left-side menu, click on Applications and then select Applications.        Create a New Application:          On the Applications page, click the Create Application button.      In the modal that appears:                  Fill in the Name field with a value such as Developer Portal.          Select Single Page Application as the Application Type.          Click Create.                      Configure Application Settings:          On the next page, go to the Settings tab.      Scroll down to the Application URIs section.      Add https://127.0.0.1:4000 (or the URL where your developer portal will be hosted) as an entry for:                  Application Login URI                    Add http://127.0.0.1:4000 (or the URL where your developer portal will be hosted) as an entry for:                  Allowed Callback URLs          Allowed Logout URLs          Allowed Web Origins                      Save Changes:          Scroll to the bottom of the page and click Save Changes to persist your application settings.      Adding Auth0 to the Moesif Developer PortalTo connect Auth0 to the Developer Portal, you’ll need to update the environment variables.Retrieving Values from Auth0  Navigate to the Applications screen in Auth0.  Select the application you created for the Developer Portal.  Go to the Settings tab.  Copy the following values:          Domain: Paste this into the REACT_APP_AUTH0_DOMAIN entry in your environment configuration.      Client ID: Paste this into the REACT_APP_AUTH0_CLIENT_ID entry in your environment configuration.      Updating Environment VariablesDepending on your setup, these variables can be added to either the my-dev-portal/.env and my-dev-portal-api/.env files (for Node setups) or the distribution/docker-compose.yml file (for Docker setups).Environment Variables for NodeTo configure Stripe in the Developer Portal, you will need to update two .env files located in different parts of your project:  my-dev-portal-api/.env file: This is where you configure the backend API environment.  my-dev-portal/.env file: This is where you configure the frontend environment.Backend  Open the my-dev-portal-api/.env file.  Replace the following lines with the correct values:AUTH_PROVIDER=&quot;Auth0&quot;AUTH0_DOMAIN=&quot;your Auth0 Domain&quot;  Save the .env file to ensure the updated values are persisted.Frontend  Open the my-dev-portal/.env file.  Replace the following lines with the correct values:REACT_APP_AUTH0_DOMAIN=&quot;yoururl.us.auth0.com&quot;REACT_APP_AUTH0_CLIENT_ID=&quot;your Auth0 Client ID&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment:dev-portal-api:  environment:    - AUTH_PROVIDER=&quot;Auth0&quot;    - AUTH0_DOMAIN=&quot;your Auth0 Domain&quot;dev-portal:  environment:    - REACT_APP_AUTH0_DOMAIN=&quot;yoururl.us.auth0.com&quot;    - REACT_APP_AUTH0_DOMAIN=&quot;your Auth0 Domain&quot;    - REACT_APP_AUTH0_CLIENT_ID=&quot;your Auth0 Client ID&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.With the Auth0 application created and environment variables updated, you’re now ready to proceed to the next step: setting up your payment provider for the Developer Portal.Next StepsOnce all the values are added, save the file to make sure the updated values are persisted. Next, move on to configuring you billing provider.Verifying Identity Provider FunctionalityAfter configuring the rest of the developer portal you can verify identity provider functionality in Auth0. On the User Management &amp;gt; Users screen, you should see your newly created user present, tracked by their email.",
      "url": " /developer-portal/configure-auth0-for-identity/",
      "author": "Matthew",
      "categories": "Developer Portal, Developer Portal Identity"
    }
    ,
  

    "developer-portal-configure-okta-for-identity": {
      "title": "Configure Okta for Identity",
      "content"	 : "The Moesif Developer Portal requires an Identity Provider to secure the front-end application and control access. Below are the steps required to set up Okta as an identity provider to work with the Moesif Developer Portal.Creating the App within OktaTo configure Okta for the Moesif Developer Portal, follow these steps:  Log into Okta:          From the left-side menu, click on Applications and select Applications.        Create a New App Integration:          Click the Create App Integration button on the Applications page.        Select App Type:          In the modal that appears:                  Under Sign-in method, choose OIDC - OpenID Connect.          Under Application type, select Single-Page Application.          Click Next.                      Configure App Details:          App integration name: Enter a name, such as Developer Portal.      Grant type: Ensure Authorization Code and Refresh Token are selected.      Sign-in redirect URIs: Add the redirect URI for your environment, e.g., http://127.0.0.1:4000/login/callback if running locally.      Sign-out redirect URIs: Add a URI like http://127.0.0.1:4000/.      Assignments: Choose Skip group assignment for now unless specific group assignments are needed.        Save the Configuration:          Scroll to the bottom of the page and click Save to save the application settings.      Adding Okta to the Moesif Developer PortalTo connect Okta to the Developer Portal, you’ll need to update the environment variables.Retrieving Values from Okta  Navigate to the Applications screen in the Okta console.  Select the application you created for the Developer Portal.  Go to the General tab.  Locate the following values and copy them:          Client ID: Use this value for the REACT_APP_OKTA_CLIENT_ID entry in the frontend environment configuration.      Issuer (Org URL): Use this value for the REACT_APP_OKTA_ORG_URL in the frontend configuration and the OKTA_DOMAIN in the backend configuration. When configuring the frontend, append /oauth2/default to this URL.        Generate an API Token:          Follow Okta’s API token creation guide.      Use the token for the OKTA_API_TOKEN entry in the backend environment configuration.      Updating Environment VariablesEnvironment Variables for NodeTo configure Okta in the Developer Portal, you will need to update two .env files located in different parts of your project:  my-dev-portal-api/.env: This is where you configure the backend API environment.  my-dev-portal/.env: This is where you configure the frontend environment.Backend Configuration  Open the my-dev-portal-api/.env file.  Replace the following lines with the correct values:OKTA_DOMAIN=&quot;https://your-okta-url.okta.com/&quot;OKTA_API_TOKEN=&quot;your_api_token_here&quot;OKTA_APPLICATION_ID=&quot;your_app_client_id_here&quot;  Save the .env file to ensure the updated values are persisted.Frontend Configuration  Open the my-dev-portal/.env file.  Replace the following lines with the correct values:REACT_APP_OKTA_ORG_URL=&quot;https://yoururl.okta.com/oauth2/default&quot;REACT_APP_OKTA_CLIENT_ID=&quot;Your Okta Client ID&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment:dev-portal-api:  environment:    - OKTA_DOMAIN=&quot;https://your-okta-url.okta.com/&quot;    - OKTA_API_TOKEN=&quot;your_api_token_here&quot;    - OKTA_APPLICATION_ID=&quot;your_app_client_id_here&quot;dev-portal:  environment:    - REACT_APP_OKTA_ORG_URL=&quot;https://yoururl.okta.com/oauth2/default&quot;    - REACT_APP_OKTA_CLIENT_ID=&quot;Your Okta Client ID&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.Next StepsOnce all the values are added, save the files to ensure the updated values are persisted. You can then proceed to configure your billing provider.Verifying Identity Provider FunctionalityAfter configuring the rest of the developer portal, verify the identity provider functionality in the Okta console. Navigate to the Directory &amp;gt; People screen, where you should see your newly created user tracked by their email address.",
      "url": " /developer-portal/configure-okta-for-identity/",
      "author": "Matthew",
      "categories": "Developer Portal, Developer Portal Identity"
    }
    ,
  

    "developer-portal-configure-stripe-for-checkout": {
      "title": "Configure Stripe for Checkout",
      "content"	 : "A Billing Provider is needed to facilitate the checkout process and invoice customers for usage. When APIs are used, Moesif will aggregate the API usage and send the usage to the billing provider to be invoiced.For a more in-depth explanation on integrating with Stripe check out our Integrating with Stripe Billing Meter documentation.Setting up Stripe as a Billing ProviderIn order to use Stripe as a billing provider for the Moesif Developer Portal, you’ll need to set up products and prices within Stripe.There are four steps that need to be completed:  Creating a Product in Stripe  Integrate Moesif and Stripe  Configuring the Stripe Extension in Moesif  Setting up a Billing Meter in MoesifCreating a Product in StripeBefore you create your product and price in Stripe, make sure you meet these prerequisites.Step 1: Log in and Navigate to ProductsLog into Stripe Dashboard and proceed to the Product Catalog page.Step 2: Configure Product SettingsThe following steps demonstrate how to create a product, define its pricestructure, and create a billing meter for the price in Stripe.  In Product Catalog, select Create product.    Select Recurring and then select More pricing options.   Select Recurring and choose Usage-based as the pricing model. You canchoose the usage amount as package, unit, or tier.  Define your price amounts, for example, $0.01 for each 1k API requests.      In the Meter section, select the plus icon + to create a billing meter to associate the price with.    a. Enter the meter name.    b. Enter the event name for which the billing meter reports usage.    c. Select the aggregation method for meter events. Moesif supports the Sum and Last aggregation methods.    d. Expand Advanced Options and make sure that Event Time Window is set to Raw.    In the Advanced section, enter a description for the price.  Select Next and then select Add product to finish.For further details on creating products and prices in Stripe, refer to the Stripe documentation.You can create more products and prices by following the same steps.These steps describe how to create products and prices in Stripe with Stripe billing meters. We recommend this method for new setups. Moesif also supports Stripe prices configured for the legacy usage-records API.Integrate Moesif and StripeTo integrate Stripe with Moesif, navigate to the Billing Meters screen in Moesif. Click the Edit Billing Provider dropdown in the top right corner and select Stripe.Follow the configuration steps presented in the modal to connect Stripe to Moesif. This setup ensures Moesif can report usage to Stripe for billing purposes. For detailed guidance, refer to our Stripe Integration Documentation.Adding the Moesif Webhook to StripeStep 1: Open Webhooks in StripeThe first step in the integration is to add the Moesif webhook into the Moesif configuration for Stripe. Adding this allows Stripe to send subscription updates to Moesif.To add the Moesif webhook to Stripe, in the Stripe dashboard, click on Developers in the upper right-hand side, and then Webhooks in the left-side menu. This will bring you to the Webhooks page where you can view existing webhooks and add new ones. To add a new webhook we will click the Add an endpoint button at the bottom of the screen.Step 2: Configure the EndpointFrom here, plug in the Moesif API endpoint URL and configure the events to listen to. You’ll want to copy your Moesif Webhook URL, shown in the Stripe Settings modal displayed in Moesif, into the Endpoint URL field. After this, click the Select Events button.Step 3: Select EventsOn the Select events to send screen, Scroll to the Customer section and select the option for Select all Customer events. After this, click the Add events button at the bottom of the screen. After this, you’ll be returned to the original screen where you added the endpoint details. Scroll to the bottom of the screen and click Add endpoint to save the webhook endpoint to Stripe.For more information, refer to our documentation on adding the Moesif webhook to Stripe.Configuring the Stripe Extension in MoesifStep 1: Retrieve API KeyTo enable Moesif to report usage quantities to Stripe, you need to provide the Stripe API details in the Moesif configuration screen.For the Stripe API Key field in Moesif, retrieve your API key from Stripe by following these steps:  Log in to your Stripe account.  Navigate to the Developers section in the dashboard.  Select API Keys from the left-hand menu.  Copy either the Secret key or a Restricted key, depending on your setup needs.For more information about Stripe API Keys, refer to Stripe’s API Keys documentation.Step 2: Configure API Details in MoesifAfter copying the key from Stripe, paste the key into the Stripe API Key field on the Stripe Configuration screen in Moesif. After setting the API key value, scroll down to the bottom of the screen and click Save to save the configuration in Moesif. At this point, your Stripe integration is complete in Moesif and you can begin to use it.For detailed guidance, refer to our documentation on configuring the Stripe extension in Moesif.Setting up a Billing Meter in MoesifFor API monetization with Moesif, a Billing Meter tracks usage based on specific criteria and reports it to the billing provider. Setting up a Billing Meter involves:Step 1: Navigate to Billing MetersIn Moesif, navigate to the Billing Meters screen from the left-side menu and click Add Billing Meter.Step 2: Configure the MeterProvide the following details for your Billing Meter:            Field      Description                  Billing Meter Name      Internal name for the Billing Meter.              Billing Provider      Choose Stripe as the billing provider.              Product      Select the Stripe product tied to your usage metrics.              Price      Select the Stripe price tied to your usage metrics.              Filters      Define criteria to include only relevant API requests.      For Metrics, common options include:            Metrics Option      Description                  Volume &amp;gt; Event Count      Counts every event meeting the criteria.              Uniques &amp;gt; Users      Counts unique users sending requests that meet the criteria.              Uniques &amp;gt; Sessions/API Keys      Counts unique sessions or API keys used to send requests matching the criteria.      Step 3: Test the MeterAfter creating the meter, perform a Meter Test to verify connectivity with Stripe and confirm usage reporting. Alternatively, you can test this manually after completing your Developer Portal setup.For additional details, refer to our documentation on creating billing meters.Adding Stripe to the Moesif Developer PortalFinding Your API Key and Management URLAdding Stripe to the Moesif Developer Portal requires adding some details to the .env or docker-compose.yml file in the Developer Portal project.Find Your API KeyTo find your API Key:  Log in to your Stripe account.  Navigate to the Developers section in the dashboard.  Click on API Keys in the left-hand menu.  Copy the Perishable key.For more details, refer to Stripe’s API Keys documentation.Find Your Management URLThe Management URL is required to integrate Stripe’s Customer Portal into the Moesif Developer Portal.  To locate and activate your Management URL:  Log in to your Stripe account.  Go to the Customer Portal settings page.  Scroll to the Integration Settings section and ensure the Customer Portal is activated.Copy the Customer Portal Management URL provided in the settings. For more details, refer to Stripe’s no code customer portal documentation.Updating Environment VariablesEnvironment Variables for NodeTo configure Stripe in the Developer Portal, you will need to update two .env files located in different parts of your project:  my-dev-portal-api/.env file: This is where you configure the backend API environment.  my-dev-portal/.env file: This is where you configure the frontend environment.Backend  Open the my-dev-portal-api/.env file.  Replace the following lines with the correct values:STRIPE_API_KEY=&quot;your_api_key&quot;  Save the .env file to ensure the updated values are persisted.Frontend  Open the my-dev-portal/.env file.  Replace the following lines with the correct values:REACT_APP_STRIPE_PUBLISHABLE_KEY=&quot;your_api_key&quot;REACT_APP_STRIPE_MANAGEMENT_URL=&quot;your_management_url&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment:dev-portal-api:  environment:    - STRIPE_API_KEY=&quot;your_api_key&quot;dev-portal:  environment:    - STRIPE_API_KEY=&quot;your_api_key&quot;    - STRIPE_MANAGEMENT_URL=&quot;your_management_url&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.Next StepsNext, move on to configuring your key provisioning provider to enable secure access to your APIs and ensure seamless API key management.Verifying Billing Provider FunctionalityAfter configuring the rest of the developer portal you can verify billing provider functionality in Stripe. On the Customers screen, you should be able to see your newly created user, tracked by their email. If you click on the customer, you should also be able to see their subscription. The subscription should match the one selected in the sign-up flow in the Developer Portal.",
      "url": " /developer-portal/configure-stripe-for-checkout/",
      "author": "Matthew",
      "categories": "Developer Portal, Developer Portal Payment"
    }
    ,
  

    "developer-portal-setup-auth0-m2m-plugin": {
      "title": "Setup Auth0 M2M Plugin",
      "content"	 : "Configuring Auth0 Machine2MachineThe Moesif Developer Portal can be used with Auth0 Machine2Machine flow to generate OAuth credentials (i.e. a client id/secret) and display to customer to access your APIs. The customer can use this with OAuth client to convert into a short-lived JWT enabling access with any API gateway or framework which supports JWT including AWS API Gateway with a Lambda Authorizer.  When  Auth0 Machine2Machine flows requires a paid plan from Auth0. Alternatively, you can use the JWT provisioning plugin to achieve similar functionality.Configure the Developer PortalConfiguring the .env FileYou’ll first need to create a client in Auth0 with the correct permissions.  Log into Auth0 and navigate to “Applications”  Click Create Application and select “Machine2Machine”  Select the “Auth0 Management API” and select the following scopes:  create:client_grants  read:users  create:users  update:users  create:clients  create:organizations  read:organizations  update:organizations  create:organization_members  create:organization_client_grantsIn the my-dev-portal-api project, you’ll need to set the following envvars in your .env file:            envvar name      description                  PLUGIN_AUTH0_M2M_DOMAIN      Auth0 Domain for your account. Typically ends in auth0.com              PLUGIN_AUTH0_M2M_CLIENT_ID      Client Id for the Auth0 Application which can access the Auth0 Management API              PLUGIN_AUTH0_M2M_CLIENT_SECRET      Secret for the Auth0 Application which can access the Auth0 Management API              PLUGIN_AUTH0_M2M_API_AUDIENCE      Your own API’s audience (not Auth0 Management API)              PLUGIN_AUTH0_M2M_API_SCOPE      Your own API’s scopes (not Auth0 Management API)      Configuring API gateway or appWithin your API gateway or service, install a Moesif server integration.Configure the server integration’s identify company function to extract the org_id claim from the JWT.AWS API Gateway Specific ConfigurationIn order to set up JWT key provisioning with AWS API Gateway, you can either create a JWT authorizer or a custom Lambda Authorizer.Follow the instructions here to create a new Lambda Authorizer. Once done:  If not done already, cd into my-dev-portal-api and run npm install  Go to your newly created Lambda Authorizer in the AWS Console  Under Code source, click the Upload from dropdown and select .zip file.  Upload the zip resources/aws-authorizer/authorizer.zip to your newly created authorizer.",
      "url": " /developer-portal/setup-auth0-m2m-plugin/",
      "author": "Dylan",
      "categories": "Developer Portal, API Key Provisioning Plugin, RemoveH1"
    }
    ,
  

    "developer-portal-setup-custom-provisioning": {
      "title": "Setup Custom Provisioning",
      "content"	 : "Set up Custom Provisioning (JWT)Moesif Developer Portal allows you to set up custom key provisioning for generating API keys to control secure access to your APIs. It has built-in support for JWT tokens.The following sections describe how to set up and use JWT as the custom key provisioning system. See Build Your Own Key Provisioning Plugin for instructions on how to set up your own key provisioning system.Configure the Developer PortalConfiguring the .env FileIn the my-dev-portal-api project, you’ll need to set the following envvars in your .env file:            envvar name      description                  PLUGIN_JWT_ALGORITHM      Algorithm to use for signing JWT. The developer portal supports RS256 and HS256 algorithms.              PLUGIN_JWT_SECRET      Secret used for signing. Make sure to keep private and store in a robust key store.              PLUGIN_JWT_USER_ID_FIELD      The field in the claims that contains user id. Defaults to “sub”.              PLUGIN_JWT_COMPANY_ID_FIELD      The field in the claims that contains company (customer) id. Defaults to “org_id”.              PLUGIN_JWT_EXPIRES_IN      How long JWT is valid. Can be a number in seconds or use shorthand like “30d”.              PLUGIN_JWT_KID      The key ID value of a JWT that uniquely identifies the JWT in a JWKS (JSON Web Key Set). You must set this key for RS256-signed JWTs.      Configuring API gateway or appWithin your API gateway or service, install a Moesif server integration.Configure the server integration’s identify company function to extract the org_id claim from the JWT.AWS API Gateway Specific ConfigurationIn order to set up JWT key provisioning with AWS API Gateway, you can either create a JWT authorizer or a custom Lambda Authorizer.Follow the instructions here to create a new Lambda Authorizer. Once done:  If not done already, cd into my-dev-portal-api and run npm install  Go to your newly created Lambda Authorizer in the AWS Console  Under Code source, click the Upload from dropdown and select .zip file.  Upload the zip resources/aws-authorizer/authorizer.zip to your newly created authorizer.Build Your Own Key Provisioning PluginIf you want to implement your own provisioning system to generate API keys, implement the ProvisioningPlugin class:/** * Interface for ProvisioningPlugin * @interface ProvisioningPlugin */class ProvisioningPlugin {      /**     * Unique slug to identify plugin such as &quot;kong-konnect&quot; or &quot;auth0-jwt&quot;     * @type {string}     */    slug;      /**     * Get a user from the gateway or auth provider     * @param {string} customerId - The ID of the customer.     * @param {string} email - The email of the user.     * @returns {string} - The normalized user object.     */    getUser(customerId, email) {      throw new Error(&#39;Method not implemented.&#39;);    }        /**     * Create a new user     * @param {string} customerId - The ID of the customer.     * @param {string} email - The email of the user.     * @param {string} subscriptionId - The billing subscription ID.     * @returns {string} - The normalized user object.     */    provisionUser(customerId, email, subscriptionId)  {      throw new Error(&#39;Method not implemented.&#39;);    }        /**     * Create a new API Key     * @param {string} customerId - The ID of the customer.     * @param {string} email - The email of the user.     * @param {string} userId - The ID of the user.     * @returns {string} - The API key.     */    createApiKey(customerId, email) {      throw new Error(&#39;Method not implemented.&#39;);    }      /**     * Read config from envvars. Backwards Compatible with old envvar names     * @param {string} name - Name of the envvar     * @returns {string} - The envvar value.     */    getConfig(name) {      return process.env[name] || process.env[name.replace(&#39;PLUGIN_&#39;, &#39;&#39;)]    }  }    module.exports = {    ProvisioningPlugin,  };Then make sure you load the plugin in developer portal API’s pluginLoader.js file.For an example implementation of the ProvisioningPlugin class, see its implementation for the JWT plugin.",
      "url": " /developer-portal/setup-custom-provisioning/",
      "author": "Dylan",
      "categories": "Developer Portal, API Key Provisioning Plugin, RemoveH1"
    }
    ,
  

    "developer-portal-setup-kong-gateway-plugin": {
      "title": "Setup Kong Gateway Plugin",
      "content"	 : "Configuring Kong API GatewaySetup the GatewayThe Moesif Developer Portal can be used with a running instance of Kong. To integrate Moesif and Kong, you can follow our guide that covers integrating Moesif and Kong in detail. Alternatively, you can also check out our integration documentation for Kong if you’re already an experienced Kong user. Once you have the integration set, you’ll be able to complete the rest of the Kong setup for the Developer Portal.Configure the GatewayCreate an Endpoint in Kong GatewayTo monetize your APIs using the developer portal, you’ll need to set up an endpoint in Kong. This allows Kong to route and manage traffic to your upstream API, enabling features like authentication and rate limiting. If you already have an endpoint, you can use the existing one, provided it meets the requirements for your intended use case. Below are the steps to create a new service and route using Kong’s CLI.Create a ServiceA service in Kong represents your upstream API or microservice. Use the following command to create a service:curl -i -X POST http://localhost:8001/services     --data name=TestService     --data url=https://www.httpbin.orgIn this command:  Replace http://localhost:8001/services with URL of your Kong admin instance.  Replace TestService with the desired name for your service.  Replace https://www.httpbin.org with the URL of your upstream service.Create a RouteA route specifies how Kong should route requests to your service. To create a route for the service created in Step 1, use the following command:curl -i -X POST http://localhost:8001/routes     --data service.name=TestService     --data name=TestRoute     --data methods=GET     --data paths=/test-routeIn this command:  Replace http://localhost:8001/routes with URL of your Kong admin instance.  Replace TestService with the name of your previously created service.  Replace TestRoute with the desired name for the route.  Replace /test-route with the desired path for the route.Verify the EndpointOnce the service and route are created, you can test the endpoint to ensure it is configured correctly. Use the following command to test the route:curl -i http://localhost:8000/test-routeIn this command:  Replace http://localhost:8000/test-route with URL of your Kong instance.This command sends a GET request to the route. If everything is configured correctly, you should see a response from your upstream service (https://www.httpbin.org in this example).You should see a 200 OK response as well as a response body containing the response’s contents (essentially a webpage). With our endpoint working, now let’s move on to securing it with an API key.Configure Gateway AuthenticationAdding Key Auth to All EndpointsSince the Developer Portal generates API keys, you must add and enable the Key-Auth plugin to your Kong endpoint. For simplicity, you can enable this plugin globally. If you want to apply Key-Auth only to specific/monetized routes, you can do that as well.To add the Key-Auth plugin globally using the CLI, use the following command:curl -i -X POST http://localhost:8001/plugins     --data name=key-auth     --data config.key_names=apikey     --data enabled=trueIn this command:  name=key-auth specifies the Key-Auth plugin.  config.key_names=apikey sets the header field name to apikey.  enabled=true ensures the plugin is active.To test it out, resend the request from earlier. You should get a 401 Unauthorized response with a message body stating No API key found in request. If you are not getting this response, please refer to the Kong documentation for key-auth.Configure the Developer PortalIntegrating Kong with MoesifThe Moesif-Kong plugin simplifies sending API analytics to Moesif. To set it up, refer to our integration documentation or follow the detailed steps in our integration guide.After enabling the Moesif-Kong integration you should start seeing API call metrics in Moesif. To secure your API, ensure that unauthenticated calls are blocked by the key-auth plugin in Kong. Unauthorized requests should return 401 Unauthorized responses, which will also appear in Moesif for monitoring.Updating Environment VariablesDepending on your setup, variables can be added to either the my-dev-portal-api/.env file (for Node setups) or the distribution/docker-compose.yml file (for Docker setups).This should point to the Kong admin API URL and port, not the gateway URL/port used for traffic proxying. If you’re running Kong locally, the default admin API URL is http://localhost:8001. For remote or custom configurations, update this value to match the correct URL and port.Environment Variables for Node  Open the my-dev-portal-api/.env file.  Replace the following lines with your admin API URL:PLUGIN_APIM_PROVIDER=&quot;Kong&quot;PLUGIN_KONG_URL=&quot;http://localhost:8001&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment, replacing with your admin API URL:dev-portal-api:    environment:        - PLUGIN_APIM_PROVIDER=Kong        - PLUGIN_KONG_URL=&quot;http://localhost:8001&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.Testing the Developer PortalOnce the Developer portal is configured, testing out all of the moving parts of the Developer Portal is crucial. Doing this ensures that everything is working as intended. See our detailed testing process here.Verifying Key Provisioning Functionality via Kong CLIAfter completing the developer portal configuration, you can verify Kong functionality and key provisioning using the Kong CLI. Follow these steps:List All ConsumersUse the following command to fetch the list of all consumers in your Kong instance:curl -X GET http://localhost:8001/consumersReplace http://localhost:8001 with your Kong admin API URL if it’s running remotely.Check the response for your newly created user. The output should include details such as username, id, and custom_id.Search for a Specific Consumer by Stripe Customer IDIf you know the custom_id (e.g., the Stripe customer ID stripe_customer_ID), filter the results to locate the specific consumer entry:curl -X GET &quot;http://localhost:8001/consumers?custom_id=stripe_customer_ID&quot;Retrieve Consumer DetailsTo view detailed information about the consumer, including associated keys, use the id or username of the consumer:curl -X GET http://localhost:8001/consumers/{consumer_id_or_username}Replace {consumer_id_or_username} with the appropriate consumer ID or username.Verify the custom_id FieldEnsure that the consumer entry includes the custom_id field with the Stripe customer ID (e.g., stripe_customer_ID). This confirms that the user is successfully added, and key provisioning is functioning correctly.",
      "url": " /developer-portal/setup-kong-gateway-plugin/",
      "author": "Matthew",
      "categories": "Developer Portal, API Key Provisioning Plugin, RemoveH1"
    }
    ,
  

    "developer-portal-setup-kong-konnect-plugin": {
      "title": "Setup Kong Konnect Plugin",
      "content"	 : "Configuring Kong KonnectKong Konnect offers a suite of tools and services for managing, securing, and optimizing your APIs and microservices. The Moesif Developer Portal can seamlessly integrate with Kong Konnect to enhance your API management capabilities.We’ll cover configuring Kong Konnect for the Developer Portal in this document.Setup the GatewayIf you haven’t already, sign up for Kong Konnect and log in to the Kong Konnect Portal. Once logged in, you can begin setting up your API Gateway to integrate with Moesif.To get started, we recommend following our Kong Konnect Docker Demo for a streamlined setup.Prerequisites  A running Self-Managed Hybrid Kong Konnect Gateway.  A configured Service and Route.  The Moesif Kong Konnect plugin configured.Configure the GatewayAdding the Key Authentication PluginTo secure your endpoints, you can add the Key Authentication (keyauth) plugin and apply it globally to all routes.  Navigate to the Gateway Manager in the Kong Konnect Portal and select your Control Plane.  Go to the Plugins section and click on New Plugin.  Search for the Key Authentication plugin and select Enable.  Configure the plugin with default settings, or adjust the parameters based on your requirements.          We will assume that the plugin is applied Globally and Key Names is set toapikey.      We will include the provisioned api key from the developer portal in requests sent by including an apikey header.        Click Save to apply the plugin.Once applied, every request to your endpoints will require an API key for authentication.For more details, refer to the Kong Key Authentication Plugin documentation.Configure the Developer PortalRetrieving ValuesLog into Kong Konnect and navigate to the Gateway Manager select your control plane and take note of the following values under About this Hybrid Control Plane.  PLUGIN_KONG_URL          Locate the Admin API URL.      Copy the value and add /core-entities to the URL.      Use this value for PLUGIN_KONG_URL.        PLUGIN_KONNECT_API_URL          Locate the Admin API URL.      Take note of the base URL - will look like https://us.api.konghq.com.      Use this value for PLUGIN_KONNECT_API_URL.        PLUGIN_KONNECT_API_VERSION          Locate the Admin API URL.      Take note of the version number in the URL - will look like v2.      Use this value for PLUGIN_KONNECT_API_VERSION.        PLUGIN_KONNECT_RUNTIME_GROUP_NAME          Use the Name of the control plane.      Use this value for PLUGIN_KONNECT_RUNTIME_GROUP_NAME. By default, this is default.        PLUGIN_KONNECT_PAT          Navigate to your Profile in the Konnect UI and select Personal Access Tokens.      Generate a new token, providing a name and expiration date.      Copy the token and paste it into PLUGIN_KONNECT_PAT.      Environment Variables for NodeIf you are standing up each service in the Moesif Developer Portal individually using Node/NPM - in the my-dev-portal-api project, add the following environment variables to the .env file:PLUGIN_APIM_PROVIDER=&quot;Kong&quot;PLUGIN_KONG_URL=&quot;{your-konnect-api-url}/{your-konnect-api-version}/control-planes/{your-control-plane-id}/core-entities&quot;PLUGIN_KONNECT_API_URL=&quot;https://us.api.konghq.com&quot;PLUGIN_KONNECT_API_VERSION=&quot;v2&quot;PLUGIN_KONNECT_RUNTIME_GROUP_NAME=&quot;default&quot;PLUGIN_KONNECT_PAT=&quot;&quot;Save the .env file to ensure the updated values are persisted.Environment Variables for DockerIf you are using the Docker Compose file included in the Moesif Developer Portal repository or in the Kong Konnect Docker Demo repository, add the following environment variables to the docker-compose.yml file:dev-portal-api:  environment:    - PLUGIN_APIM_PROVIDER=Kong    - PLUGIN_KONG_URL={your-konnect-api-url}/{your-konnect-api-version}/control-planes/{your-control-plane-id}/core-entities    - PLUGIN_KONNECT_API_URL=https://us.api.konghq.com    - PLUGIN_KONNECT_API_VERSION=v2    - PLUGIN_KONNECT_RUNTIME_GROUP_NAME=    - PLUGIN_KONNECT_PAT=Save the docker-compose.yml file to ensure the updated values are persisted.Testing the Developer PortalOnce the Developer portal is configured, testing out all of the moving parts of the Developer Portal is crucial. Doing this ensures that everything is working as intended. See our detailed testing process here.Verifying Key Provisioning Functionality via Kong KonnectAfter completing the developer portal configuration, you can verify Kong functionality and key provisioning using Kong Konnect.  In Kong Konnect, select Gateway Manager and then select your Control Plane.  Select Consumers on the left navigation pane.  You should see the Username and Custom ID associated with the user created in the Developer Portal.Verify the custom_id FieldEnsure that the consumer entry includes the custom_id field with the Stripe customer ID (e.g., stripe_customer_ID). This confirms that the user is successfully added, and key provisioning is functioning correctly.",
      "url": " /developer-portal/setup-kong-konnect-plugin/",
      "author": "Dylan",
      "categories": "Developer Portal, API Key Provisioning Plugin, RemoveH1"
    }
    ,
  

    "developer-portal-setup-tyk-plugin": {
      "title": "Setup Tyk Plugin",
      "content"	 : "Configuring Tyk API GatewaySetup the GatewayThe Moesif Developer Portal can be used with a running instance of Tyk API Gateway. To integrate Moesif and Tyk, you can follow our guide that covers integrating Moesif and Tyk in detail. Alternatively, you can also check out our integration documentation for Tyk if you’re already an experienced Tyk user. Once you have the integration set, you’ll be ready to move to the next step in the Moesif Developer Portal setup process.Configure the GatewayCreating an Endpoint in Tyk DashboardFor the Moesif Developer Portal to help you monetize your APIs, you’ll require an endpoint in Tyk. If you already have an endpoint created, feel free to skip ahead to the next step in the guide. If you need to create an endpoint and are using the Tyk Dashboard, you can create the endpoint by following these steps:Log in to Tyk Dashboard:If you already have an account, log in to the Tyk Dashboard. If not, sign up for an account to get started.Create a New API:  Navigate to the dashboard’s main page.  Click on the APIs section, located in the main navigation menu.  Click the Add New API button to begin the API creation process.API Details:  Enter a suitable API Name, such as TestService.  Under Type, select HTTP.  Fill in the Upstream URL field with the URL of the service you want to expose. For this example, use http://www.httpbin.org.Select + Configure API to explore some more advanced configuration settings.API Configuration:  Under Listen path, set the listen path to whatever you would like, we will be setting it to /test-service/. Unselect strip the listen path  Choose whether to enable SSL/TLS encryption for the API in the Enable SSL/TLS field.  Specify supported protocols in the API Protocol field, such as http, https.  Set allowed HTTP methods in the Allowed HTTP Methods field. Choose GET for this case.  Under Authentication, we will want to set the Authentication Mode to Authentication Token. Under Authentication Token &amp;gt; Auth Key Header Name, type Authorization. If you would like to test your endpoint without any authentication you can set this to Open (Keyless). This is assumed in the next testing step.Save Changes:  After completing the necessary fields and configuring API settings, save the changes by clicking the Save button.Testing the EndpointTo test your newly created endpoint, you’ll want to use a tool like Postman or Insomnia. Alternatively, you could also just use a browser. In your tool, add your endpoint URL, which will look like {TYK_URL}:PORT/test-service/, and send a GET request.After the request has been sent, you should see a 200 OK response as well as a response body containing the HttpBin contents.Configure Gateway AuthenticationAdding Authentication to Your EndpointEnsure that you have set the Authentication Mode to Authentication Token within your API configuration for your endpoint. Under Authentication Token &amp;gt; Auth Key Header Name, type Authorization.Configure the Developer PortalConfiguring the .env FileIn the Developer Portal code, there are a few environment variables that you will need to populate for Tyk. Below are the details on how to find and populate these variables in the my-developer-portal-api/.env file.Tyk GatewayFor the PLUGIN_TYK_GATEWAY_URL, If you’re running a local instance of Tyk, by default this should be running on http://localhost:8080. If this is the case, you can leave the value as is. If it is different or running remotely, you can change the value to point to your Tyk gateway.Tyk Gateway SecretThis would also be a good time to grab your PLUGIN_TYK_GATEWAY_SECRET_KEY. If running in docker, your PLUGIN_TYK_GATEWAY_SECRET_KEY can be found in the tyk.conf file in the Gateway container under the &quot;secret&quot; variable.Connecting Tyk to MoesifNow that we have our endpoints in Tyk set up and our base developer portal code pulled down, we can start to get analytics flowing into Moesif from Tyk. For instructions on how to integrate Tyk and Moesif, you can reference our integration documentation or a more in-depth step-by-step approach in our integration guide.Tyk Master Key CreationFor the developer portal, an additional step is required within the Tyk configuration. In the tyk.conf file, we also need to set allow_master_keys to true. This allows us to automate authentication key creation via the Tyk API.Testing the Developer PortalOnce the Developer portal is configured, testing out all of the moving parts of the Developer Portal is crucial. Doing this ensures that everything is working as intended. See our detailed testing process here.Verifying Key Provisioning FunctionalityAfter configuring the rest of the developer portal you can verify Tyk functionality after creating a key. Head to the Tyk Dashboard, under System Management &amp;gt; Keys you should see a new key created. You should see the Alias / Key Hash Value associated with a Stripe customer ID (will resemble cus_123abc).",
      "url": " /developer-portal/setup-tyk-plugin/",
      "author": "Matthew",
      "categories": "Developer Portal, API Key Provisioning Plugin, RemoveH1"
    }
    ,
  

    "developer-portal-set-up-custom-billing-provider": {
      "title": "Setting Up Custom Billing Provider",
      "content"	 : "This document describes how to set up a custom billing provider with Moesif Developer Portal.OverviewSetting up a custom billing provider with Moesif Developer Portal involves the following steps in general:  Creating a plan and price definining the subscription of your product.  Implementing a checkout process.  For a successful checkout, implement the backend logic that performs the following tasks:          Verifies the purchase and subscription details.      Create subscription object.      Send the data to moesif.      Provision required services.      Set the Environment VariablesSet the following environment variables to custom:my-dev-portal.env.REACT_APP_PAYMENT_PROVIDER=custommy-dev-portal-api.env.APP_PAYMENT_PROVIDER=customDefine Your Product SubscriptionUse Moesif’s Product Catalog feature to create the Plan and Price for your product subscription. Make sure you create a custom plan by selecting Custom. After successfully, creating the plans and prices, the developer portal shows the available plans in the Plans page.Implement the Checkout Process FormNow you need to implement the checkout process form for your custom plan as the CustomCheckForm React component:import React from &quot;react&quot;;import { Link } from &quot;react-router-dom&quot;;function CustomCheckoutForm({ planId, priceId, user, idToken }) {  return (    &amp;lt;div id=&quot;checkout&quot;&amp;gt;      &amp;lt;div&amp;gt;        &amp;lt;h3&amp;gt;          For custom billing provider, please implement your custom check out          flow here.        &amp;lt;/h3&amp;gt;        &amp;lt;ul&amp;gt;          &amp;lt;li&amp;gt;            Typically, the flow involves redirecting to a payment gateway.          &amp;lt;/li&amp;gt;          &amp;lt;li&amp;gt;            Upon successful payment, it should come back to{&quot; &quot;}            &amp;lt;code&amp;gt;              http://127.0.0.1/return?price_id={encodeURIComponent(priceId)}              &amp;amp;plan_id={encodeURIComponent(planId)}            &amp;lt;/code&amp;gt;            , with some sort of success code or identifier          &amp;lt;/li&amp;gt;          &amp;lt;li&amp;gt;            On return page, it would make API call to backend:            &amp;lt;ul&amp;gt;              &amp;lt;li&amp;gt;to verify the payment is successful.&amp;lt;/li&amp;gt;              &amp;lt;li&amp;gt;to create the subscription.&amp;lt;/li&amp;gt;              &amp;lt;li&amp;gt;to provision any services.&amp;lt;/li&amp;gt;            &amp;lt;/ul&amp;gt;          &amp;lt;/li&amp;gt;          &amp;lt;li&amp;gt;            For now: to simulate success return from payment provider, continue            to:{&quot; &quot;}            &amp;lt;strong&amp;gt;              &amp;lt;Link                to={`/return?price_id=${encodeURIComponent(                  priceId                )}&amp;amp;plan_id=${encodeURIComponent(planId)}`}              &amp;gt;                &amp;lt;button&amp;gt;return page&amp;lt;/button&amp;gt;              &amp;lt;/Link&amp;gt;            &amp;lt;/strong&amp;gt;          &amp;lt;/li&amp;gt;        &amp;lt;/ul&amp;gt;      &amp;lt;/div&amp;gt;    &amp;lt;/div&amp;gt;  );}export default CustomCheckoutForm;Implement Successful CheckoutAfter you perform checkout through the checkout form you build in the preceding step, the following flow of events must happen:  The backend verifies the purchase and subscription details  The backend creates the subscription  The backend provisions the necessary services, if anyInitiate Successful CheckoutThe registerPurchaseCustom function function sends the purchase and subscription details to the backend for verification:function registerPurchaseCustom({  planId,  priceId,  sessionId,  idToken,  user,  setCustomerEmail,  setStatus,  setLoading,  setProvisionError,}) {  setLoading(true);  fetch(`${import.meta.env.REACT_APP_DEV_PORTAL_API_SERVER}/register/custom`, {    method: &quot;POST&quot;,    headers: {      &quot;Content-Type&quot;: &quot;application/json&quot;,      Authorization: `Bearer ${idToken}`,    },    body: JSON.stringify({      plan_id: planId,      price_id: priceId,      // session_id:      // you may have a some sort of session id or checkout id from your payment provider that you can      // use to verify purchase on the backend.    }),  })    .then(async (res) =&amp;gt; {      if (!res.ok) {        const errorBody = await res.json();        throw new Error(          `Failed provision: ${res.status}, body: ${JSON.stringify(errorBody)}`        );      }      return res.json();    })    .then((data) =&amp;gt; {      setStatus(&quot;complete&quot;);      setCustomerEmail(user?.email);    })    .catch((err) =&amp;gt; {      setProvisionError(err);    })    .finally(() =&amp;gt; {      setLoading(false);      moesifIdentifyUserFrontEndIfPossible(idToken, user);    });}It sends the purchase and subscription details, like plan and price IDs, to the /register/custom endpoint. The next step shows how you you can verify those details.Verify Successful PurchaseThe verification involves these steps:      Implement the BillingProvider class containing the verification logic. It must work with your custom billing provider to verify that a purchase is successful and return the subscription details accordingly. For example, the following assumes a successful purchase, creates a hard-coded subscription object, and returns it:     class BillingProvider {   verifyPurchaseAndCreateSubscription(req, data) {     // use the request info to verify the purchase after checkout     // but generally your billing provider should verify the subscription     // and return the subscription object.     // below is a fake subscription generated on the fly.         const subscription = {       id: generateGUID(),       plan_id: data?.plan_id,       price_id: data?.price_id,       ...data,       current_period_start: new Date().toISOString(),       current_period_end: getOneMonthFromNowISO(),     };         return {       subscription,     };     // throw new Error(&#39;Verify Purchase Not Implemented.&#39;);   } }            Write the handler function for HTTP POST request to /register/custom endpoint that uses the BillingProvider implementation to verify purchase and create subscription. For example:     app.post(   &quot;/register/custom&quot;,   authMiddleware,   jsonParser,   async function (req, res) {     const customerId = await getUnifiedCustomerId(req.user);     const email = req.user?.email;     // verify plans and subscription using your custom billing provider.     try {       const { subscription } =         await customBillingProvider.verifyPurchaseAndCreateSubscription(req, {           user: req.user,           ...req.body,         });           console.log(&quot;custom subscription created&quot;, subscription);           syncToMoesif({         companyId: customerId,         userId: customerId,         email: email,       });           sendSubscriptionToMoesif({         companyId: customerId,         subscriptionId: subscription.id,         planId: subscription.plan_id,         priceId: subscription.price_id,         currentPeriodStart: subscription.current_period_start,         currentPeriodEnd: subscription.current_period_end,         metadata: {           // additional metadata you might want add.         },       });           const user = await provisioningService.provisionUser(         customerId,         email,         subscription.id       );       res.status(201).json({ status: &quot;provisioned&quot; });     } catch (err) {       console.error(&quot;Error registering user&quot;, err);       res.status(500).json({         message: &quot;Failed to provision user. &quot; + err.toString(),       });     }   } );        Here, the callback function extracts the subscription object from your implementation  of BillingProvider for a successful purchase. It then sends the subscription  data to Moesif and provisions the user services.  ",
      "url": " /developer-portal/set-up-custom-billing-provider/",
      "author": "Sakib",
      "categories": "Developer Portal"
    }
    ,
  

    "developer-portal-using-the-developer-portal": {
      "title": "Using the Developer Portal",
      "content"	 : "The Developer Portal has been configured, and now it’s time to run and test it. This guide walks you through starting the portal using either Node or Docker, along with steps for testing and verifying its functionality.Running with NodeTo configure and run the Developer Portal using Node / NPM, you need to set up the relevant environment variables for front-end and back-end communication.BackendThis my-dev-portal-api/.env file contains the relevant environment variables for the back-end communication.FRONT_END_DOMAIN=127.0.0.1:4000FrontendThis my-dev-portal/.env file contains the relevant environment variables for the front-end communication.# Frontend portal serverHOST=&quot;127.0.0.1&quot;PORT=&quot;4000&quot;# Portal API serverREACT_APP_DEV_PORTAL_API_SERVER=&quot;http://127.0.0.1:3030&quot;Ensure all other configurations are correctly set in their respective .env files. Once the .env files are configured, follow these steps to start the Developer Portal:      Start the API Application          Navigate to the /my-dev-portal-api directory in your terminal.              Run the following command:        node app.js                    Keep this terminal running.            Start the Front-End UI Project          Open another terminal at the /my-dev-portal directory.              Run the following command:        npm start                    Keep this terminal running.      Running with DockerYou can also run the Developer Portal using Docker. Ensure that Docker and Docker Compose are installed on your system. The following docker-compose.yml configuration lists the relevant environment variables, but be sure to include your current configuration:version: &#39;2&#39;services:  dev-portal:    image: moesif/dev-portal    ports:      - 4000:4000    environment:      - HOST=127.0.0.1      - PORT=4000      - REACT_APP_DEV_PORTAL_API_SERVER=http://dev-portal-api:3030  dev-portal-api:    image: moesif/dev-portal-api    ports:      - 3030:3030    environment:      - FRONT_END_DOMAIN=127.0.0.1:4000To start the Developer Portal with Docker:      Run the following command from the distribution/docker directory:     docker-compose up -d      Testing the Developer PortalOnce the Developer Portal is configured and running, thorough testing is essential to ensure functionality across multiple platforms. Follow these steps:  Open your browser and navigate to the Developer Portal.  At the Home Screen, click the Sign Up button in the top-right corner.  Fill out the form to create a user.  Subscribe to a product of your choice.  Complete the checkout process.  You should then land on the Dashboard screen of the Developer Portal.These steps help ensure that you can provision an API key and attribute API calls to specific users accurately.Verifying FunctionalityAfter setup, verify that the newly created user has been propagated to all connected services. Check each service, such as identity, billing, and key provisioning platforms, to confirm proper integration. Refer to the documentation for your specific plugin providers for further details.",
      "url": " /developer-portal/using-the-developer-portal/",
      "author": "Matthew",
      "categories": "Developer Portal"
    }
    ,
  

    "developer-portal-configuring-the-management-api": {
      "title": "Configuring the Management API",
      "content"	 : "The Dashboard of the Moesif Developer Portal is powered by Moesif Embedded Templates which utilizes Moesif’s Management API. This functionality enables charts and visualizations in Moesif to be seamlessly displayed within the developer portal. Additionally, the management API allows Stripe to display plans and prices within the developer portal.Creating a Management Token for API AccessTo enable API access for Stripe to retrieve plans and prices, and for the Developer Portal to utilize embedded templates, follow these steps to create a management token:  Navigate to Your Moesif Profile:          Go to Profile &amp;gt; API Keys.        Configure Token Permissions:          Set read access for the following resources:                  User          Company          Plans          Price          Subscriptions          Workspaces          Public Workspaces                      Set an Expiration Date (Optional):          Specify an expiration date for the token if needed.        Generate the Token:          Click Generate Token to complete the process.      Copy the generated key for later use. The generated token will be essential for integrating Moesif Embedded Templates and Stripe into the Developer Portal.Updating Environment VariablesTo integrate the management token and templates, update the environment variables for your development setup.Environment Variables for Node  Open the my-dev-portal-api/.env file.  Replace the following lines with the correct values:MOESIF_MANAGEMENT_TOKEN=&quot;your Moesif management token&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment:dev-portal-api:   environment:      - MOESIF_MANAGEMENT_TOKEN=&quot;your Moesif management token&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.Next StepsAfter updating the environment variables, save the changes and proceed to configuring the dashboards.",
      "url": " /developer-portal/configuring-the-management-api/",
      "author": "Dylan",
      "categories": "Developer Portal"
    }
    ,
  

    "developer-portal-configuring-the-dashboards": {
      "title": "Configuring the Dashboards",
      "content"	 : "The Dashboard of the Moesif Developer Portal is powered by Moesif Embedded Templates. This functionality enables API logs, usage metrics, and other visualizations to be seamlessly displayed within the developer portal for your customers.Adding Embedded Templates to the DashboardThe Dashboard of the Developer Portal includes two key visualizations sourced from Moesif: a Live Event Log and a Time Series Chart. These charts provide insights into user activity trends and detailed call logs. To set up these embedded templates, follow the steps below:Create the Live Event Log  In Moesif, click the New button in the top-left menu and select Live Event Log.  Once the log is displayed, click Embed/API in the top-right corner.  In the Embed/API Access modal:          Select Embed Template under Select Integration Type.      Name the template (e.g., “Live Event Log”).      Enable Dynamic User ID in the Sandbox Policy section.        Click Get Embed Code to generate the embed code. Copy the workspace id in the first paragraph for later use.Create the Time Series Chart  In Moesif, click the New button and select Time Series.  Once the chart is displayed, click Embed/API in the top-right corner.  In the Embed/API Access modal:          Select Embed Template under Select Integration Type.      Name the template (e.g., “Time Series”).      Enable Dynamic User ID in the Sandbox Policy section.        Click Get Embed Code to generate the embed code. Copy the workspace id in the first paragraph for later use.Updating Environment VariablesTo integrate the management token and templates, update the environment variables for your development setup.Environment Variables for Node  Open the my-dev-portal-api/.env file.  Replace the following lines with the correct values:MOESIF_TEMPLATE_WORKSPACE_ID_LIVE_EVENT_LOG=&quot;workspace ID&quot;MOESIF_TEMPLATE_WORKSPACE_ID_TIME_SERIES=&quot;workspace ID&quot;  Save the .env file to ensure the updated values are persisted.Environment Variables for Docker  Open the distribution/docker-compose.yml file.  Add or update the following entries in the relevant service configuration under environment:dev-portal-api:   environment:   - MOESIF_TEMPLATE_WORKSPACE_ID_LIVE_EVENT_LOG=&quot;workspace ID&quot;   - MOESIF_TEMPLATE_WORKSPACE_ID_TIME_SERIES=&quot;workspace ID&quot;  Save the docker-compose.yml file to ensure the updated values are persisted.Next StepsAfter updating the environment variables, save the changes and proceed to using the Developer Portal.",
      "url": " /developer-portal/configuring-the-dashboards/",
      "author": "Matthew",
      "categories": "Developer Portal"
    }
    ,
  

    "product-catalog": {
      "title": "Introduction to The Product Catalog",
      "content"	 : "The Product Catalog in Moesif lets you manage all of your billing plans and prices. With the product catalog, you can easily create, manage, view, and archive plans and prices across your billing providers. This creates a simple and easy-to-use interface to create products within billing providers that are compatible with Moesif’s API metering and billing solution.Benefits of Product Catalog  Business owners can create plans and prices right in the Moesif UI without having to access billing systems. This eliminates managing two different systems and therefore saves resources.  Your billing system remains as the system of record where Moesif pushes to. Therefore, your accounting flows don’t suffer any impact.  You have a single set of APIs to query your product catalog, providing a layer of abstraction.  Product Catalog makes it easy to use multiple billing systems in parallel. For example, using Zuora for enterprise customers and Stripe for self-service.Navigating to the Product CatalogTo get to the Product Catalog screen, select Product Catalog from the navigation menu.How Product Catalog WorksMoesif pushes and pulls product information from your billing system. Your billing provider remains the source of truth which ensures accounting and finance flows don’t suffer any impact.When you create a plan or price in Moesif, it shows up in your billing provider.Provider MappingEach provider may have slightly different terminology. The following table provides an outline:            Moesif      Stripe      Chargebee      Recurly      Zuora                  Plan      Product      Item Plan      Plan      Rate Plan              Price      Price      Item Price      Add-On      Rate Plan Charge              Subscription      Subscription      Subscription      Subscription      Subscription      How to Model Plans and PricesWe recommended that you create different plans when the package has significant differences in terms of its offerings and nature. For example, you can have different tiers, each with a unique set of features or entitlements. However, we recommend that you create multiple prices under the same plan to model different price points. For example, you may have different prices for annual, monthly, and volume discounts all under the same plan.Here’s an example using Moesif pricing:Free Plan  Free PriceGrowth Plan   - Growth Annual (1m Events/mo) Price      - Amount for USD      - Amount for CAD   - Growth Monthly (1m Events/mo)  Price      - Amount for USD      - Amount for CAD   - Growth Annual (5m Events/mo) Price      - Amount for USD      - Amount for CAD   - Growth Annual (5m Events/mo) Price      - Amount for USD      - Amount for CADEnterprise Plan  - Enterprise Yearly    (500m Events/mo) Price  - Enterprise Yearly    (1,500m Events/mo) Price",
      "url": " /product-catalog/",
      "author": "Matthew",
      "categories": "Billing, Product Management"
    }
    ,
  

    "product-catalog-managing-plans": {
      "title": "Managing Plans in the Product Catalog",
      "content"	 : "Using the Product Catalog, you can create plans through a single, simple interface across billing providers. You can also manage all plans across all of your billing providers in a single area, making for a seamless and convenient experience.The Plans ScreenTo get to the Plans screen, select Plans under Product Catalog from the navigation menu.Stripe currently calls their plans Products. Therefore, a Moesif Plan maps to a Stripe Product.The Plans screen shows a list of plans available across your billing providers. The list contains the following details about your plans:  Provider  The platform or provider where the plan lives.  Plan Name  The internal plan name.  ID  The plan’s unique identifier, created by the billing provider.  Status  The status of the plan, Active or Archived.  Created at  The date and time when the plan was first created.  Modified at  The date and time of the last time the plan was updated or modified.  Actions  A sub-menu that allows users to view, clone, and set the status of the plan.PrerequisitesTo create a plan in Moesif, make sure you meet the following requirements:  Have an active account with a billing provider—for example, Stripe.  Have the billing provider integrated with Moesif.Creating a PlanTo create a plan, in the Plans screen, select Create New.In the new screen, specify a name for your plan and choose a billing provider.Depending on the billing provider you choose, you must fill out the necessary details for the plan. For example, for Stripe, you have the following details:  ID  An auto-generated plan identifier. Stripe creates it for internal usage.  Unit label  Optional.    A label representing units of the product or plan. Corresponds to the Stripe Product’s unit_label parameter.    Description  Optional.    This field can hold a description to help with the internal identification of the plan.    Metadata  Optional.    In this field, you can add plan metadata as JSON key-value pairs. It corresponds to the Stripe Product’s metadata parameter.  Once you’ve populated the applicable fields, select Create to create the plan.Updating a PlanTo update a plan, follow these steps from the Plans screen.  Select the plan name that you want to update. Alternatively, select ⋮ Actions and then select View Details.  Make your changes.  Select Save.Note that you can’t edit all the details of a plan. For auditing purposes, certain fields remain read-only after you create a plan. In general, you can edit the following details:  Plan name  Plan status  Description  MetadataArchiving a PlanTo archive a plan, select ⋮ Actions and then select Archived.Alternatively, select the name of the plan you want to archive and then select Archived from the dropdown next to the plan name. Then select Save.Cloning a PlanTo make a copy of an existing plan, follow these steps:  Select Product Catalog and then select Plans from the navigation menu.  For the plan you want to make a copy of, select ⋮ Actions and then select Clone.  Fill out the necessary details of your plan.  Select Create.",
      "url": " /product-catalog/managing-plans/",
      "author": "Matthew",
      "categories": "Billing, Product Catalog"
    }
    ,
  

    "product-catalog-managing-prices": {
      "title": "Managing Prices in the Product Catalog",
      "content"	 : "Using the Product Catalog, you can create prices and add them to plans through a single, simple interface across billing providers. You can also manage all prices across all of your billing providers in a single area, making for a seamless and convenient experience.The Prices ScreenTo get to the Prices screen, select Prices under Product Catalog from the navigation menu.The Prices screen shows a list of prices available across your billing providers.The list contains the following details about your prices:  Name  The internal price name.  ID  The price’s unique identifier the billing provider creates.  Parent Plan  The plan to which the price applies to.  Period  The billing period that the price applies to.  Pricing Model  The price’s applicable pricing model.  Created At  The creation date and time of a plan.  Status  The status of the price, Active or Archived.  Actions  A sub-menu that allows users to view, clone, and set the status of the price.PrerequisitesTo create a price in Moesif, make sure you meet the following requirements:  Have an active account with a billing provider—for example, Stripe.  Have the billing provider integrated with Moesif.  Create a plan within the billing provider to attach the price to.Creating a PriceTo create a plan, in the Prices screen, select Create New.Moesif supports creating metered and recurring prices. We recommend that you create one-time fees and shippable items directly in your billing system.In the new screen, you can add the following details to your price:Price NameThe name that identifies your price internally.IDThe auto-generated price identifier. The billing provider creates it for internal usage.Linked PlanThe plan that the price links to.MetadataOptional.Allows you to add price metadata.PricingAllows you to specify the following pricing details:  Pricing model  Price structure  Usage measurement methodPricing ModelAllows you to designate the pricing model that the price applies to. The pricing models that appear here depend on the billing provider. For example, the following pricing models are available for Stripe:  Per Unit (Package)  Volume Tiers  Graduated Tiers  FlatThe exact details about how these pricing models work also depend on the billing provider. For Stripe, see Recurring pricing models to understand how Stripe’s pricing models work.Price StructureHere, you can specify the price structure and the unit of currency. For example, if you charge per unit, specify the price per unit and choose USD as the currency.Usage Measurement MethodFor usage-based pricing models, depending on the plan you link the price to and the billing provider, you can specify the usage calculation and aggregation methods.For Stripe, the Per Unit, Volume Tiers, and Graduated Tiers pricing models lets you choose between the following two options:  Stripe Price Meter  Uses Stripe Meter. We recommend you choose this option.    After selecting this option, you must:          Select the Stripe Meter to attach the price to or create a new Stripe Meter.      Specify the period of time over which to aggregate the usage.        To create a new Stripe Meter, select Create New Meter. Then enter the following meter details:          Meter name      The event name the meter tracks      The method for aggregating usage data        Moesif supports Sum and Last as usage aggregation methods.    Legacy Usage Aggregation  Uses Stripe’s legacy usage-records billing.    After selecting this option, specify how to aggregate usage. For example, you can choose to sum all consumed units per month by selecting Sum of unit(s) used for per Month from the dropdown menus.  Pricing OptionsThis section allows you to specify how taxes apply to the price. Similar to pricing models, the options available in this section depend on the billing provider. For example, the following tax structure options are available for Stripe:  Auto  Pricing includes tax  Pricing does not include taxOnce you’ve populated the applicable fields, select Create to create the price.Updating a PriceTo update a price, follow these steps from the Prices screen.  Select the price name that you want to update. Alternatively, select ⋮ Actions and then select View Details for the price you want to update.  Make your changes.  Select Save.Note that you can’t edit all the details of a price. For auditing purposes, certain fields remain read-only after you create a price.Archiving a PriceTo archive a price, select ⋮ Actions and then select Archived.Alternatively, select the name of the price you want to archive and then select Archived from the dropdown next to the price name. Then select Save.Cloning a PriceTo make a copy of an existing price, follow these steps:  Select Product Catalog and then select Prices from the navigation menu.  For the price you want to make a copy of, select ⋮ Actions and then select Clone.  Fill out the necessary details of your price.  Select Create.",
      "url": " /product-catalog/managing-prices/",
      "author": "Matthew",
      "categories": "Billing, Product Catalog"
    }
    ,
  

    "product-catalog-api-access": {
      "title": "Get API Access to Plan and Price Data in Product Catalog",
      "content"	 : "Moesif gives you API access to billing plan and price data in the Product Catalog through the Management API. Moesif automatically generates the HTTP request for you with the necessary credentials. After processing the request, Moesif sends back a JSON response with the data.This feature allows you to securely integrate your billing plans and prices information into external workflows and applications.Access Plan Data through API  Select Plans under Product Catalog in the navigation menu.  Select Embed / API. Moesif generates a cURL command that you can use immediately to access data of your existing plans. Moesif also gives you the HTTP request details for using any HTTP client.  Select the Curl Command tab for the cURL command and the HTTP Details tab for the HTTP request details.Access Price Data through API  Select Prices under Product Catalog in the navigation menu.  Select Embed / API. Moesif generates a cURL command that you can use immediately to access data of your existing prices. Moesif also gives you the HTTP request details for using any HTTP client.  Select the Curl Command tab for the cURL command and the HTTP Details tab for the HTTP request details.",
      "url": " /product-catalog/api-access/",
      "author": "Sakib",
      "categories": "Billing, Product Catalog"
    }
    ,
  

    "platform": {
      "title": "Platform Overview",
      "content"	 : "Platform OverviewThe Moesif platform enables you to understand and monetize API usage with a powerful analytics and billing platform.Moesif ingests event data from your API products and traditional web based applications via the Collector API. The analytics and monitoring is handled within the Moesif infrastructure which ensures you have low maintenance overhead.As an open platform, Moesif can sync usage records to customer data platforms like Segment and HubSpot. Moesif also provides API monetization capabilities by connecting to billing systems like Stripe, Recurly, Chargebee and Zuora.Data ModelYour event data can be modeled as API Calls and Custom Actions:  API Calls performed against your APIs such as API Gateways like Kong and Amazon API Aateway  Custom Actions performed within your web apps such as React or Javascript. This also includes events from customer data platforms like Segment.Customers are modeled using both companies and users:  A company is typically your direct customer and is typically an organization  A user is a member of the company (such as end user or employee and the organization)Custom metadata can be stored with any of these four entities as shown above.",
      "url": " /platform/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-dynamic-sampling": {
      "title": "Dynamic Sampling",
      "content"	 : "Dynamic sampling is a cost-savings feature that lets you control which API calls are logged to Moesif based on customer or API behavior. This can be done within the Moesif UI and doesn’t require any code changes or restarts. Moesif will push new rules to your server integrations automatically.Because Moesif never receives skipped API calls, they do not count against your subscription’s event quota. In addition, Moesif automatically extrapolates and normalizes metrics, so your reporting is accurate even if different customers and behaviors have different sample rates.Example use casesBelow are some common examples of how you can leverage dynamic sampling:  Sample customers who signed up in the last 90 days at 100% for maximum support visibility; everyone else is sampled at 50%  Down-sample your largest volume of customers to 25%, so they don’t consume your quota.  Suppress collection of health probes and other low-value traffic.  Opt-out specific customers from data collection based on their contract terms and privacy requirements.  Ensure all 4xx or 5xx errors are always logged (100% sample rate)You can create sampling rules based on customer demographics, user behaviors, and specific regex matches on API fields like URI or status codes.Dynamic Sampling is available only on enterprise plans. Companies with high-volume APIs (millions or billions of API calls per day) benefit most from the cost savings from dynamic sampling. {: .text-center .notice–info}How sampling worksWith sampling, Moesif only sees a portion of your API traffic based on behaviors which can be any of:  User or company behavior (such as whether they signed up in the last 90 days or experienced an error during the previous 7 days).  User or company demographics (such as free vs. paid customers).  API attributes such as status code or URI.Because Moesif doesn’t see all traffic, you can reduce your Moesif subscription cost as sampled API calls do not count against your quota. So, for example, if your API usually sees 1 billion API calls per month, but you set the global sample rate to 25%, you only need a plan for 250 million events per month. However, because Moesif has full knowledge of your sampling rules, the platform is intelligent enough to extrapolate usage metrics even if different customers have different sample rates.Dynamic Sampling works only on API Calls. Actions triggered from a UI are not sampled. {: .text-center .notice–info}How to set sample ratesMoesif supports four levels of sampling (prioritized in this order):  Sample API calls for a single user or company  Sample API calls based on regex rules on API fields like specific URIs  Sample API calls based on user behaviors and demographics (via saved cohorts)  Sample API calls globallySample rates are prioritized in the above order. If both the user and company have a defined sample rate, the user’s rate always takes priority over the company’s rate. Meaning a sample rate set for a specific customer takes precedence over the sample rate associated with a behavioral cohort that a customer belongs to. Unsurprisingly, the global sample rate has the lowest priority and is, by default, set to 100% for all customers.To access dynamic sampling, click your Avatar at the bottom left of the navigation pane and select Dynamic Sampling.User behavior-driven samplingBehaviorally driven sampling is the most powerful and common way to leverage dynamic sampling. With behaviorally driven sampling, you apply a sample rate to members of a behavioral cohort, such as “Companies who made over 1M API Calls last 4 weeks” or “Newly integrated users who made purchase transactions.” You can create both a company rule and a user rule.For high reliability, set your global sampling rate to the “expected” sampling you want for most customers, and do not set global sampling to a very low number, like 1%. Then, use behavioral cohorts to opt-in groups of users/companies to higher or lower sample rates. Behavioral cohorts are dynamically refreshed every few minutes. However, there is a small window where a new user or company has not yet enrolled into a cohort and has their rates propagated to your server integration. This causes the user/company to fall back to global and regex-based sampling rules.To set a sample rate for a cohort of users or companies:1. Save a behavioral cohortIf you have not created a behavioral cohort (which drives sampling rules and governance rules, among other things), you will need to create one.  Click the orange new button at the top left, and select User Cohort or Company Cohort.  Add the customer demographics or behavioral filters you want for the cohort; once done, click the _Create Cohort_button at the top left and give it a name.In this example, we are selecting users who were created in the last 4 months and performed at least 1 API call to either /widgets/buying or /purchases in the last year.2. Set the sample rate for the cohortOnce you have created a cohort, go back to Dynamic Sampling from the bottom left menu. Then, click the orange + Rule button and select New User Rule or click New Company Rule based on what you created in step 1.From here, you will see a list of saved behavioral cohorts. Select one and then set the sample rate.In this case, 100% means to log all API calls, whereas 0% suppresses all data collection.Static rate for a single user or companyFinally, any user or company can have a defined sample rate from 0% to 100%. By default, all users sample 100% of API traffic (i.e., all traffic). Reducing any customer to 0% effectively suppresses all data collection for that user (A mechanism to enable GDPR/CCPA compliance). A use case of leveraging user-level sampling is to set your 10 largest customers to a less than 100% sample rate, which will collect 100% of API traffic for all others.To set the sample rate for an individual user or company, click on Users or Companies in the top header, then look up the user or company of interest. Once you open their profile view, click the orange button Edit Sample Rate.Regex rulesRegex rules allow you to dynamically adjust sample rates based on specific fields within the API call. For example, you may want to log any response status code &amp;gt; 400 at 100%. You can also use regex rules to suppress data collection on uninteresting traffic such as GET /health/probe. API Calls do not need to be attributed to a user or company for regex rules to work, which makes them perfect for health probes and test traffic.To get started, click your Avatar at the bottom left and select the Dynamic Sampling menu.Click the orange + Rule button and select New Regex Rule. This will open a panel where you can choose the fields and the regular expression to match.Select the field to match on, such as the Request Route or the Response Status. Then, add your regular expression. If you need help, view regex101 to build one.Then select the sample rate that should be applied for this regular expression. In the above example, we want to suppress data collection for non-interesting traffic by not logging health probes.Global samplingThe global sample rate is used by any user (or company) that doesn’t have its own sample rate nor belongs to any behavioral cohort. To modify the global sample rate, click on Settings button.This also brings up two other options to suppress traffic: IP addresses, IP address ranges, and known bots and crawlers.Auditing effective sample ratesThere are two ways to audit the effective sample rate for a customer. First, the effective rate includes any statically defined sample rate for a user/company, that could be used for GDPR compliance, and any sample rates that are dynamically set by behavioral cohort rules. It does not include non-customer-centric rates like regex rules which are applied on a per-request level. To view the effective sample rate for a customer:  Go to any user or company profile to view the Sample Rate.  Click your Avatar at the bottom left, select Dynamic Sampling, and click the orange Settings button at the top. A modal will appear with the following at the bottom of the window:The time when your cohort rules were last updated is also displayed. This means the most recent time when either you manually saved the cohort criteria or because a user/company was added or removed from a cohort based on their behavior. If the cohort hasn’t been updated, this could imply no customers have been added or removed recently.SDK/Plugin support for Dynamic SamplingContact us if your SDK is not supported and we can prioritize on our roadmap.            SDK      User Rule      Company Rule      Regex Rule              AWS Lambda Node      Y      Y      N              AWS Lambda Python      N      N      N              AWS Lambda GO      N      N      N              AWS Lambda Ruby      N      N      N              Azure APIM      Y      Y      N              Cloudflare      Y      Y      N              C# .NET      Y      Y      Y              Envoy      Y      Y      Y              Go      Y      Y      N              Java Servlet      Y      Y      N              Kong API Gateway      Y      Y      Y              K8s NGINX Ingress      Y      Y      N              NGINX      Y      Y      Y              Node.js      Y      Y      N              PHP Laravel      N      N      N              PHP Slim      Y      Y      N              PHP Symfony      N      N      N              Python Django      Y      Y      Y              Python Tornado      Y      Y      N              Python WSGI      Y      Y      Y              Python ASGI      Y      Y      N              Python Requests      Y      Y      N              Ruby Rack      Y      Y      Y              Tyk API Gateway      Y      Y      N              3Scale      Y      Y      N              Play Filter      Y      Y      N      ",
      "url": " /platform/dynamic-sampling/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-secure-proxy": {
      "title": "Secure Proxy",
      "content"	 : "With the Secure Proxy appliance, sensitive data can stay private to your organization via client-side encryption and customer-managed keys. You gain the privacy benefits of an on-premises installation without the cost of maintaining your own data infrastructure. It’s recommended if you’re in a regulated environment with sensitive data such as financial or healthcare and can help you meet any internal compliance requirements like HIPAA (more info on security and compliance).For a case study, view How pVerify Deploys Moesif HIPAA-Compliant API Analytics to scale COVID testing.How it worksThe secure proxy is deployed as a Docker container in your infrastructure which handles encryption and decryption on the fly using your customer-managed keys. Because your master keys are never transmitted or stored on Moesif servers, its employees cannot access or inspect your API data.Secure proxy is available only on enterprise plans. Reach out to our sales team for help.KeystoreThe secure proxy has connectors for popular Cloud key stores and will automatically rotates data keys as needed. Currently, AWS Key Management Service (KMS), AWS CloudHSM, and Azure Key Vault are supported. If you require an alternative, reach out to our success team.Moesif always encrypts your data at rest and in motion using Moesif-managed keys even if Secure Proxy is not deployed. Secure Proxy is an additional privacy layer enabling you to have full control over encryption keys (also called customer-managed keys).Features supportedThe majority of Moesif features will function normally even with the secure proxy deployed including the dashboards, Management API, alerts, and embedded dashboards. Moesif built a customized analytics store which works on encrypted data enabling you to still gain the reports you expect from Moesif. There are some minor limitations which we recommend reviewing before deploying secure proxy.AccessThere are two different ways to deploy secure proxy depending on whether you plan on utilizing Moesif’s embedded dashboards feature:      Local network only: If you don’t plan to use Moesif’s embedded dashboards feature, you can deploy the secure proxy on an internal host that’s not exposed to the internet.However, the host must be accessible by an employee’s laptop when they log into the Moesif portal such as by being on a corporate VPN.        Exposed to the internet: If you plan on using Moesif’s embedded dashboards feature, the secure proxy must be accessible by the internet so that your customers can also decrypt their data on the fly. The recommended way to do so is to deploy NGINX with SSL in front of Moesif secure proxy with SSL. A Docker example with NGINX and Moesif Secure Proxy is available on GitHub. Once done, you can add a CNAME or A Record to your DNS settings like analytics.acmeinc.com. Employees can also access the Moesif portal on the go and do not need to be on a corporate VPN.  What’s encryptedAll sensitive data such your HTTP headers, request and response body, and event metadata is encrypted. Non-sensitive fields such as request time is not encrypted for proper analytics. More info on unencrypted data.ExampleA working docker-compose.yml is available on GitHub with moesifproxy and NGINX configured with SSL termination using Let’s Encrypt.How to install1. Generate API KeysYou will need both your Collector Application Id and a Management API Key which can be found by logging into Moesif and going to API Keys from the menu.For Management API Key, ensure you generate with at least the following scopes:  create:events  read:events  create:encrypted_keys  read:encrypted_keys  read:workspaces  update:workspaces  read:virtual_eventtypes  update:virtual_eventtypes2. Create AWS Key Management ServiceWithin your AWS Consle, create a new AWS Key Management Service. You can also use an existing KMS instance if preferred. Once AWS KMS is deployed, create a new symmetric encryption key within AWS KMS. Ensure the key type is set to symmetric and the use case, select Encrypt and decrypt.Obtain your Customer Key Id from the AWS Console. This will be set in AWS_CUSTOMER_KEY_ID in the later steps. To find your Key Id please follow the instructions here.3. Create IAM Policy to access KMSWith AWS Console, create a new IAM policy which can access AWS KMS. Edit the policy using JSON editor and paste in the JSON below. If using Option B: AWS KMS access assuming an IAM role, you’ll also need permission to assume roles.{  &quot;Version&quot;: &quot;2012-10-17&quot;,  &quot;Statement&quot;: [    {      &quot;Effect&quot;: &quot;Allow&quot;,      &quot;Action&quot;: &quot;kms:*&quot;,      &quot;Resource&quot;: &quot;*&quot;    },    {      &quot;Effect&quot;: &quot;Allow&quot;,      &quot;Action&quot;: &quot;sts:AssumeRole&quot;,      &quot;Resource&quot;: &quot;*&quot;    }  ]}The above example will apply to all resources. As a best practice, you should set the “Resource” key to the ARN of the individual resources.4. Run the Docker imageRun the moesif/moesifproxy:latest docker image which is available in Docker Hub. In order for the secureproxy to access your AWS KMS, there are two ways to authenticate: You can either use Option A: AWS KMS access with access key or Option B: AWS KMS access assuming an IAM role.Option A: AWS KMS access with access keyThis option is the simplest which uses AWS access keys. These are passed to the secure proxy using the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.  Within AWS Console, create a new IAM User. Ensure Access key - Programmatic access is checked.  Then, associate the newly created user with the IAM policy created in the last step.  Using the user’s credentials, set AWS_CUSTOMER_KEY_ID and AWS_SECRET_ACCESS_KEYYou can run the secureproxy using Docker run like below:docker run -it  -e MOESIF_MANAGEMENT_API_KEY=&quot;Your Moesif Management Key&quot;  -e MOESIF_APPLICATION_ID=&quot;Your moesif application Id&quot;  -e AWS_CUSTOMER_KEY_ID=&quot;Your customer managed key(CMK) in AWS KMS&quot;  -e AWS_ACCESS_KEY_ID=&quot;Your AWS access Key Id&quot;  -e AWS_SECRET_ACCESS_KEY=&quot;Your AWS secret access key&quot;  -e AWS_KMS_REGION=&quot;Your AWS KMS region such as &#39;us-west-2&#39;&quot;  -p 9500:9500 --name moesifproxy moesif/moesifproxyIn Option A, AWS_SECURE_PROXY_ROLE_ARN and AWS_KMS_REGION are not defined.Option B: AWS KMS access assuming an IAM roleThis option provides additional security vs Option A as developers don’t need to store long-lived AWS credentials in environment variables. Instead, the secureproxy will use temporary AWS credentials to assume the IAM role which was created in last step to access your AWS KMS instance. In order for Secure Proxy to assume role in AWS_SECURE_PROXY_ROLE_ARN, base credentials must already been injected by AWS or K8s service accounts to your container.If you are using AWS EKS, follow the AWS Docs for Kubernetes Service Accounts. If you’re using EC2 directly, follow the AWS Docs for EC2.Note that for EC2 credential injection, if you are using a single role to inject into the instance and also to assume the role in AWS_SECURE_PROXY_ROLE_ARN, you will need to add the following trust policy to the role you are injecting into the instance in addition to a trust policy allowing the EC2 service to assume the role in AWS_SECURE_PROXY_ROLE_ARN. This requirement is a recent change by AWS which is announced here: https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/{  &quot;Version&quot;: &quot;2012-10-17&quot;,  &quot;Statement&quot;: [    {      &quot;Effect&quot;: &quot;Allow&quot;,      &quot;Action&quot;: &quot;sts:AssumeRole&quot;,      &quot;Principal&quot;: {        &quot;Service&quot;: &quot;ec2.amazonaws.com&quot;      }    },    {      &quot;Effect&quot;: &quot;Allow&quot;,      &quot;Action&quot;: &quot;sts:AssumeRole&quot;,      &quot;Resource&quot;: &quot;arn:aws:iam::123456789012:role/MyRole&quot;    }  ]}  To use Option B, create a new IAM role. Make note of the ARN of the newly created role.  Then, associate the newly created user with the IAM policy created in the last step.  Set the environment variable AWS_SECURE_PROXY_ROLE_ARN to the newly created role’s ARN.  Set AWS_KMS_REGION to the string representing AWS region where AWS KMS is configured.You can run the secureproxy using Docker run like below:docker run -it  -e MOESIF_MANAGEMENT_API_KEY=&quot;Your Moesif Management Key&quot;  -e MOESIF_APPLICATION_ID=&quot;Your moesif application Id&quot;  -e AWS_CUSTOMER_KEY_ID=&quot;Your customer managed key (CMK) in AWS KMS&quot;  -e AWS_SECURE_PROXY_ROLE_ARN=&quot;IAM role that secure proxy should assume to access AWS KMS&quot;  -e AWS_KMS_REGION=&quot;Your AWS KMS region such as &#39;us-west-2&#39;&quot;  -p 9500:9500 --name moesifproxy moesif/moesifproxyIn Option B, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not defined.Option C: Azure KeyVaultPlease make sure that service principal has the following permissions:  Key Vault Crypto User  Key Vault Reader  Only works for key vaults that use the Azure role-based access control permission model.  The Key algorithm should be RSA-256.          Key Type: RSA      RSA Key Size: 2048        No expiry time for key or atleast 2 years from the creation time.  Auto Rotation should be disabledImportant Notes: Please make sure Auto rotation policy is disabled and key is valid for more than 2 years.You can run the secureproxy using Docker run in two ways.Using Managed IdentityManage identity approach is preferred way if service is deployed in Azure Cloud.docker run -it  -e MOESIF_MANAGEMENT_API_KEY=&quot;Your Moesif Management Key&quot;  -e MOESIF_APPLICATION_ID=&quot;Your moesif application Id&quot;  -e KMS_PROVIDER=&quot;Azure&quot;  -e AZURE_VAULT_URL=&quot;The URL of your Azure Key Vault (e.g., https://your-vault-name.vault.azure.net/)&quot;  -e AZURE_KEY_NAME=&quot;The name of the key in Azure Key Vault to be used for encryption/decryption&quot;  -p 9500:9500 --name moesifproxy moesif/moesifproxyUsing Environment VariablesSame as above but needs three extra environment variables:  AZURE_TENANT_ID    : The Azure Active Directory tenant (directory) ID  AZURE_CLIENT_ID    : The application (client) ID registered in Azure Active Directory  AZURE_CLIENT_SECRET: The client secret for the application registered in Azure ADdocker run -it  -e MOESIF_MANAGEMENT_API_KEY=&quot;Your Moesif Management Key&quot;  -e MOESIF_APPLICATION_ID=&quot;Your moesif application Id&quot;  -e KMS_PROVIDER=&quot;Azure&quot;  -e AZURE_VAULT_URL=&quot;The URL of your Azure Key Vault (e.g., https://your-vault-name.vault.azure.net/)&quot;  -e AZURE_KEY_NAME=&quot;The name of the key in Azure Key Vault to be used for encryption/decryption&quot;  -e AZURE_TENANT_ID=&quot;The Azure Active Directory tenant (directory) ID&quot;  -e AZURE_CLIENT_ID=&quot;The application (client) ID registered in Azure Active Directory &quot;  -e AZURE_CLIENT_SECRET=&quot;The client secret for the application registered in Azure AD&quot;   -p 9500:9500 --name moesifproxy moesif/moesifproxyRotate Azure Key Vault keysSecure Proxy version v1.4.4 and later supports migration from one Azure Key Vault key to another. This migration re-encrypts Moesif data encryption keys with the new Azure key while keeping your existing encrypted event data readable.Before rotating, start the moesif/moesifproxy:v1.4.4 container with your existing Azure Key Vault configuration:KMS_PROVIDER=AzureAZURE_VAULT_URL=https://&amp;lt;old-vault-name&amp;gt;.vault.azure.net/AZURE_KEY_NAME=&amp;lt;old-key-name&amp;gt;The Azure identity used by the proxy must have decrypt permission on the old key and encrypt permission on the new key. For migrations across Azure subscriptions or vault owners, run the migration with an Azure identity that can access both keys.Then call the /keystore/rotate endpoint with the new Azure Key Vault key:curl --request POST   --url http://&amp;lt;proxy-host&amp;gt;:9500/keystore/rotate   --header &#39;Content-Type: application/json&#39;   --data &#39;{    &quot;azure_vault_url&quot;: &quot;https://&amp;lt;new-vault-name&amp;gt;.vault.azure.net/&quot;,    &quot;azure_key_name&quot;: &quot;&amp;lt;new-key-name&amp;gt;&quot;  }&#39;After the endpoint returns success, restart the proxy with the new Azure Key Vault configuration:KMS_PROVIDER=AzureAZURE_VAULT_URL=https://&amp;lt;new-vault-name&amp;gt;.vault.azure.net/AZURE_KEY_NAME=&amp;lt;new-key-name&amp;gt;Verify that search results through the proxy return decrypted data before routing normal production traffic back through the updated proxy.5. Update your server integrationYou must update your server integrations to send data to the collector proxy located at http://localhost:9500/collector of your secure proxy (assuming it’s running at localhost:9500). This ensures data is properly encrypted before sending to Moesif.To do so, update the Base URI of your server integration to http://localhost:9500/collector.Refer to the options section of your respective server integration docs or reach out to support if you need help.An example for moesif-nodejs is below:const moesifMiddleware = moesif({  applicationId: process.env.MOESIF_APPLICATION_ID,  baseUri: &#39;http://localhost:9500/collector&#39;,});6. Let Moesif knowOnce both the secure proxy and your server integration is set up, email Moesif support with your the hostname for secure proxy.Moesif will make an update to your account to finalize installation.Accessing the Moesif Collector APITo send data to the Moesif collector API, you must use the proxy located at http://localhost:9500/collector. This ensures data is properly encrypted before sending to Moesif. Any previous references to https://api.moesif.net should be replaced with http://localhost:9500/collector.For example, to save users to Moesif, perform the following API call:curl -X POST http://localhost:9500/collector/v1/users  -H &#39;Content-Type: application/json&#39;  -H &#39;X-Moesif-Application-Id: YOUR_MOESIF_APPLICATION_ID&#39; -d &#39;{&quot;user_id&quot;:&quot;12345&quot;,&quot;company_id&quot;:&quot;67890&quot;,&quot;metadata&quot;:{&quot;email&quot;:&quot;john@acmeinc.com&quot;,&quot;first_name&quot;:&quot;John&quot;,&quot;last_name&quot;:&quot;Doe&quot;,&quot;title&quot;:&quot;Software Engineer&quot;}}&#39;Accessing the Moesif Management APITo access your data using the management API, you must use the proxy located at http://localhost:9500/api. Any previous references to https://api.moesif.com/v1 should be replaced with http://localhost:9500/api. This ensures data is properly decrypted before consumption by any integrations you have.Do not include the /v1 path segment when accessing management API. The secure proxy adds this automatically.For example to query using the events endpoint, replace https://api.moesif.com/v1/search/~/search/events with http://localhost:9500/api/search/~/search/events like bellow:curl -X POST -H &#39;Authorization: Bearer YOUR_MANAGEMENT_API_KEY&#39; -H &#39;Content-Type: application/json&#39; -d &#39;{&quot;size&quot;:50,&quot;sort&quot;:[{&quot;request.time&quot;:{&quot;order&quot;:&quot;desc&quot;,&quot;unmapped_type&quot;:&quot;string&quot;}}]}&#39; -i &#39;http://localhost:9500/api/search/~/search/events?from=-7d&amp;amp;to=now&amp;amp;time_zone=America%2FLos_Angeles&amp;amp;week_starts_on=5&#39;Scaling Moesif proxyFor light load, you may be fine with a single Docker container running. If you expect a high volume of data collected or want to ensure high availability, you can run a pool of Secure Proxy instances behind a load balancer such as NGINX or HaProxy. Because secure proxy doesn’t maintain any persistent state, scaling Secure Proxy is simplified.Different Secure Proxy setupsEach application in Moesif can be configured with a different secure proxy hostname. This can be helpful if you want different encryption keys for different environments.For example, you might want different encryption keys for your staging and your production environments. In this case, you would run two different Secure Proxy setups, one for each application.Configuration optionsMOESIF_APPLICATION_IDRequired Your Moesif Collector Application Id which can be found by logging into Moesif and going to API Keys from the top-right menu.MOESIF_MANAGEMENT_API_KEYRequired Your Moesif Management API key. You can generate a new one by logging into Moesif and going to API Keys from the top-right menu.Ensure your API key is generated with at least the following scopes:  create:events  read:events  create:encrypted_keys  read:encrypted_keys  read:workspaces  update:workspaces  read:virtual_eventtypes  update:virtual_eventtypesIf you’re using additional functionality from the Moesif Management API, you may need additional scopes.ENABLE_DEBUG_LOGSSet to true to print debug logs. This is helpful to debug internal issues with secure proxy.AWS optionsThe below options are used to configure AWS KMS.AWS_CUSTOMER_KEY_IDAWS_CUSTOMER_KEY_ID is the Customer managed key (CMK) in AWS KMS, To find KeyId follow the instructions hereAWS_KMS_REGIONAWS_KMS_REGION is a string representing aws region where AWS KMS is configured. Defaults to ‘us-west-2’AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEYThese are access keys needed to access AWS KMS via API. More information about access keys here. Make sure that IAM user/role associated with the access keys has permissions to access AWS KMS.AWS_SECURE_PROXY_ROLE_ARNThis is the ROLE ARN that secure proxy should assume to access AWS KMSAzure KeyVault optionsThe below options are used to configure Azure Key Vault.KMS_PROVIDERKMS_PROVIDER should be set to ‘Azure’ to use Azure Key Vault as the Key Management Service provider.AZURE_TENANT_IDAZURE_TENANT_ID is the Azure Active Directory tenant (directory) ID. This is a unique identifier for your Azure AD instance. You can find this in the Azure portal under Azure Active Directory &amp;gt; PropertiesAZURE_CLIENT_IDAZURE_CLIENT_ID is the application (client) ID registered in Azure Active Directory. This is used to authenticate your application with Azure. You can create a new application registration in Azure AD to get this IDAZURE_CLIENT_SECRETAZURE_CLIENT_SECRET is the client secret for the application registered in Azure AD. This acts as the application’s password for authentication. You can generate a new client secret in your application’s settings in Azure ADAZURE_VAULT_URLAZURE_VAULT_URL is the full URL of your Azure Key Vault instance (e.g., “https://your-vault-name.vault.azure.net/”). This is where your encryption keys are storedAZURE_KEY_NAMEAZURE_KEY_NAME is the specific name of the key within your Azure Key Vault that you want to use for encryption and decryption operationsEncryption optionsThese options below control what data is encrypted. This can be useful if you require numeric math or date math. See Limitations of client-side encryption.MOESIF_ENCRYPTION_ENABLEDSet to false to disable client-side encryption. This can be useful if you don’t need client-side encryption features but would like to leverage this service as a buffer.MOESIF_ENCRYPT_NUMERICSSet to false if numbers does not contain sensitive data and don’t require encryption. This enables numeric math in Moesif.MOESIF_ENCRYPT_DATESSet to false if dates (RFC 3339 formatted strings) does not contain sensitive data and don’t require encryption. This enables date math in Moesif.MOESIF_ENCRYPT_REQUEST_HEADERSSet to false if request headers does not contain sensitive data and don’t require encryption.MOESIF_ENCRYPT_RESPONSE_HEADERSSet to false if response headers does not contain sensitive data and don’t require encryption.MOESIF_ENCRYPT_METADATASet to false if event metadata does not contain sensitive data and don’t require encryption.MOESIF_ENCRYPT_REQUEST_HEADERS_BLACKLISTSet to a comma separated string of blacklist of fields that will bypass request headers encryption. For example, if MOESIF_ENCRYPT_REQUEST_HEADERS_BLACKLIST=Host is set, then Moesif will skip encrypting the host request header. Please note that this configuration option is case insensitive.MOESIF_ENCRYPT_RESPONSE_HEADERS_BLACKLISTSet to a comma separated string of blacklist of fields that will bypass request headers encryption. For example, if MOESIF_ENCRYPT_REQUEST_HEADERS_BLACKLIST=Last-Modified is set, then Moesif will skip encrypting the Last-Modified response header. Please note that this configuration option is case insensitive.MOESIF_ENCRYPT_REQUEST_BODY_BLACKLISTSet to a comma separated string of blacklist of fields that will bypass request body encryption. For example, if MOESIF_ENCRYPT_REQUEST_BODY_BLACKLIST=dev,digit,test is set, then Moesif will skip encrypting dev, digit and test at any level while creating an event. Please note that this configuration option is case insensitive.MOESIF_ENCRYPT_RESPONSE_BODY_BLACKLISTSet to a comma separated string of blacklist of fields that will bypass response body encryption. For example, if MOESIF_ENCRYPT_RESPONSE_BODY_BLACKLIST=uuid,message is set, then Moesif will skip encrypting uuid and message at any level while creating an event. Please note that this configuration option is case insensitive.MOESIF_ENCRYPT_METADATA_BLACKLISTSet to a comma separated string of blacklist of fields that will bypass metadata encryption. For example, if MOESIF_ENCRYPT_METADATA_BLACKLIST=datacenter,sf is set, then Moesif will skip encrypting datacenter and sf at any level while creating an event. Please note that this configuration option is case insensitive.MOESIF_ENCRYPT_GRAPHQL_QUERYSet to true if the GraphQL query string is sensitive and requires encryption (uncommon). Moesif will encrypt the GraphQL query in request body. When encrypted, GraphQL analytics will have limited functionality. Default to false, where Moesif will encrypt all the fields in the request body except query field.MOESIF_ENCRYPTION_ROTATION_MONTHSSet to an integer as the duration in calendar months for encryption key rotation. Default = 12, e.g. 12 months for annual key rotation happening on 01-01 00:00 UTC each year.  Customers who require a specific key rotation interval can set MOESIF_ENCRYPTION_ROTATION_MONTHS to the schedule of calendar months at which they would like their encryption keys to change.  Key rotation always happens on the first of a calendar month.  Moesif recommends the default value of 12.How to buildMoesif Proxy uses the revel webframework. To learn more about revel https://revel.github.io/To build Docker imagedocker build -t moesif/moesifproxy:latestTo push to Docker repodocker logindocker push moesif/moesifproxy:latestTroubleshootingDebug logsIf you experience issues with secure proxy, restart your instance after setting the environment variable ENABLE_DEBUG_LOGS to true. This will print helpful debug logs which can be shared with Moesif support.Verify accessIf you experience errors related to AWS Credentials like NoCredentialProviders, it’s likely the secure proxy cannot access your keystore in AWS.  Check that you correctly injected the right role and that the associated policy has access AWS KMS. See create a role to access KMS.If you’re using AWS KMS access assuming an IAM role, also ensure the role is correctly attached to your EC2 VM or k8s pod and the role has permissions to assume a role.Limitations  If enabled for a pre-existing app, filtering and aggregations will not work on old data. We recommend creating a new app in Moesif for enabling secure proxy.  Numeric fields will behave like strings (i.e. no math supported) unless MOESIF_ENCRYPT_NUMERICS is set to false.  Date fields will behave like strings (i.e. no date math supported) unless MOESIF_ENCRYPT_DATES is set to false.  If using embedded templates (for customer-facing portal), the secure proxy must be accessible from the internet.  We recommend a subdomain like analytics.acmeinc.com that points to NGINX with SSL (See Docker example).  Alert rules with a group by will not have decrypted values in any notifications. A feature is on our roadmap for Q1 2024 to fix this.Unencrypted dataThere are certain parts of your API data that bypass client-side encryption for proper analytics, including:  Request and response time (latency)  Route and verb  Response status code  user_id and company_id  Binary and non-JSON payloads such as Protobuf or Thrift  The names of fields used within your APILike most web analytics tools, the secure proxy does not encrypt data from client integrations like moesif-browser-js as tracking custom actions like “Signed In” or “Viewed Page” typically do not typically contain sensitive data.Other use casesBesides client-side encryption and decryption, the secure proxy enables a variety of other use cases:  Reduce the number of outbound connections to Moesif’s APIs.  Relay requests from servers that don’t have direct access to the internet.  White label the Moesif Collector or Management API like analytics.acmeinc.com/api.",
      "url": " /platform/secure-proxy/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-graphql": {
      "title": "GraphQL support",
      "content"	 : "Moesif natively supports GraphQL APIsthroughout the entire platform.OverviewMoesif parses your GraphQL operations into its respective components.This allows you to filter and aggregate on any GraphQL query fields including GraphQL selectors and variables. This also enables you to create complex alerts in Moesif based on specific resources or responses even if for 200 OK HTTP status codes.The parsed GraphQL query fields are available in Request.Graphql Query.ExampleConsider the following set of criteria for a time series metrics plot for an API:  We want to plot the performance metrics of GraphQL mutation operations in a bar chart.  We want to plot this chart for each day for the past week.  We want to know the average latency and the maximum latency.  We want the chart show performance data for individual mutation operations.For this set of criteria, the filters, group definition, and metrics specification look like this:Notice that we’ve asked for a stacked bar chart.With these settings, Moesif plots this chart:We get a breakdown on the performances of each GraphQL mutation operations for each day.Comparing GraphQL Analytics vs REST AnalyticsMoesif can provide insight into how users access your GraphQL APIs compared to your REST APIs. This enables you to track how the usage differs if you’re migrating from REST to GraphQL.Consider the following two examples showcasing similar metrics for GraphQL and REST APIs:  The first example shows a breakdown of mutatation operations by definition name.  The REST equivalent shows a breakdown of non GET API transactions broken down byAPI routes.GraphQL segmentation chart breaking down GraphQL operations by definition nameSegmentation chart for a REST API breaking down API calls by API routesGraphQL over HTTPThere are four different ways to transport GraphQL over HTTPthat Moesif supports.      For the Content-Type set to application/graphql, Moesif treats the HTTP request body content as the GraphQL query string itself.     {   human(id: &quot;1000&quot;) {     name     height(unit: FOOT)   } }        Your have specified the GraphQL query string in the URL using ?query= when receiving a HTTP GET request.      A standard GraphQL POST request that uses  application/json as the Content-Type header includes a JSON-encoded request body of the following form:     {   &#39;query&#39;: &#39;...&#39;,   &#39;operationName&#39;: &#39;...&#39;,   &#39;variables&#39;: { &#39;myVariable&#39;: &#39;someValue&#39;, ... } }        Alternatively, you have specified the GraphQL query string in the ?query= query string when receiving an HTTP POST request.Filters and SegmentationIf Moesif detects a GraphQL request, you will find the parsed AST in Request.Graphql Query in the Filters pane.You can select any attribute in your GraphQL operation such as a specific queryfield name or argument value.Like REST APIs, you have the same set of metrics tools for GraphQL APIs. For more information, see Introduction to Event Analytics and Logging.",
      "url": " /platform/graphql/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-ethereum-web3": {
      "title": "Ethereum Web3 API support",
      "content"	 : "DApp IntroductionDecentralized Applications (or DApps) are applications that do not rely on a centralized backendrunning in AWS or Azure that power traditional web and mobile applications(outside of hosting the frontend code itself). Instead,the application interacts directly with a blockchain which can be thought of distributedcluster of nodes analogous to applications interacting directly with a “masterless”cluster of Cassandra nodes with full replication on every peer in anuntrusted peer-to-peer network.These blockchain nodes do not require a leader which would defeat the purpose ofbeing truly decentralized. Unlike leader election in various consensus protocols like Raft and Paxos,blockchain transactions are sent to and processed by “random” nodes via Proof of Work or Proof of Stake.These nodes are untrusted nodes running in an arbitrary sized network onvarious compute devices around the world.DApps are the frontend apps which interact with these blockchain over an API. For Ethereum, this API is a JSON-RPC layer called the Ethereum Web3 API which Moesif supports natively.An example implementation of Web3 would be Web3.js.Moesif Ethereum support overviewUsing a Moesif server integration, you can automatically capture Ethereum Web3 API calls so you can monitor your DApp for any errorsor performance issues when interacting with the blockchain. You can also upload your compiled contract ABI to Moesif which enables Moesif to map the unreadablehex values in the Web3 calls to the original contract function names and parameter names.This provides you with very powerful analytics on which smart contract functions are being called,how long they take, and who is making them.Moesif parses the Web3 API calls such as the below eth_sendTransaction and also links to other usefultools like Etherscan,so you can easily understand why transactions failed.Ethereum AnalyticsThe power of integrating Moesif is not just inspecting individual web3 calls, but to get a total understanding ofhow your DApp interacts with the Ethereum blockchain. For example, you can see which of your smart contract functions are called the most.Moesif captures transient context like the User Agent and timing of Web3 calls.How to integrate1. SDK integrationSince you cannot directly add monitoring agents to Ethereum nodes, you will be using one ofMoesif’s client side integrations. These SDKsautomatically track outgoing Web3 API calls from your DApp to the Ethereum network orAJAX calls to your backend.If your building a browser based DApp (i.e using Web3.js)follow the integration guide for moesif-browser-js SDKAn example Ethereum DApp with Moesif integrated is available here.2. Uploading ABIsWhile optional, moesif-eth-cli is a simple CLI that can upload the compiled smart contracts (ABIs).This ensures Moesif can decode the hex values into their original values making debugging far easier and readable. More info.Install the Moesif Ethereum command line tools:$ npm install -g moesif-eth-climoesif-eth -f ./build/contracts -t MOESIF_MANAGEMENT_API_TOKENFor help:$ moesif-eth --helpYou can integrate the moesif-eth-cli command line tools with your DApp build flow to automatically upload the ABI every time the smart contracts are compiled.ABI DecodingEvents (from transactionReceipts) and function calls to smart contracts are hex encodedwhen traveling over the Web3 protocol. This can make debugging very difficult.Moesif maintains a database of the function hex signatures (i.e. function selectors)for commonly used ABI functions from public smart contracts. If an Ethereum ABI function matches one found in our global database, Moesif will automatically use that templateto decode the hex values into human readable values.The decoded data will be available in the Ethereum tab:However, your specific DApp will most likely have custom functions which do not match a function signature in the public database.To get deep insights into private ABI functions, Moesif provides the ability to upload your compiled smart contracts.Uploaded smart contracts are scoped only to your specific org/app in Moesif. See ABI upload installationMoesif will attempt to use your private compiled contract first and only default to the global database if not found.Additional Filters based on ABIWith the ABIs uploaded and events decoded based on them, additional filters will become available, such as type of event (event vs function), the smart contract function name,or the input parameters. These fields are available in all analytics charts such as segmentation and time series.JSON-RPC EventsIn addition to Web3 API, Moesif will also detect the underlying JSON-RPC requests, so that relevant fields such as theRPC method name and respective parameters will be shown.    Filters and segmentationYou can filter and segment on any of the RPC parameters including the method name, the input parameters,error code, and more. This way, you can drill into the performance or error rate for a specificRPC method.Field NamesIf Moesif detects a JSON-RPC/Ethereum Web3 API, Moesif will parse your RPC call so that youcan filter and segment your API data on the RPC fields such as the RPC method or params.These field are under under the jsonrpc child object just like HTTP headers are under therequest.headers child object.            Field      Description                  jsonrpc.request.method      method name of the RPC call such as eth_getTransactionCount()              jsonrpc.request.params      list of params passed into the RPC call. Since Ethereum Web3 passes params as a ordered array, Moesif prepends the method name to add context to the array index. Meaning eth_getTransactionCount__1 and eth_getTransactionCount__2 would correspond to the first and second params for the eth_getTransactionCount method.              request.jsonrpc      version of the JSON-RPC protocol such as 2.0              response.jsonrpc      version of the JSON-RPC protocol such as 2.0              request.id      identifier established by the Web3 client              response.id      Should match the request id              response.error.code      The JSON-RPC error code such as -32601 (Method Not Found)      Review the Web3 JSON-RPC API Reference for the full list of possible Web3 methods and their params.Alerting on errorsMoesif will also support triaging and aggregating metrics on specific RPC method names soyou don’t just have a single bucket under the route POST /.",
      "url": " /platform/ethereum-web3/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-gdpr": {
      "title": "GDPR and CCPA Compliance",
      "content"	 : "Moesif was designed from the ground up with security and privacy in mind and is aligned with the policies and practices of General Data Protection Regulation (GDPR) and California Consumer Privacy Act (CCPA). Please contact your account manager or privacy@moesif.com for any questions.Moesif does not sell any contact data collected on behalf of our customers or market Moesif services to our customer’s end-users.Because Moesif already attributes API calls to individual user_id’s, Moesif makes managing GDPR subject access requests such  right to access and right to erasure a breeze for our customers.Right to ErasureMoesif supports the right to erasure for any user data previously stored in Moesif through a permanent deletion of that user data.Via UIIn the UI, you can delete user and company data by going to any user or company profile and click More Actions on the top right of the page followed by selecting Right to Erasure.Via APIIn the spirit of automation, this can be done easily with our DELETE /search/users/:id endpoint after obtaining a Management API token in Moesif.curl -X DELETE https://api.moesif.com/v1/search/{orgId}/users/{user_id}   -H &#39;Authorization: Bearer YOUR_MANAGEMENT_APITOKEN&#39;Right to AccessAny data logged in Moesif for a specific user and associated API calls made by the user can be obtained through our Management API or exported within the Moesif portal.Via UIIn the Moesif UI, you can get a users events by going to Live API Log, add a filter for particular user or company id, and select Export. You’ll be prompted for an email to send a link with the exported data.Via APIGet a user profile:curl -X POST https://api.moesif.com/v1/search/{orgId}/users/{user_id}   -H &#39;Authorization: Bearer YOUR_MANAGEMENT_APITOKEN&#39;Get a user’s API activity:curl -X POST https://api.moesif.com/v1/search/{orgId}/search/events?app_id={appId}&amp;amp;from=-52w&amp;amp;to=now   -d &#39;{&quot;query&quot;:{&quot;term&quot;:{&quot;user_id&quot;:&quot;{END USER ID}&quot;}}}&#39;  -H &#39;Authorization: Bearer YOUR_MANAGEMENT_APITOKEN&#39;Right to ObjectDeleting a user’s events from Moesif will remove historical data, but it will not prevent new data from being collected moving forward.Via UIFor enterprise customers, moesif supports Right to Object, with our one-click suppression feature.To stop collecting data for a user or company, go to Users or Companies, select the person’s profile, and click Edit Sample Rate. You will need to set to 0%.Via APIMoesif enterprise customers also has an API to programmatically change the sample rate for any user or company. Contact your account executive for documentation.For self serve plans, they do not have one-click suppression feature, but you can still implement your own logic that skips collection for certain users via the SDK’s skip hook.Data ScrubbingYou can also used the SDK’s maskcontent function to scrub specific fields with sensitive data such as health or financial related information before leaving your data center.options.maskContent = function(event) {  // Modify or remove any API call property that you don&#39;t want to be sent to Moesif.  event.request.headers[&#39;X-Tracking-Metadata&#39;] = undefined;  event.request.body.password = undefined;  return event;}To learn more about our user privacy features, please contact us at privacy@moesif.com.",
      "url": " /platform/gdpr/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-saml": {
      "title": "Single Sign-On: Generic SAML",
      "content"	 : "Moesif provides a single sign-on integration with SAML identity providers.In order to set up SSO:  You must be able to configure your identity provider  You must be on a Moesif enterprise planBenefits of SSO  Improve security and regulatory compliance  Reduce IT costs through auto-provision and de-provisioning  Enforce policies like Multi-Factor Authentication (MFA), Password Reset, etc  Improve usability for employeesHow SSO worksMoesif supports both identity-provider (IdP) initiated and service-provider (SP) initiated single sign-on.When IdP initiated, a user logs in through your IdP’s app directory. When SP initiated, a user logs in by entering their employee email on Moesif’s website. Because their email domain has SSO enabled, they will be redirected to your organization’s single sign-on page. Once enabled, team management and role-based access control (RBAC) is handled by your identity provider rather than within the Moesif application.Home Realm DiscoveryMoesif’s SSO implementation supports Home Realm Discovery. This means SSO is enforced for your entire company domain even if a new employee is not yet added to your Moesif organization. This ensures employees cannot bypass SSO such as by entering a username/password. It also reduces your IT burden as employees never have to decide on what type of login they should use as redirect is automatic as soon as they enter their email.Enterprise Single Sign-On is available only on enterprise plansHow create a SAML app using OktaThis guide shows how to set up a generic SAML app with a generic SAML identity provider.If Moesif already has an integration for your provider, we recommend leveraging that instead. If we don’t have a provider specific integration, we recommend OIDC over SAML.1. Go to Applications within the Okta admin dashboardClick the Add Application button2. In the applications directory, click Create New App3. In the popup select Web from the dropdown and then select SAML 2.04. Enter a name for the app and optionally upload a logoYou can download the Moesif logo here5. On the next step, enter your single sign on URL and Audience URIThe single sign on URL looks like https://auth.moesif.com/login/callback?connection=myorgnameThe Audience URI looks like urn:auth0:moesif:myorgnameYou can obtain your single sign on URL and Audience URI by emailing your Moesif technical account manageror support@moesif.comBesides filling in the Single sign on URL and Audience URI fields, you will need to map four fieldsunder Attribute Statements as specified below:            Name      Name Format      Value                  email      Unspecified      ${user.email}              given_name      Unspecified      ${user.firstName}              family_name      Unspecified      ${user.lastName}              role      Unspecified      appuser.role      All other fields can be left to their default values.6. On the next step, select I’m an Okta customer adding an internal app and select finish7. Finally, select View Setup Instructions in the yellow boxAfter clicking View Setup Instructions, you’ll see the Identity Provider Single Sign-On URL and your X.509 Certificatefor the newly created application. Email both of these items to your Moesif technical account manager who will finalize linking yourMoesif organization to your IdP application.8. Add role field (Optional)To manage role-based access control for Moesif within your identity provider, you can add a field role to the Moesif appuser.Within the Okta admin portal, go to Directory -&amp;gt; Profile Editor, and select the Edit Profile button next to the newly created Moesif application.Click on Add Attribute on the left side and add a field role as shown in below screenshot.Checkbox Define enumerated list of values and add the three predefined rolessupported by Moesif:  admin  member  read-only  dashboard-viewerIf your Moesif subscription has any custom roles, you can also add their names to this list.After SSO activatedOnce SSO is enabled:  Team members will no longer be able to log in with a password or social account.  Password reset is disabled.  Administrators will no longer be able to add/remove team members within Moesif.  Role-based access control is synced from your identity provider and cannot be changed within Moesif.Any employee logging in with your company’s domain will automatically be redirected to the single sign-on page where they can click log in. All team management and role-based access control actions is done through your identity provider. Moesif automatically syncs user accounts.Disabling SSOAn organization can disable SSO at any time by contacting their technical account manager. Once disabled, existing team members who already had an account prior to SSO can log in with their password. New users who were provisioned through SSO can reset their password to log in.",
      "url": " /platform/saml/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-adfs": {
      "title": "Single Sign-On: ADFS",
      "content"	 : "Moesif provides a single sign-on integration with Microsoft’s Active Directory Federation Services (ADFS).In order to set up SSO with ADFS:  You must be an ADFS administrator  You must be on a Moesif enterprise plan with SSO enabledBenefits of SSO  Improve security and regulatory compliance  Reduce IT costs through auto-provision and de-provisioning  Enforce policies like Multi-Factor Authentication (MFA), Password Reset, etc  Improve usability for employeesHow SSO worksMoesif supports both identity-provider (IdP) initiated and service-provider (SP) initiated single sign-on.When IdP initiated, a user logs in through your IdP’s app directory. When SP initiated, a user logs in by entering their employee email on Moesif’s website. Because their email domain has SSO enabled, they will be redirected to your organization’s single sign-on page. Once enabled, team management and role-based access control (RBAC) is handled by your identity provider rather than within the Moesif application.Home Realm DiscoveryMoesif’s SSO implementation supports Home Realm Discovery. This means SSO is enforced for your entire company domain even if a new employee is not yet added to your Moesif organization. This ensures employees cannot bypass SSO such as by entering a username/password. It also reduces your IT burden as employees never have to decide on what type of login they should use as redirect is automatic as soon as they enter their email.PoliciesOnce SSO is enabled:  Team members cannot log in with a username/password or social login (like GitHub).  Password reset is disabled.  Users can only be provisioned or de-provisioned by the IdP. You cannot modify team members within Moesif.  Role-based access control (RBAC) is synced from your identity provider and cannot be changed within Moesif.Enterprise Single Sign-On is available only on enterprise plansHow to setup ADFS with Moesif1. Adding relying party trustRun the following two commands in the Windows PowerShell window.(new-object Net.WebClient -property @{Encoding = [Text.Encoding]::UTF8}).DownloadString(&quot;https://raw.github.com/auth0/adfs-auth0/master/adfs.ps1&quot;) | iexAddRelyingParty &quot;urn:auth0:moesif&quot; &quot;https://auth.moesif.com/login/callback&quot;This script uses the ADFS PowerShell SnapIn to configure a Relying Party that will issue, for the authenticated user, the following claims: email, upn, given name, and surname.2. Configuring custom rolesYou can map Moesif’s custom role attributes to ADFS using a Claim issuance Policy.After your policy is set up, you can assign members to custom role groups using the Member of tab within the ADFS user properties window.  Review Microsoft’s guide Create a Rule to Send Claims Using a Custom Rule.  Within the AD FS console, select Relying Party Trusts from the left tree. On the right side, find the Moesif Trust just created.  Right-click it and click Edit Claim Issuance Policy in the dropdown.  Click Add Rule.  Set Claim rule template to Send Claims using a custom rule.  Click Next and give it a name like “Map groups to Moesif roles” c:[Type == &quot;http://temp/variable&quot;] =&amp;gt; issue(Type = &quot;https://www.moesif.com/saml/role&quot;, Value = c.Value)3. Provide Moesif your Federated metadataYour metadata for an ADFS federation typically located at https://&amp;lt;yourservername&amp;gt;/federationmetadata/2007-06/federationmetadata.xml.You will need to share your federated metadata URL with your account manager or Moesif support. Moesif will automatically poll the URL to look for changes (once a day) like a new signing certificate added to prepare for a rollover.Once enabledAny employee logging in with your company’s domain will automatically be redirected to the single sign-on page where they can click log in. All team management and role-based access control actions is done through your identity provider. Moesif automatically syncs user accounts.Disabling SSOAn organization can disable SSO at any time by contacting their technical account manager. Once disabled, existing team members who already had an account prior to SSO can log in with their password. New users who were provisioned through SSO can reset their password to log in.",
      "url": " /platform/adfs/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-microsoft-entra": {
      "title": "Single Sign-On: Microsoft Entra",
      "content"	 : "Moesif provides a single sign-on integration with Microsoft Entra.In order to set up SSO with Microsoft Entra:  You must be an Microsoft Entra administrator  You must be on a Moesif enterprise plan with SSO enabledBenefits of SSO  Improve security and regulatory compliance  Reduce IT costs through auto-provision and de-provisioning  Enforce policies like Multi-Factor Authentication (MFA), Password Reset, etc  Improve usability for employeesHow SSO worksMoesif supports both identity-provider (IdP) initiated and service-provider (SP) initiated single sign-on.When IdP initiated, a user logs in through your IdP’s app directory. When SP initiated, a user logs in by entering their employee email on Moesif’s website. Because their email domain has SSO enabled, they will be redirected to your organization’s single sign-on page. Once enabled, team management and role-based access control (RBAC) is handled by your identity provider rather than within the Moesif application.Home Realm DiscoveryMoesif’s SSO implementation supports Home Realm Discovery. This means SSO is enforced for your entire company domain even if a new employee is not yet added to your Moesif organization. This ensures employees cannot bypass SSO such as by entering a username/password. It also reduces your IT burden as employees never have to decide on what type of login they should use as redirect is automatic as soon as they enter their email.PoliciesOnce SSO is enabled:  Team members cannot log in with a username/password or social login (like GitHub).  Password reset is disabled.  Users can only be provisioned or de-provisioned by the IdP. You cannot modify team members within Moesif.  Role-based access control (RBAC) is synced from your identity provider and cannot be changed within Moesif.Enterprise Single Sign-On is available only on enterprise plans.How to setup Microsoft Entra with MoesifThis guide is for OIDC-based SSO which is recommended over SAML for newer installations.Step 1: Create a New Enterprise Application in Microsoft EntraLog in to Microsoft Entra:  Access your Microsoft Entra admin portal.  Navigate to Enterprise applications:  Go to Azure Active Directory &amp;gt; Enterprise applications.Create a New Enterprise Application:  Click on New application.  Click Create your own application  Enter a name for your application (e.g., “Moesif Integration”).  Ensure Integrate any other application you don&#39;t find in the gallery (Non-gallery) is selected      Click Create    Set the Platform to Web.  Set the Redirect URI to https://auth.moesif.com/login/callback.  Click Register.  Make note of the Application (client) ID. Moesif will need this later.Step 2: Configure Linked App RegistrationNavigate to App registrations:  Go to Azure Active Directory &amp;gt; App registrations.  Select All applications  Find the linked app registration for your newly created Enterprise application.Set Authentication Settings:  In the newly created application, navigate to Authentication.  Select Add a platform and select Web.  Set the Redirect URI to https://auth.moesif.com/login/callback and click Configure  UnderImplicit grant and hybrid flows, ensure ID tokens (used for implicit and hybrid flows) is checked.  Click Save.Step 3: Create App roles  In the newly created app registration, navigate to the App roles panel.  Click “Create App role”  For Allowed Member Types, select Both (Users/Groups + Applications)  Set the value to admin. You can give it a friendly name and description.Repeat creating additional roles for all values below:  admin  member  read-only  dashboard-viewerIf your Moesif subscription has any custom roles, you can also add their names to this list.Step 4: Configure Certificates &amp;amp; SecretsCertificates &amp;amp; Secrets:  Navigate to Certificates &amp;amp; secrets.  Click New client secret.  Add a description (e.g., “Moesif Secret”).  Set an expiration period.  Click Add.  Copy the Value of the client secret. Make note for the Moesif team. You will need this later.Step 5: Share with MoesifSend an email to your customer success representative or to support@moesif.com with the following information:  Your Application (client) ID  Your Entra domain  Your Client SecretStep 6: Test the IntegrationTest Authentication:  Navigate to your Moesif application.  Attempt to log in using Microsoft Entra credentials.  Ensure that the authentication flow completes successfully and that you are redirected back to Moesif.Enable SCIM Provisioning (Optional)If you want users to be deleted and updated automatically, you can also configure SCIM.  Within the enterprise application, select Provisioning from the left  Under Provisioning Mode, select Automatic.  Open the panel Admin Credentials, and enter the SCIM Endpoint URL and token provided by Moesif  Open the panel Mappings and select `  Ensure Provisioning Status is set to On  Select Users and groups from left side and select Provision Microsoft Entra ID Users  Find the custom attribute externalId and select Edit. Change source attribute to objectid and precedence to 3. Click Ok.  Find the custom attribute emails[type eq &quot;work&quot;].value and select Edit. Change Match objects using this attribute to Yes and set matching precedence to 2. Click Ok.  It should look like below:  Lastly, ensure Provisioning Status is set to On.Once enabledAny employee logging in with your company’s domain will automatically be redirected to the single sign-on page where they can click log in. All team management and role-based access control actions is done through your identity provider. Moesif automatically syncs user accounts.Disabling SSOAn organization can disable SSO at any time by contacting their technical account manager. Once disabled, existing team members who already had an account prior to SSO can log in with their password. New users who were provisioned through SSO can reset their password to log in.",
      "url": " /platform/microsoft-entra/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-okta": {
      "title": "Single Sign-On: Okta (OIDC)",
      "content"	 : "Benefits of SSO  Improve security and regulatory compliance  Reduce IT costs through auto-provision and de-provisioning  Enforce policies like Multi-Factor Authentication (MFA), Password Reset, etc  Improve usability for employeesHow SSO worksMoesif supports both identity-provider (IdP) initiated and service-provider (SP) initiated single sign-on.When IdP initiated, a user logs in through your IdP’s app directory. When SP initiated, a user logs in by entering their employee email on Moesif’s website. Because their email domain has SSO enabled, they will be redirected to your organization’s single sign-on page. Once enabled, team management and role-based access control (RBAC) is handled by your identity provider rather than within the Moesif application.Home Realm DiscoveryMoesif’s SSO implementation supports Home Realm Discovery. This means Moesif will redirect the log in page to a special page as soon as Moesif recognizes thee team members email. This takes the guess work of remembering special URLs to log in via SSO. SSO is then enforced for your entire company domain even if a new employee is not yet added to your Moesif organization. If you prefer having a special breakglass account that bypasses this, let us know and we can set one up for you.Installation OptionsFor Okta, Moesif provides both an Okta OIDC Connector along with a SAML-based integration. Unless there is strong reason to use SAML, we strongly recommended new installations use the Okta OIDC Connector. This provides a streamlined installation and much better at provisioning deprovisioning team members.If you prefer the traditional SAML approach, view this guide.How to setup Okta with MoesifPrerequisitesIn order to set up SSO with Okta:  You must be able to configure your Okta account  You must be on a Moesif enterprise plan1. Create a “Moesif Application”  Go to Applications, and create a new OIDC Application as shown below:  Ensure “Web Application/server-side application” is selected which will provide both a client id and a secret for Moesif (Moesif only stores these server-side and never in browser code)  Give the application a name such as Moesif API Analytics  Configure the application like below  The text values from the screenshot are also provided for easier copy/paste:            Setting      Value                  Sign-in redirect URIs      https://auth.moesif.com/login/callback              Login initiated by      Either Okta or App              Login flow      Redirect to app to initiate login (OIDC Compliant)              Initiate login URI      https://www.moesif.com/wrap?allowed_identity_providers[0]={identityNameFromMoesif}              Immediate app access with Federation Broker Mode      Disabled        Moesif will provide the unique slug for identityNameFromMoesif. Typically, this is your company domain, but with . replaced with -.  For example, if your domain is acmeinc.com, you’ll use ?allowed_identity_providers[0]=acmeinc-com2. Create Moesif Role attribute for OIDC app profile  Go to Profile Editor → Click on the OIDC Profile View  Click Add Attribute  Add an attribute with the name moesifrole like below  You will need to add an enum type for at least these three roles:          admin      member      read-only      dashboard-viewer        If you have defined custom roles in Moesif, you will need to add those as well.If you prefer a different attribute name, let us know and we can update our mapping for your orgYou confirm any custom roles by going to Apps &amp;amp; Team within Moesif or check with your customer success rep.3. Create a Group for Each Moesif Role  To reduce the burden of managing the permissions of every employee, it’s recommended to create groups which already are associated with the required Moesif role.  Create a new group in Okta such as moesif-admin  Then, after the group is created, associate the group with the newly created Moesif application  You should also select the appropriate Moesif role we defined earlier for the group. This will cause anyone part of this group to also have the Moesif role you defined.4. Test the IdP-Initiated Flow  At this point, the application should be fully configured.  Add yourself to one of the groups so you have access to the Moesif app.  Then, within your Okta app launcher, try accessing the Moesif application.5. Let Moesif Know  With the IdP-Initiated flow working, Moesif can enable SP-initiated flow  Moesif cannot enable a single user to test SP-initiated flows          This should only be enabled once IdP-initiated flow is working. Once enabled, any users with your chosen email domains that are under your control will be redirected to a special login form where the team member will be prompted to log in via your IdP        With SP-initiated enabled, you should test two flows:          You’re already logged into your IdP. In this case, you’ll simply be prompted to click “Continue” to log into the Moesif application      You’re not yet logged into your IdP. In this case, you’ll be redirected to your IdP’s login screen which will then redirect you back to Moesif.      After SSO activated  If a user’s role changes, they need to log out of Moesif to have access to new role.  Regardless of log out, Moesif sessions expire after one hour which will force a refresh  Team members will no longer be able to log in with a password or social account.  Password reset is disabled.  Administrators will no longer be able to add/remove team members within Moesif.  Role-based access control is synced from your identity provider and cannot be changed within Moesif.If your Moesif subscription has any custom roles, you can also add their names to this list.After SSO activatedOnce SSO is enabled:  Team members will no longer be able to log in with a password or social account.  Password reset and MFA controls are disabled.  Administrators will no longer be able to add/remove team members within Moesif.  Role-based access control is synced from your identity provider and cannot be changed within Moesif.  User licenses are added as new users are provisioned. Contact us to change this behavior.What is experience like:  Team members can log in via their IdP or from Moesif’s website.  If team member logs in from the website, they will automatically be redirected to a special log in page.Any employee logging in with your company’s domain will automatically be redirected to the single sign-on page where they can click log in. All team management and role-based access control actions is done through your identity provider. Moesif automatically syncs user accounts.Disabling SSOAn organization can disable SSO at any time by contacting their technical account manager. Once disabled, existing team members who already had an account prior to SSO can log in with their password. New users who were provisioned through SSO can reset their password to log in.",
      "url": " /platform/okta/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-okta-saml": {
      "title": "Single Sign-On: Okta (SAML)",
      "content"	 : "Moesif provides a single sign-on integration with Okta.Benefits of SSO  Improve security and regulatory compliance  Reduce IT costs through auto-provision and de-provisioning  Enforce policies like Multi-Factor Authentication (MFA), Password Reset, etc  Improve usability for employeesHow SSO worksMoesif supports both identity-provider (IdP) initiated and service-provider (SP) initiated single sign-on.When IdP initiated, a user logs in through your IdP’s app directory. When SP initiated, a user logs in by entering their employee email on Moesif’s website. Because their email domain has SSO enabled, they will be redirected to your organization’s single sign-on page. Once enabled, team management and role-based access control (RBAC) is handled by your identity provider rather than within the Moesif application.Home Realm DiscoveryMoesif’s SSO implementation supports Home Realm Discovery. This means SSO is enforced for your entire company domain even if a new employee is not yet added to your Moesif organization. This ensures employees cannot bypass SSO such as by entering a username/password. It also reduces your IT burden as employees never have to decide on what type of login they should use as redirect is automatic as soon as they enter their email.Enterprise Single Sign-On is available only on enterprise plansHow to setup Okta with MoesifPrerequisitesIn order to set up SSO with Okta:  You must be able to configure your Okta account  You must be on a Moesif enterprise plan  Okta also has a guide available hereThis guide is for SAML-based SSO. However, we recommend OIDC for ease of use for newer installations.1. Go to Applications within the Okta admin dashboardClick the Add Application button2. Search for Moesif and click Add3. Select the Sign On tab and then select the Edit buttonIn the red box marked above box, enter your Moesif Okta company domain, which is your Okta domain with any . replaced with -For example if you log into Okta at myorgname.okta.com, you should enter myorgname-okta-cominto the corresponding field.If you’re unsure, email your Moesif technical account manager or support@moesif.com4. Select View Setup Instructions in the yellow box.This will open up Okta’s set up instructions.Under step 2 Save, then attach the following Metadata file to your request, copy the the metadata URL.Email the URL to your Moesif account manager who will finish setting up SSO.https://myorgname.okta.com/app/XXXXXXXXXXX/sso/saml/metadata5. Add role fieldWhile optional, to manage role-based access control for Moesif within your identity provider, you need to add a field role to the Moesif appuser.Within the Okta admin portal, go to Directory -&amp;gt; Profile Editor, and select the Edit Profile button next to the newly created Moesif application.Click on Add Attribute on the left side and add a field role as shown in below screenshot.Checkbox Define enumerated list of values and add the three predefined rolessupported by Moesif:  admin  member  read-only  dashboard-viewerIf your Moesif subscription has any custom roles, you can also add their names to this list.After SSO activatedOnce SSO is enabled:  Team members will no longer be able to log in with a password or social account.  Password reset and MFA controls are disabled.  Administrators will no longer be able to add/remove team members within Moesif.  Role-based access control is synced from your identity provider and cannot be changed within Moesif.  User licenses are added as new users are provisioned. Contact us to change this behavior.What is experience like:  Team members can log in via their IdP or from Moesif’s website.  If team member logs in from the website, they will automatically be redirected to a special log in page.Any employee logging in with your company’s domain will automatically be redirected to the single sign-on page where they can click log in. All team management and role-based access control actions is done through your identity provider. Moesif automatically syncs user accounts.Disabling SSOAn organization can disable SSO at any time by contacting their technical account manager. Once disabled, existing team members who already had an account prior to SSO can log in with their password. New users who were provisioned through SSO can reset their password to log in.",
      "url": " /platform/okta-saml/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-multi-factor-authentication": {
      "title": "MFA and Profile",
      "content"	 : "Setting Up Multi-Factor AuthenticationMulti-Factor authentication (MFA) allows you to secure your Moesif account against unauthorized access by promting for a second verification method beyond your password. MFA adds a layer of protection helping to ensure sensitive customer data is protected.To set up MFA, Go to Settings -&amp;gt; My Account and scroll down to MFA Section  Click on Enroll to start.  Use your Authenticator App to Scan the QR code.  Enter the 6 digit numeric code from your Authenticator App to finish your enrollment.Moesif only supports Authenticator Apps like Authy, Google Authenticator, or any other app that support TOTP algorithms. Because SMS is considered insecure for MFA, Moesif does not support SMS-based MFA.After enrolling, you can remove or add more devices by load up the QR code and scan it again.Managing Multi-Factor AuthenticationSingle-sign OnIf you have enterprise SSO configured for your Moesif org, Moesif will disable prompting for MFA code as your identity provider will handle this flow.Lost DeviceIf you lost access to your verification, contact us to recovery your account.Personal DetailsIf you signed up via email and password, you can update the basic personal details on my accounts page. If you used a third party identify provider like Google or Enterprise SSO, your profile will be populated automatically within the My Account page.",
      "url": " /platform/multi-factor-authentication/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-organizations-and-team": {
      "title": "Apps and Team",
      "content"	 : "OrganizationsAn organization represents your company’s subscription with Moesif and is created when you signed up. Team members and applications are associated with your organization.Self-serve plans typically have just a single organization. However, enterprise plans can create complex organizational structures such as to manage quotas for different departments and business units. Contact us for info on this.ApplicationsAn application represents a single environment in Moesif which allows you to keep data isolated and organized.All applications within your organization share the same plan quotas so you don’t need to purchase multiple plans.You should create separate Moesif applications for different environments like “Staging” and “Production” to keep data isolated and organized. You can also clone dashboard configuration between applications, which makes setup easier.Your events, users, companies, dashboards, and automation rules are scoped to a single application. This means user id 1234 in one application may refer to different customer than user id 1234 in another application.You can edit the below settings under Apps and Team.There is a soft limit of 10 apps which is sufficient for most customers. Please contact us if you need this limit raised or need to understand how to best organize your data.NameThe friendly name for your application such as Development APITime ZoneIf set, all reports and times will use this time zone for all team members. By default, charts are rendered using the Browser’s local time which may not be ideal forcompanies with global teams. Setting a global time zone ensures all team members are looking at the same metrics.Weeks Starts OnIf set, all weekly intervals will start on this day for all team members. By default, weeks start on Monday which may not be aligned with yourinternal reporting. Similar to setting a global time zone, this enables all team members to use the same day for the start of weeks.Changing time zone or week starts on will not update previously saved workspaces and tags. However, you can copy or re-save any existing workspaces to ensure they are updated with your latest settings.Team membersYou can invite multiple team members to your Moesif organization as specified by your current plan.To add team members, go to Apps and Team under the bottom left menu in the Moesif portal.it’s recommended to also set up Multi-Factor Authentication within Moesif or your enforce it within your identity provider for best security posture.Role-based access controlMoesif supports role-based access control to maintain internal security and compliance.All plans have three built-in roles, Admin, Member, and Read-only.Enterprise plans can create additional roles via Custom Roles.            Role      Description              admin      The admin role can add/delete team members, modify subscription, access security audit logs in addition to all permissions by member role.              member      The member role has access to most features in Moesif and is recommended for majority of team members.              read-only      The read-only role can view data, but cannot create anything. They cannot create share links or export data.              dashboard-viewer      A limited access role that can only view dashboards, but not create new dashboards.      Custom RolesIf you have an Enterprise plan, you can create custom roles based on Moesif’s API scopes. This enables you to have fine-grained permission control based on team and responsibility.  For example, you can create a support role that can only view API logs, but not dashboards  Or create a a dashboard-editor role that can only view and edit dashboards, but not automation settings.Newly created custom roles may take a few minutes to be propagated. If you immediately assign a user to a new role, they may experience permission errors.To do so, select Edit Roles and then select New Custom Role.This will bring up the scopes picker.You can add or remove scopes based on your security requirements. View API scopes for a full description of each permission.At the top, we recommend selecting an existing role at the top to use as a starting point and then modify as needed.Application-Level PermissionsYou can restrict user access to specific applications within your organization.User Access LevelsAn Organization has these two types of access states:  Global access  Application-level accessGlobal Access (Default)New users invited to the organization and all admins have global access in the organization and they can access all existing applications. These users automatically gain access to any new applications.Application-Level Access (Restricted)Users who have been explicitly removed from at least one application in an organization have this restricted access. These users can only access the specific applications specified in their permissions. Contrary to global access, these users do not automatically gain access to new applications; an Admin must explicitly grant them access to any new apps.Managing Access  Select your account icon to bring up the settings menu bar.  Select Apps and Team.  Select Edit 🖉 in the app to which you want to restrict or grant access to.  Remove the user from the application or select a user to grant them access to the application.Only users with the system default admin role can manage application access. Users with Custom Roles, even those with full permissions, cannot modify app assignments.Important Considerations  When you carry out a permission changes, like granting access to a new App, you must log out and log back in for the changes to take effect.  Only users with global access, including admins, can create new applications. Users with application-level (restricted) access cannot create new apps.  If you delete an application, Moesif automatically removes it from the permission lists of all users who had access to it.Privacy RulesRoles can also be associated with a set of privacy rules. This enables you to redact or limit access to sensitive fields based on the team member’s role. To learn more, view Docs on Privacy Rules.Restricting Identity ProvidersMoesif offers a method to restrict logins to your organization to one of the three social identity providers that Moesif supports:  Google  Microsoft  GithubThis can be helpful if you want to prevent account sharing and leverage security features like Multi-Factor Authentication (2FA). For example, you can restrict logins to Google if your company is already using Google Workplace. This feature is available for any paying customers.While this feature can improve your security posture, it’s not intended to be a replacement for Enterprise Single Sign-On which provides much greater control for strict compliance needs. Enterprise customers can leverage Moesif Single Sign-On which supports Active Directory, Okta, or any SAML compatible identity providers.In order to access this feature, click on Edit Identity Providers as seen below.You can then specify the identity provider that you wish to restrict access from.",
      "url": " /platform/organizations-and-team/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-privacy-rules": {
      "title": "Privacy Rules",
      "content"	 : "Privacy rules enables you to redact or limit access to sensitive fields based on the team member’s role.This mechanism is integrated with Moesif’s Role-based access control and Custom Roles feature.The Privacy Rules feature is available only on enterprise plans. Reach out to our sales team for help.How Privacy Rules Works  Depending on the team member’s role, Moesif will redact a field or groups of fields  Privacy Rules are scoped to a Moesif application. This enables you to restrict access to a sensitive application like “Production”, but allow team members to see all fields in a “Development” applications.  Privacy Rules supports wildcards. This enables you to redact entire object trees such as request.body.payment_info.*Create a Privacy RuleFirst, follow these instructions to create a custom role. You’ll want to give your role a friendly name like Support Agent or Dashboard Editor.Once the role is created, go to Privacy Rules from the settings menu.From there, select the + Add New button.This will open a popup where you can add the fields you would like to redact.  Dropdown enables you to pick an existing field in your application.  Text enables you to enter a field name and leverage wildcards.Select the role(s) that this privacy rule should be applied to. You can select multiple roles.Click the Save button.Newly created privacy rules may take up to 10 minutes for changes to be propagated. Team members may still have access to fields until their session is refreshed.",
      "url": " /platform/privacy-rules/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-support-access": {
      "title": "Support Access",
      "content"	 : "To request support, email support@moesif.com or use the in-app chat. From there, a Moesif representative will be in contact to assist you with your request. If needed, approved Moesif support representatives can access your Moesif account with your permission to assist you such as to help setup your account or to troubleshoot an issue. To protect your data from unauthorized access, Moesif has a policy to verify your identity before performing sensitive operations.Support Process  The fastest way to request support is by emailing support@moesif.com from an authorized user on your Moesif subscription. If you send from a different email or use in-app chat, support will request you to verify your identity by replying from your authorized email.  The Moesif representative will further verify your identity by requesting your org identifier which can be found by navigating to the “Apps and Team” settings.Payment Security  Moesif will never ask you to share credit card or payment details through email or in-app chat. Only use the temporary magic link provided by a support agent.  Moesif will never ask for personal details like social security or drivers license through email or phone.What can support view  With your permission, a subset of support representatives can open a limited view of your data using ephemeral credentials limited to 12 hours.  Access is verified using MFA and Moesif’s identity management solution, Okta Auth0  All activity is logged and audited with the user id and time. You can also view this activity by going to the Audit Logs area within your Moesif account.Moesif is unable to assist you with your data when you are using Moesif’s client-side encryption feature. In this case, a screen share is best way to gain support. If you lose your encryption keys, Moesif is unable to access or recover your data.Administrating your account  If you require administrative changes to your account, the support representative must request a privileged admin to do so. These are limited to select members of our senior leadership team.  The support request must come from an authorized admin on your subscription. If you are not an admin, support will require further verification from an admin from your account.",
      "url": " /platform/support-access/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "platform-my-subscription": {
      "title": "My Subscription",
      "content"	 : "Moesif plans have both a committed monthly quota and pay-as-you-go for any events above your quota.This gives you options depending on your requirements. You can either leverage the discounts by committing to a larger plan, or youcan maintain flexibility by simply pay-as-you-go.Committed use discountsYour plan defines your commitment level (i.e. a minimum monthly event quota), which enables you to get steep discounts relative to pay-as-you-go.For both Growth and Enterprise plans, the per-unit pricing decreases as you upgrade tiers which makes it easy to scale to billions of events without high cost.For example, if you commit to 5 million events, your per-unit cost is $1.42 per 10k events.Once you upgrade to the 15 million plan, your per unit cost drops to $1.38 per 10k events.As you upgrade to very high volumes, this drops down to pennies per 10k.Pay-as-you-goThere is no requirement to commit to a large plan upfront. Events above your monthly quota are simply pay-as-you-go.This provides you flexibility if your usage varies each month without fear of being locked into long term commitments.The pay-as-you-go rate is defined by your subscription tier, which decreases as you upgrade your plan.If you’re unsure of your projected volume, it’s recommended to start on a smaller plan as anything above is pay-as-you-go.When you’re ready to commit to a larger plan, you can upgrade at any time.Your monthly events resets on your monthly billing day which can be found within My Subscription.Upgrades and DowngradesYou can upgrade your tier at anytime. This makes it easy to start on a small plan and upgrade your plan as you start consistently going over your quota.The upgrade is prorated through your existing billing cycle. For example, if you are 6 months into a 12-month subscription term, then 50% of your previous payment would be refunded and applied to the upgrade. Your subscription renewal date does not change.Downgrades are applied at the next renewal. Moesif is unable to downgrade before renewal. The cost savings you enjoy from committed use discounts is due to Moesif’s abilityto also commit to a minimum spend with our cloud vendors like AWS and Azure. These vendor contracts are locked in for 1 year or 3 year terms and unable to be downgraded.Billing and Usage NotificationWithin “My Subscription”, you can define usage alerts so you know when you are close to or exceeding your included monthly quota. This can be done by clicking the “+ Billing Notification” button.You can add a subscription owner or other member to take action such as upgrading the plan or adjust sampling rules to ensure you stay within your expected quota. Ensure you add team@moesif.com to your address book.",
      "url": " /platform/my-subscription/",
      "author": "Derric",
      "categories": "Platform"
    }
    ,
  

    "extensions": {
      "title": "Extensions and Plugins",
      "content"	 : "Moesif has extensions for many of the 3rd party services you may be using.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Send Auth0 Logs to Moesif Extension                                                                                                                                                                                                  Moesif’s Desk.com Plugin                                                                                                                                                                                                  Moesif’s Freshdesk Plugin                                                                                                                                                                                                  Moesif’s HubSpot Extension                                                                                                                                                                                                  Moesif’s Marketo Extension                                                                                                                                                                                                  Moesif’s PagerDuty Integration                                                                                                                                                                                                  Moesif’s Pendo Integration                                                                                                                                                                                                  Moesif’s Salesforce Extension                                                                                                                                                                                                  Moesif’s Slack Integration                                                                                                                                                                                                  Moesif’s Zapier Plugin                                                                                                                                                                                                  Moesif’s Zendesk Plugin                                                                                                                          Check out the Moesif extension gallery to see of all the extensions available.Most extensions are available on all plans. However, certain premium extensions such as Salesforce and data warehouses are available on enterprise plans only which includes a dedicated account manager to help you setting them up.If there is an extension missing, email us",
      "url": " /extensions/",
      "author": "Derric",
      "categories": ""
    }
    ,
  

    "extensions-auth0": {
      "title": "Send Auth0 Logs to Moesif Extension",
      "content"	 : "Deploy this integration to ship Auth0 events from your Auth0 account to Moesif using custom log stream via webhooks.Prerequisites  An Auth0 account and tenant. Sign up for free.  A Moesif account. Sign up for free.Set up MoesifTo configure the integration with Moesif:  Create a Moesif Account if you haven’t done so.  Obtain your MOESIF APPLICATION ID through onboarding steps or under Settings &amp;gt; Installation.Setup &amp;amp; Deploy Webhook ServiceCopy the folder log-streams-webhook from github repo https://github.com/Moesif/auth0-logs-to-moesif to your local drive. To verify if your can run the webhook.$ npm install # If running yourselfadded XX packages from XX contributors in XX.XXs$ npm start # If running yourselfListening on port 3050# Replace the Authorization header below with MOESIF_APPLICATION_ID$ curl   --header &quot;Authorization: MOESIF_APPLICATION_ID&quot;   --header &quot;Content-Type: application/json&quot;   --request POST   --data &#39;[{&quot;data&quot;: {&quot;type&quot;: &quot;f&quot;, &quot;description&quot;: &quot;Test failure&quot;, &quot;log_id&quot;: &quot;abc1234567890&quot;, &quot;user_id&quot;: &quot;testuser&quot; }}]&#39;   http://localhost:3050/logsAbove should verify you are able to run the webhook, and see the event in your Moesif account.Deploy the webhook to a cloud service of your choice, and obtain the host domain.Add the Auth0 Custom Webhook Stream  In your Auth0 Dashboard, navigate to Monitoring &amp;gt; Streams, and select Create Stream.  From the New Event Stream listing, select Custom Webhook.  Enter a Name, and select Create.  Locate the Payload URL field, and enter https://[host domain]/logs.  For Authorization Token: use your MOESIF_APPLICATION_ID.  Locate the Content Type field, and select “application/json”.  Locate the Content Format field, and select “JSON Array”.  Save the changes and create the stream by selecting Save.Trouble ShootIn Auth0 check your data:  Check the Dashboard Logs &amp;gt; Search screen to make sure the record is there.  Check Health tab for stream and delivery attemped.In Moesif check your data:  Go to your Moesif Account  Click on Start New -&amp;gt; Event Stream and verify the Auth0 event arrives.Check for errors in your deployed webhook:  Set DEBUG = true in to see console.log to verify          If your webhook service is receiving events from Auth0.      If there is error transforming and sending events to Moesif.      ",
      "url": " /extensions/auth0/",
      "author": "Derric",
      "categories": "Extensions"
    }
    ,
  

    "extensions-desk": {
      "title": "Moesif&apos;s Desk.com Plugin",
      "content"	 : "A quick overview of Moesif’s Desk.complugin and setup guide to automatically import error traces, device context, and customer events into Desk.com ticketsBenefits of using Moesif and Desk.com      Moesif is an API Analytics and monitoring service for platform teams with support for REST, GraphQL, and more.        Ensure your customers succeed by having a quick turnaround time rather than being stalled by incomplete log data. With Moesif’s hosted service, you have visibility to customers’ API history, error traces, and deep root cause analysis.        With the Desk.com integration, Moesif sends detailed context like the error trace experienced by the customer, version info, and device info into your Desk.com tickets.        View the error immediately in the customer’s ticket in the Desk.com agent panel without resorting to manual log search.  How to setup Moesif with Desk.comThis setup guide is specific to the Moesif Desk.com integration. For general Moesif info, view product features.      Log into your Moesif.com account get YOUR_PLUGIN_TOKEN.You’ll find your Desk.com plugin token from Moesif Dashboard -&amp;gt; Bottom Left Menu -&amp;gt; Extensions Setup        On Desk.com Dash, go to Admin &amp;gt; Cases &amp;gt; Integration URLs and then Add New.  In Edit Integration URL form, enter the following (replacing YOUR_TOKEN with the one from Moesif):            Field      Value                  Open Location      Canvas iFrame              URL      https://www.moesif.com/plugin/desk?email={{customer.email | uri_encode}}&amp;amp;externalId={{customer.uid | uri_encode}}&amp;amp;token=YOUR_PLUGIN_TOKEN      ",
      "url": " /extensions/desk/",
      "author": "Derric",
      "categories": "Extensions"
    }
    ,
  

    "extensions-freshdesk": {
      "title": "Moesif&apos;s Freshdesk Plugin",
      "content"	 : "A quick overview of Moesif’s Freshdesk pluginand setup guide to automatically see HTTP error traces and application API history in FreshDesk tickets.Resolve technical issues faster with Moesif and Freshdesk:      Moesif is an API Analytics and monitoring service for platform teams with support for REST, GraphQL, and more.        The integration imports user profile data such as browser, device info, SDK version, and geographic location directly into Freshdesk tickets to avoid long emails threads with customers to get debug info.        View HTTP request history and any errors right in Freshdesk tickets for that end-user so you don’t have to waste time searching application logs manually.        Have instant access to Moesif’s API insights in Freshdesk tickets.  How to setup Moesif with FreshdeskThis setup guide is specific to the Moesif Freshdesk integration. For general Moesif info, view product features.      Log into your Moesif.com account get your Freshdesk plugin token.You’ll find your Freshdesk plugin token from Moesif Dashboard -&amp;gt; Bottom Left Menu-&amp;gt; Extensions Setup        Go to the Moesif integrationon Freshdesk’s App Marketplace and click install.        Paste the integration token from Plugin Setup into the Freshdesk plugin field.  ",
      "url": " /extensions/freshdesk/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-hubspot": {
      "title": "Moesif&apos;s HubSpot Extension",
      "content"	 : "The Moesif HubSpot connector syncs customer API usage metrics in Moesif to your HubSpot records. This enables you to trigger HubSpot marketing emails and workflows that are hyper-personalized such as when a customer makes their first API call or exceeds their plan limits.Examples of some workflows you can create using this extension:  Email new users emails when they successfully integrated (or nudge them if they haven’t sent any API calls)  Warn customers when they are close to or have exceeded their plan’s quota  Notify all customers who were using a down or broken APIHow It WorksAny field that is part of a user or company profile in Moesif can be synced to a HubSpot contact property. This sync occurs regularly and may take up to 15 minutes for an update to be reflected in HubSpot.Authorizing Moesif with HubSpotLog into your Moesif account and select Extensions from the bottom left menu. Within the extensions gallery, find the HubSpot extension (which is under the Sales &amp;amp; Marketing category) and click the orange Install button.A modal will appear, click the orange Connect To HubSpot button to authenticate Moesif with your HubSpot account.Mapping your HubSpot propertiesMapping Moesif to HubSpotOnce your account is connected, click the Load Fields. This will populate all the properties found in your HubSpot account. Add each field you would like to sync to HubSpot. The field must be of the same type. (i.e. a string in Moesif must be a textfield in HubSpot). Any fields not added will not be synced.Users  A user in Moesif corresponds to a contact in HubSpot  Users are synced to contacts via email  Users without email field set will not syncCompanies  A company in Moesif corresponds to a company in HubSpot  Companies are synced to HubSpot companies via the Moesif company_domain      Companies in Moesif without company_domain set will not sync      Because HubSpot does not support dates with a time component, we recommend syncing Moesif date fields to text fields in HubSpot.Besides user and company fields, this extension can also sync behavioral cohorts which is a dynamic list of users that match specific behavior in Moesif. An example would be Users who are exceeding their rate limits or Users with multiple 400 errors in last 24 hrs.If you haven’t created your HubSpot properties yet, create them within your HubSpot account. Once done, you can refresh the properties by clicking Load Fields again.Tips  We recommend creating a HubSpot Property Group such as “Moesif” or “API Analytics” which can help better organize them.  Null values are skipped. This means if a field is “cleared” in Moesif, it will not clear the corresponding field in HubSpot.  It’s better to created dedicated fields set by each tool like Moesif vs fields that can be set by many sources.",
      "url": " /extensions/hubspot/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-marketo": {
      "title": "Moesif&apos;s Marketo Extension",
      "content"	 : "The Moesif Marketo extension enables you sync your Moesif data to Marketo. This enables you to trigger Marketo marketing campaigns that are hyper-personalized such as when a customer makes their first API call. For example, you can leverage Smart List and Smart Campaign filters to trigger different drip campaigns based on whether the customer integrated, and how much volume.OverviewAny field that is part of a user or company profile in Moesif can be synced to a Marketo lead property. This sync occurs regularly and may take up to 15 minutes for an update to be reflected in Marketo.How Moesif data is mapped to Marketo  A user in Moesif maps to a lead in Marketo.  A company in Moesif maps to a company in Marketo.  A Behavioral Cohort in Moesif maps to a Group List in Marketo.  Cohort Membership in Moesif is logged as an activity in Marketo.How it worksThis integration syncs behavioral cohorts created in Moesif to Marketo as a Group List.Once you create the behavioral cohort in Moesif, Moesif dynamically sends that list of users to Marketo, and keeps it up to date as users enter and exit the behavioral cohort criteria. This makes it easy to trigger behaviorally-driven email campaigns in Marketo without any custom code.Marketo’s API requires an email in order to update leads correctly. This means that users in Moesif must have an email associated with their profile. Moesif users without an email field will not be synced to Marketo. View docs on user profiles to see how to add and populate the email field for a user in Moesif.Creating the Roles and Users for the integrationStep #1 - Create the Role in MarketoOnce you’ve logged into Marketo, you will select the Admin function from the My Marketo dropdown menu at the top of the screen.From the Admin screen, select Users &amp;amp; Roles option.From the Users &amp;amp; Roles screen, navigate to the Roles tab and select New Role.In the modal that appears, Add in details for Role Name, Description, and select API Access in the Permissions display. After these details are input, click Create.You will now see the role added to your available roles in Marketo.Step #2 - Create an API Only User in MoesifWhile on the Users &amp;amp; Roles screen, select the Users tab and select Invite New User.In the modal that appears, you’ll fill out the fields for Email, First Name, and Last Name. Once filled in, click Next.On the next screen, you will assign the role that you created in the previous step. You’ll also check off the checkbox for API Only, then click Next.Lastly, you’ll click Send on the final screen.For an API Only user, no welcome email needs to be sent. For a regular user, this screen will be populated with a welcome message template. For Moesif, an API Only user is required.You should now see your created user displayed in the list of available users.Enabling the extensionStep #1 - Add your Marketo credentialsLog into your Moesif account and select Extensions from the account menu in the bottom left of the screen.Within the extensions gallery, find the Marketo extension, under the Sales &amp;amp; Marketing category, and click the orange Install button.Once the Install button is clicked, you will then see a modal appear.In the popup, click the orange Add Partner Key. You will need to enter the following information from your Marketo account:  client_id  client_secret  url_identity  url_restThe credentials for the client_id and client_secret can be found by going to LaunchPoint in Marketo (accessed through the side menu). You can then get the credentials for the service we created in earlier steps by clicking on View Details at the end of the service entry in the list.The client ID and Secret will then be shown.The credentials for the url_identity and url_rest can be found by going to Web Services in Marketo (accessed through the side menu). The field values are then displayed under the REST API heading.After plugging these details into Moesif, you can click Submit.Once clicked, if successful you will see “Partner Connected” displayed in green underneath the Edit Partner Key button. You will then click the Load Marketo Fields button to load the fields from Marketo.Step 2. Map your Marketo propertiesOnce your account is connected, click the Load Marketo Fields. This will discover all the properties found in your Marketo account. Add each field you would like Moesif to sync to Marketo. The field must be of the same type. (i.e. a string in Moesif must be a string in Marketo). If you do not select a field, it will not be synced.If you haven’t created your Marketo properties yet, create them within your Marketo account. Once done, you can refresh the properties by clicking Load Fields again.Create a behavioral cohortCreate a behavioral cohort in Moesif with your API usage criteria. As customers in Moesif match your criteria, they will be added to the behavioral cohort which will be synced to Marketo.The behavioral cohorts will then be available in Marketo for you to use. These are accessible through Group Lists &amp;gt; Moesif Cohort Lists. From here you will see your imported cohorts.The Moesif to Marketo sync tales takes about 5 minutes. If you do not see your cohort in Marketo, wait a few minutes.The Group Lists are accessible by going to the Database menu option at the top of the screen in Marketo.As Moesif users (Marketo Leads) match your behavioral cohort criteria, they will be dynamically added to your Group List in Marketo.Create a CampaignUse the generated Group List as a trigger to generate a new email campaign. Moesif will continuously enroll or disenroll leads from the list based on your behavioral cohort criteria.For questions, reach out to your dedicated account manager or email support.Limitations  Marketo does not support two leads having the same email address whereas two Moesif users can have the same email as the user_id is used for deduplication. Only one lead wil be synced to Marketo.  A Marketo List does not support + which is sometimes used by gmail users such as john+1@example.com and john+2@example.com. Those leads will skip being synced. You can develop a separate process to clean these emails.  Users without emails will not be synced to Marketo  Sync may take at least 5 minutes before changes are reflected in Marketo",
      "url": " /extensions/marketo/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-pagerduty": {
      "title": "Moesif&apos;s PagerDuty Integration",
      "content"	 : "PagerDuty + Moesif Integration Benefits  Notify on-call responders about API functional and performance issues that are affecting customers  Utilize PagerDuty’s routing and escalation rules in sync with Moesif alertsHow it WorksAlerts that are invoked in Moesif will be routed to PagerDuty to take advantage of the routing and escalation rules you have configured. Each alert that is sent to PagerDuty creates a new PagerDuty issue with the relevant details from the alert. Once the issue is created in PagerDuty, it must be manually resolved as Moesif does not resolve it automatically.RequirementsPagerDuty integrations require an Global Admin base role for account authorization. If you do not have this role, please reach out to an Admin or Account Owner within your organization to configure the integration.SupportIf you need help with this integration, please contact [support@moesif.com].Integration WalkthroughIn PagerDutyIn order for the PagerDuty and Moesif integration to work, you should have at least 1 service created. No configuration outside of this is needed in PagerDuty, simply follow the In Moesif instructions below to complete the integration.In Moesif  Log into your Moesif account.  Go to Alert Rules in the left-side menu to bring up the alert rules and channels.  Click on + Channel in the top right of the screen and select the channel type to PagerDuty.  Click on Connect with PagerDuty button. You will be redirected to PagerDuty’s website to authorize the Moesif application.After authorization, you can optionally click on the Trigger button to send a test alert.      Choose the services that you would like Moesif alerts to post issues to and click Connect.        After creating the PagerDuty channel, You will have the option to select your newly created PagerDuty Channel when creating or updating an alert configuration in Moesif.  Optional Step: Verify Your Integration by Sending a Test Alert  Open up the channel details by click on the edit button.  Click on send test alert.How to UninstallTo uninstall the Moesif integration, simply delete the Channel using PagerDuty in Moesif. In PagerDuty, navigate to to the Services page and select the service(s) that you have integrated with Moesif. Click on Integrations, click on the settings button on the Moesif entry. Once in the Moesif integration page, click Delete Integration to delete the PagerDuty and Moesif integration from PagerDuty.",
      "url": " /extensions/pagerduty/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-pendo": {
      "title": "Moesif&apos;s Pendo Integration",
      "content"	 : "Moesif’s Pendo extension enables you to send API calls and custom actions to Pendo. This enables you to drive Pendo’s in-app guidance and tooltips from your events in Moesif. The integration will combine the best of both tools and enable data-driven product teams with more ways to analyze and communicate with their developers based on usage data rather than gut feeling.Some of the benefits of Moesif and Pendo:  Guide new customers on integrating with your APIs with a hyper-personalized onboarding.  Create in-app notifications to inform customers when they hit rate limits, using deprecated APIs, etc.“The integration between Moesif and Pendo gives API-driven businesses the best of both platforms”, said Chad Burnette, Pendo’s Head of Platform. “This is a problem I have spent countless engineering resources working to solve in the past. Now the market has an easy and scalable way to instrument APIs and then use that data to message developers directly to ease onboarding and drive greater adoption. This is perfect as you build your developer community.”For more info on the Moesif Pendo partnership, read the announcement.How it worksAPI calls are sent to Pendo as a tracked event.The Pendo event name will contain {request.verb} {request.uri} for API Calls and the {action_name} for custom actions.The Pendo event context will be populated with the applicable fields ip, userAgent, nme, and url.For Pendo event properties, Pendo supports only 20 different property names and 200 different property values. Because of this, Moesif will not send headers, or query params as these objects are typically much larger than 20 fields. Instead, the integration will send the following properties to Pendo:  durationMs  direction  eventType  requestRoute  requestVerb  requestApiVersion  responseStatusIf you’re looking to trigger Pendo workflows using complex behaviors or from high-dimensional data, we instead recommend creating a behavioral cohort which can trigger a webhook. Your custom webhook handler can relay the event to Pendo as a tracked event.How to install1. Get your Pendo integration keyWithin the Pendo UI, get your secret for tracking events.Do not use your integration key. This is used to pull data from Pendo such as into Slack or other tools.To get your tracking secret, navigate to Settings and choose Subscription Settings. From there, choose your app from Applications tab. Under Track Event Shared Secret click Show link and use that key as Secret Key on Moesif’s Pendo Integration page.2. Add your Pendo integration key to MoesifWithin the Moesif UI, go to Extensions from the top-right menu. Then search for Pendo and click install as shown in the blue box below.Once done, Moesif will start sending data to Pendo.It takes up to 15 minutes after adding or modifying your API key before it’s reflected. If you don’t see events yet, wait 15 minutes.To get started with Moesif and Pendo, reach out to your dedicated account manager or email support.",
      "url": " /extensions/pendo/",
      "author": "Derric",
      "categories": "Extensions"
    }
    ,
  

    "extensions-salesforce": {
      "title": "Moesif&apos;s Salesforce Extension",
      "content"	 : "Moesif’s Salesforce integration enables you to have visibility into a customer’s API usage right in Salesforce. Track which pilots get successfully integrated with your platform and prioritize outreach for expansion and retention goals.Some of the benefits of tracking API usage data in SalesForce  Ensure pilots had a successful implementation and are growing in usage.  Reach out to customers that are close to or exceeding their plan quota.  Set up workflows to nudge customers who didn’t integrate yet.How it worksAny field that is part of a user profile in Moesif can be synced to a SalesForce field. This sync occurs regularly and may take up to 30 minutes for an update to be reflected in SalesForce.Mapping Moesif to SalesForce  A user in Moesif corresponds to a contact in Salesforce.  A company in Moesif corresponds to an account in Salesforce.Moesif supports mapping any field to your Salesforce object including when customers first integrated with your platform, their first API call, and how much API usage have they used up.Besides user fields, this extension can also sync behavioral cohorts which is a dynamic list of users that match specific behavior in Moesif. An example would be Users who are exceeding their rate limits or Users with multiple 400 errors in last 24 hrs.Step 1 Install Moesif in SalesForceLog into your Moesif account and select Extensions from the bottom left menu. Within the extensions gallery, find the SalesForce extension (which is under the Sales &amp;amp; Marketing category) and click the orange Install button.Follow the installation link in the popup which will open a SalesForce web page like below.We recommend installing for all users, but you can also install for specific SalesForce user profiles. Proceed to install the Moesif connector in your SalesForce tenant.Step 2. Authorize Moesif with SalesForceAfter the Moesif connector is installed in your SalesForce account, go back to the installation popup in the Moesif portal and click the orange Connect To SalesForce button.Step 3. Map your SalesForce fieldsOnce your account is connected, click the Load Fields. This will populate all the fields found in your SalesForce account. Add each field you would like to sync to SalesForce. It’s highly recommended for fields to be of the same type (such as a string, a number, or a date).Any fields not added will not be synced.SalesForce’s API requires an External Id field to update the right contact SalesForce. This field should contain the same value you use for Moesif User Id.If you haven’t created your SalesForce fields yet, create them within your SalesForce account. Once done, you can refresh the fields by clicking Load Fields again.Tips  We recommend creating a SalesForce Field set such as “Moesif” or “API Analytics” which can help better organize them.  Null values are skipped. This means if a field is “cleared” in Moesif, it will not clear the corresponding field in SalesForce.  It’s better to created dedicated fields set by each tool like Moesif vs fields that can be set by many sources.For questions, reach out to your dedicated account manager or email support.",
      "url": " /extensions/salesforce/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-slack": {
      "title": "Moesif&apos;s Slack Integration",
      "content"	 : "Moesif’s alerting features enables you get notified on API functional and performance issues affecting your customers. You can also receive alerts on account health such as when a customer’s API usage drops or increases.With the Moesif Slack integration, Moesif alerts are sent to a specific channel of your choice to keep the team informed. You can monitor any chart in Moesif with the  + Alert button.How to setup Moesif with SlackThis setup guide is specific to the Moesif Slack plugin. For general Moesif info, view Moesif API monitoring) or see documentation on creating alerts.      Log into your Moesif account.        Go to Alerting from the top menu to bring up the alert rules and channels.        Click on + Channel on the left and switch the channel type to Slack.        Generate a new Slack Incoming WebHooks for your channel.        Enter your generated webhook URL in the Moesif pop up modal. Optionally, give the channel a friendly name such as the name of the Slack channel.  Each channel in Moesif represents one channel in Slack.  After creating the alert channel, go to any Event time series and select + Alert. You will have the option to select your newly created Slack Channel when creating the alert. Any filters applied on the left side are also applied to the alert rule.Additional instructions on Slack Webhooks can be found here",
      "url": " /extensions/slack/",
      "author": "Xing",
      "categories": "Extensions"
    }
    ,
  

    "extensions-zapier": {
      "title": "Moesif&apos;s Zapier Plugin",
      "content"	 : "Moesif is an API Analytics and monetization service for API productsZapier is a platform that connects multiple apps together such as marketing and sales tools.The Moesif Zapier plugin allows you to save Moesif user and company data to third party tools like your CRM and marketing automation tools, and more.Use casesThe plugin can bi-directionally sync user or company profiles in Moesif with other tools.For example, you can send a customer’s API usage data to your CRM to track who succssfully got activated with your platform or send personalized emails.You can also save business data from your CRM and other tools into Moesif as user profiles and company profiles. This enables you to segment your API usage data based on free vs. paying, look up API logs via email, and more.Supported stepsMoesif Zapier app supports two actions and two triggers.Zapier actions  Create/Update User  Find User  Create/Update Company  Find CompanyZapier triggers  New Users  New CompaniesHow to use      Accept the invite for Moesif on Zapier.        Add Moesif as a step and select Connect an Account.        You will need to paste in your Moesif Zapier plugin token. Your token can be found in the Moesif web portal by going to the Bottom Left Menu -&amp;gt; extensions -&amp;gt; Zapier.  Example zapsBelow are a few examples.Fetch user data from Moesif and send to a third party appThis Zap will trigger from a third party app such as a new contact added to your CRM, then lookup a user in Moesif by email as an intermediate step, and then save Moesif’s user data in a destination of your choice such as your CRM.      Accept the invite for Moesif on Zapier.        Click Make a Zap in Zapier and set up the trigger such as when a contact is added to your CRM.        Click the plus sign to add an intermediate step and search for Moesif.        Click Connect an Account and you will need to paste in your Moesif Zapier plugin token. Your token can be found in the Moesif web portal by going to the Bottom Left Menu -&amp;gt; extensions -&amp;gt; Zapier.        Under Choose Action Event, select Find User and then click Continue.        Fill in the Email field based on one of the previous Zapier steps.        Add a destination step and map the Moesif fields to your destination app.  Trigger from third party app and save user profile into MoesifThis Zap is triggered from an action in a third party app such as a new contact being added to your CRM and thenenriches a user profile in Moesif with that data.      Accept the invite for Moesif on Zapier.        Click Make a Zap in Zapier and search for the Zap source such as Salesforce.        Select the trigger event you want such as New Contact        Click the plus sign to add an intermediate step and search for Moesif.        Click Connect an Account and you will need to paste in your Moesif Zapier plugin token. Your token can be found in the Moesif web portal by going to the Bottom Left Menu -&amp;gt; extensions -&amp;gt; Zapier.        Under Choose Action Event, select Create/Update User and then click Continue.        Once your done, Moesif users will be updated when new contacts are created in Salesforce.  Trigger when users are created in Moesif and send to a third party appThis Zap is triggered when a new user is created in Moesif and then saves to a third party app such as a CRM or marketing automation tool.      Accept the invite for Moesif on Zapier.        Click Make a Zap in Zapier and search for Moesif        Click Connect an Account and you will need to paste in your Moesif Zapier plugin token. Your token can be found in the Moesif web portal by going to the Bottom Left Menu -&amp;gt; extensions -&amp;gt; Zapier.        Under Choose Trigger Event, select New User and then click Continue.        Click the plus sign to add an destination step and search for your third party app.        Add a destination step and map the Moesif source fields to your destination app.  ",
      "url": " /extensions/zapier/",
      "author": "Derric",
      "categories": "Extensions"
    }
    ,
  

    "extensions-zendesk": {
      "title": "Moesif&apos;s Zendesk Plugin",
      "content"	 : "A quick overview of Moesif’s Zendesk plugin and setup guide to automatically see user profile in Moesif and links to API history and API issues, etc.Resolve technical issues faster with Moesif and Zendesk:      Moesif is an API Analytics and monitoring service for platform teams with support for REST, GraphQL, and more.        The integration imports user profile data such as browser, device info, SDK version, and geographic location directly into Zendesk tickets to avoid long emails threads with customers to get debug info.        View HTTP request history and any errors right in Zendesk tickets for that end-user so you don’t have to waste time searching application logs manually.        Have instant access to Moesif’s API insights in Zendesk tickets.  How to setup Moesif with ZendeskThis setup guide is specific to the Moesif Zendesk integration. For general Moesif info, view product features.      Log into your Moesif.com account get your Zendesk plugin token.You’ll find your Zendesk plugin token from Moesif Dashboard -&amp;gt; Bottom Left Menu-&amp;gt; Extensions Setup        Go to the Moesif integration on Zendesk’s Marketplace and click install.        Paste the integration token from Plugin Setup into the Zendesk plugin field.  ",
      "url": " /extensions/zendesk/",
      "author": "Derric",
      "categories": "Extensions"
    }
    ,
  

    "troubleshooting": {
      "title": "Troubleshooting",
      "content"	 : "There are some generic troubleshooting steps that you may execute to investigate Moesif integration issues.These may be between your API gateway or framework and Moesif or between your customer data platform and Moesif. Accordingly, they are documented as server integration troubleshooting guide.",
      "url": " /troubleshooting/",
      "author": "Venkat",
      "categories": ""
    }
    ,
  

    "troubleshooting-server-troubleshooting-guide": {
      "title": "Server Troubleshooting Guide",
      "content"	 : "Server Troubleshooting GuideMoesif server integrations can usually be installed in 15 minutes or less. If you don’t see your data show up in Moesif after a minute, you can follow the below troubleshooting steps to diagnose common problems. If you contact Moesif support, please follow these steps when contacting Moesif support.1. Enable Debug OptionIf you’re using a Moesif server integration, you should first enable the integrations’s debug option.With the debug option enabled, the integration will log additional diagnostic info to your application’s standard output which can provide you visibility into what might be happening. Please share the log with Moesif Support so we can root cause any issue.To enable debug, review the integration options for your specific server integration.For example, to enable debug for moesif-nodejs, you would set the option to true:var options = {  applicationId: &#39;Your Moesif Application Id&#39;,  debug: true, // Enable debug mode};// 3. Initialize the middleware object with optionsvar moesifMiddleware = moesif(options);2. Send Test API TrafficSend some test traffic to your API to ensure it’s receiving requests. If the integration is working, your events should show up in metrics reports within a minute. Events may not show in User and Company reports for up to 10 minutes.3. Verify Moesif StartedAll SDKs and most gateway plugins require your server to restart. Try restart your respective server that has Moesif installed. If you have debug mode enabled, you should see Moesif logs. If you don’t see any logs containing the text moesif, it’s possible Moesif is not yet enabled. Check that Moesif is enabled. Also, try running your application locally to see if it’s a deployment issue.4. Verify Connectivity to Moesif Collector APIIf you’re seeing timeouts to Moesif in your logs or events are not showing up, your application may be unable to communicate to Moesif Collector API. Unless you are using Moesif secure proxy, your application must allow outgoing traffic to api.moesif.netCURL the API DirectlyFrom your container or virtual machine, execute the following curl command curl -XGET -v &quot;https://api.moesif.net/health/probe&quot; to ensure you receive a 200 OK response. If the connection times out, you may have an issue connecting to the Moesif such as due to local firewall settings (See below).Verify You Server Supports TLS 1.2 or HigherAll Moesif APIs require Transport Layer Security (TLS) 1.2 or higher to increase security posture. TLS 1.0 and 1.1 is disabled as these older versions are considered to be less secure compared to the newer versions. TLS v1.0 dates back to 1999.You can verify this by running openssl s_client -connect api.moesif.net:443 -tls1_2If there’s an error or if the connection fails, it may mean that the server does not support TLS 1.2 or higher, or there could be other issues such as network connectivity problems.Add Moesif to Outgoing FirewallsAdd a rule to your outgoing firewall and network security groups to allow traffic to the domain api.moesif.net. Moesif integrations always communicate using port 443 for SSL.Create an allow rule for the domain api.moesif.net is strongly recommended as Moesif IP addresses can change. If your firewall only supports allowing by IP address, add the two IPs 75.2.93.6 and 99.83.168.36 to your firewall allow list.5. Check Presence of Conflicting MiddlewareIf you’re using a Moesif server SDK and already have other monitoring middleware or exception handlers, it’s possible the two can conflict due to the way both instruments your application. Moesif validates our integrations with the latest version of common APM vendors like DataDog and New Relic. However, if you have a custom middleware or exception handler, Moesif may be conflicting with your custom code.First, try to find the conflicting middleware by removing each middleware one-by-one and restart your application. Once you identify the conflicting middleware, you can reorder it relative to the Moesif middleware in your request chain.If the conflicting middleware is a commercial product, let our support team know and the version of the conflicting middleware.6. Ensure Moesif Middleware is Called LastIf you are using a Moesif middleware style integration, you must ensure Moesif is initialized last in your “middleware stack”. The Moesif middleware should come after any authentication or authorization middleware you have. This ensures the Moesif middleware can read the identified user or identified company correctly. You should also ensure Moesif comes after any body parsers or decompression middleware you have.7. Ensure Your Moesif Subscription is ActiveFor security and compliance, Moesif will not collect events if the subscription is cancelled. If you’re on a free tier, Moesif will also stop collecting events once you exceed your free quota until it resets. You can verify this under Subscriptions within the Moesif UI.9. Ensure Transaction Id is DifferentIf you are ingesting raw events directly, check if you’re reusing the same transaction ids across different events. Different events should have a different transaction id so Moesif doesn’t deduplicate different events. This should be a 36 character UUID such as 123e4567-e89b-12d3-a456-42661417400010. Contact Moesif SupportIf you still experiencing integration or connectivity issues, please collect the below details and share them with Moesif Support via Email or Chat. Our team will further investigate the root cause.  Moesif server integration name and version  Programming language version  Web Framework or API gateway version  Operating System and/or cloud provider  A Sample request made against your API including headers and body  If you experienced an error, share the timestamp when it happened",
      "url": " /troubleshooting/server-troubleshooting-guide/",
      "author": "Venkat",
      "categories": "Integration, Troubleshooting"
    }
    
  
}
