{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Usage Metrics","description":"Developer documentation for the WHMCS API — the","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"usage-metrics","__idx":0},"children":["Usage Metrics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Compatibility: This functionality is available since v7.9"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Usage metrics give Services information about resource consumption and Products"," ","the ability to price those resources."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Please make sure to read the feature documentation for"," ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.whmcs.com/Usage_Billing"},"children":["Usage Billing"]}," so that you have the best"," ","understanding of how your module is expected to interact with WHMCS."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"metricprovider-function","__idx":1},"children":["MetricProvider Function"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The MetricProvider function is responsible for returning an object that implements"," ","\\WHMCS\\UsageBilling\\Contracts\\Metrics\\ProviderInterface."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This object provides a list of available metrics, all usage of the server, and"," ","usage by given tenant on that server."," ","Interface and class are documented in the WHMCS\\UsageBilling namespace at https://classdocs.whmcs.com/"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following illustrates how one might make a simple class that fulfills the interface"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"namespace WHMCS\\Module\\Server\\Mymodule;\n/**\n * The above namespace is automatically registered for autoloading classes within\n * a \"lib\" sub-directory relative to your module directory. So, place this class \n * in modules/servers/mymodule/lib/MyMtricsProvider.php. \n */\n\nuse WHMCS\\UsageBilling\\Contracts\\Metrics\\MetricInterface;\nuse WHMCS\\UsageBilling\\Contracts\\Metrics\\ProviderInterface;\nuse WHMCS\\UsageBilling\\Metrics\\Metric;\nuse WHMCS\\UsageBilling\\Metrics\\Units\\Accounts;\nuse WHMCS\\UsageBilling\\Metrics\\Usage;\n\nclass MyMetricsProvider implements ProviderInterface\n{\n    private $moduleParams = [];\n    public function __construct($moduleParams)\n    {\n        // A sample `$params` array may be defined as:\n        //\n        // ```\n        // array(\n        //     \"server\" => true\n        //     \"serverid\" => 1\n        //     \"serverip\" => \"11.111.4.444\"\n        //     \"serverhostname\" => \"my.testserver.tld\"\n        //     \"serverusername\" => \"root\"\n        //     \"serverpassword\" => \"\"\n        //     \"serveraccesshash\" => \"ZZZZ1111222333444555AAAA\"\n        //     \"serversecure\" => true\n        //     \"serverhttpprefix\" => \"https\"\n        //     \"serverport\" => \"77777\"\n        // )\n        // ```\n        $this->moduleParams = $moduleParams;\n    }\n\n    public function metrics()\n    {\n        return [\n            new Metric(\n                'emailaddr',\n                'Email Mailboxes',\n                MetricInterface::TYPE_SNAPSHOT,\n                new Accounts('Mailboxes')\n            ),\n        ];\n    }\n\n    public function usage()\n    {\n        $serverData = $this->apiCall('stats');\n        $usage = [];\n        foreach ($serverData as $data) {\n            $usage[$data['username']] = $this->wrapUserData($data);\n        }\n        \n        return $usage;\n    }\n    \n    public function tenantUsage($tenant)\n    {\n        $userData = $this->apiCall('user_stats');\n        \n        return $this->wrapUserData($userData);\n    }\n\n    private function wrapUserData($data)\n    {\n        $wrapped = [];\n        foreach ($this->metrics() as $metric) {\n            $key = $metric->systemName();\n            if ($data[$key]) {\n                $value = $data[$key];\n                $metric = $metric->withUsage(\n                    new Usage($value)\n                );\n            }\n            \n            $wrapped[] = $metric;\n        }\n        \n        return $wrapped;\n    }\n    \n    private function apiCall($action)\n    {\n        // make remote call with $moduleParams\n    }\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The MetricProvider function will be invoked in various contexts throughout WHMCS"," ","so it is important to utilize strategies in your class design that minimize"," ","communication with remote servers.  The usage() and tenantUsage() methods will"," ","only be invoked in the context of a service with a server.  However, the metrics()"," ","method will be invoked in contexts specifically about Products. This method"," ","must always return a valid list for all potential servers that use the module."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-metricprovider-function","__idx":2},"children":["Example MetricProvider Function ",{"$$mdtype":"Tag","name":"a","attributes":{"id":"example-function"},"children":[]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"use WHMCS\\Module\\Server\\MyModule\\MyMetricsProvider;\n\nfunction mymodule_MetricProvider($params) {\n\n    return new MyMetricProvider($params);\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"metrics","__idx":3},"children":["Metrics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The metric() method must return an array of \\WHMCS\\UsageBilling\\Contracts\\Metrics\\MetricInterface"," ","instances, as noted by the ProviderInterface.  You may use, or extend, \\WHMCS\\UsageBilling\\Metrics\\Metric"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"metric-type","__idx":4},"children":["Metric Type"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The metric type of your MetricInterface instance is a critical expression of"," ","if/when the remote system is resetting the usage data.  If the incorrect type is"," ","used the snapshot data stored within WHMCS may track usage incorrectly."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For metrics that are related to non-ephemeral entities, such as mailboxes, disk"," ","usage, or databases, your remote system is unlikely to reset this data.  These"," ","are a \"snapshot\" type (\\WHMCS\\UsageBilling\\Contracts\\Metrics\\MetricInterface::TYPE_SNAPSHOT)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For metrics that are related to usage that is an accumulative measure at the"," ","remote system, like bandwidth, it is likely that these will be reset of a"," ","specific frequency.  WHMCS support a \"time-based\" daily and a monthly frequency via \\WHMCS\\UsageBilling\\Contracts\\Metrics\\MetricInterface::TYPE_PERIOD_DAY"," ","and \\WHMCS\\UsageBilling\\Contracts\\Metrics\\MetricInterface::TYPE_PERIOD_MONTH. When data"," ","is collected by WHMCS, the value of these metrics will overwrite any previous"," ","data for the respective time period.  So for monthly items, WHMCS internals will"," ","manage one record for each calendar month; for daily, WHMCS will manage on"," ","record for each day of each month.  At the end of a service's billing term, any"," ","uninvoiced usage for those periods will be summed and calculations applied to"," ","that total."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"metric-units","__idx":5},"children":["Metric Units"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Several unit classes are readily available in the \\WHMCS\\UsageBilling\\Metrics\\Units"," ","namespace.  These include Bytes, MegaBytes, GigaBytes, Accounts, and Domains.  These"," ","extend one of the two base concrete classes, WholeNumber or FloatingPoint. You can use"," ","those directly or extend them with your own concrete definition if you have need"," ","for repeated use of a custom unit."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"usage","__idx":6},"children":["Usage"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Metrics should describe usage by providing an object that implements"," ","\\WHMCS\\UsageBilling\\Contracts\\Metrics\\UsageInterface."," ","You may use \\WHMCS\\UsageBilling\\Metrics\\Usage if you wish.  You will provide this"," ","usage detail via the usage() and tenantUsage() methods."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If usage values returned by your API are not in the units that you wish WHMCS to"," ","report has, you will need to manage any conversion."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The usage() method should return an array of tenants and a list of metrics with"," ","usage (in the form of an object instance that implements \\WHMCS\\UsageBilling\\Contracts\\Metrics\\UsageInterface)."," ","This method is use in a global context, such as by the cron when polling for all"," ","metric information."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The tenantUsage($tenant) should simply provide the list of MetricInterface objects"," ","that have been populated with UsageInterface objects.  This method"," ","is used in specific contexts of a service."]}]},"headings":[{"value":"Usage Metrics","id":"usage-metrics","depth":1},{"value":"MetricProvider Function","id":"metricprovider-function","depth":2},{"value":"Example MetricProvider Function","id":"example-metricprovider-function","depth":3},{"value":"Metrics","id":"metrics","depth":2},{"value":"Metric Type","id":"metric-type","depth":3},{"value":"Metric Units","id":"metric-units","depth":3},{"value":"Usage","id":"usage","depth":2}],"frontmatter":{"title":"Usage Metrics","seo":{"title":"Usage Metrics"}},"lastModified":"2026-08-03T17:00:42.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/provisioning-modules/usage-metrics","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}