Measures

When supporting Metered Plans, your integration needs to be able to return usage information so that users can be billed according to it.

Manifold fetches measures every hour by calling your integration's endpoint for each resource with metered features.

Always refer to the Provider API documentation for full API reference and definitions of advanced scenarios which Manifold supports.

Measures retrieval

The measures retrieval endpoint returns measures for a specified resource and period.

Measures are expected for each measurable feature of the resource's plan. Each measure is expressed as a JSON number value and must include the total usage for the entire period requested.

Manifold's billing period starts at the first of each month UTC and ends at the start of the next. The billing period is defined as [period_start, period_end) where period_start is inclusive, and period_end is exclusive.

Example Request

GET /v1/resources/2687m6q19x63bt5krx5jgvpaq8c4m/measures?period_start=2018-05-01T00%3A00%3A00.000Z&period_end=2018-06-01T00%3A00%3A00.000Z
X-Signature: L5sBInztA2FMUvDaiHlGze5Ocrd0P8-6oG7zWPDkK8UuxcNZ3PjT6IL-1N-7g-Vhonqy1sqxsi9CCKALzzTRAw RGMkX3O_z5jVrQhy9UteLydfEQaUD8WDurbEVZkWxHc fDdIKAxrdJoJQUbwnbRPBnsEjlvlMXsgIFKor-OgXGarZ_Y5yNm9G7nObQgKsWPBJxiHwPW4X5ihOELUfekcCg
Content-Type: application/json
Accept: application/json

Notice that both period_start and period_end query parameters are URI encoded. They will have to be decoded before being used.

Example Response

HTTP/1.1 200 OK
Content-Type: application/json
{
  "resource_id": req.params.id,
  "period_start": "2018-05-01T00:00:00.000Z",
  "period_end": "2018-06-01T00:00:00.000Z",
  "measures": {
    "storage": 30,
    "processing-time": 5
  }
}

Example Implementation (Node.js)

This code is taken directly from the Node.js Sample Provider.

server.get("/v1/resources/:id/measures", verifyMiddleware, function(req, res, next) {
  var resource = db.resources[req.params.id];
  if (!resource) {
    res.statusCode = 404;
    return res.json({ message: "no such resource" });
  }

  res.statusCode = 200;
  res.json({
    resource_id: req.params.id,
    period_start: req.query["period_start"],
    period_end: req.query["period_end"],
    measures: { "storage": 30, "processing-time": 5 } // 30 GB, used for 5 hours.
  });
});

Examples are also available in other programming languages:

We support more languages in our Authentication libraries and SDKs.

Testing

Using Grafton you can generate requests against your integration to validate your feature measurements.

Here is how you would run Grafton to generate the example Manifold request.

$ grafton test \
   --region='all::global' \
   --client-id=21jtaatqj8y5t0kctb2ejr6jev5w8 \
   --client-secret=3yTKSiJ6f5V5Bq-kWF0hmdrEUep3m3HKPTcPX7CdBZw \
   --plan-features='{"age":2,"hat_color":"red","ready":true}' \
   --plan=ursa-minor \
   --new-plan=ursa-major \
   --connector-port=3001 \
   --product=bear \
   --resource-measures "{\"storage\": 30, \"processing-time\": 5}" \
   http://localhost:8080

Here is the expected Grafton output:

Grafton output messures