# Write a metric once

`PUT /datasources/metrics/{name}` · Rivier · hosting

Write a metric once: what is counted (count, sum, average...), from which allowed table, with which conditions, by which dimensions and time column. A change makes a new draft; the approved version stays in use until a person approves the new one. The definition is tried over the whole table before it is kept.

- Scope: hosting:write
- Graphql: Mutation.hostingMetricDraft
- Sdk: hosting.metric.draft
- Cli: hosting metric draft

## Parameters

- `name` (path, required), string

## Request body

`application/json`

```json
{
  "type": "object",
  "properties": {
    "label": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "description": {
      "type": "string",
      "maxLength": 1000,
      "default": "",
      "description": "What the figure means, in words a reader of a report understands"
    },
    "sourceId": {
      "type": "string",
      "format": "uuid",
      "description": "The linked database"
    },
    "table": {
      "type": "string",
      "pattern": "^[a-z_][a-z0-9_]*\\.[a-z_][a-z0-9_]*$",
      "description": "schema.table on the source's allow-list"
    },
    "measure": {
      "type": "object",
      "properties": {
        "fn": {
          "type": "string",
          "enum": [
            "count",
            "count_distinct",
            "sum",
            "avg",
            "min",
            "max"
          ]
        },
        "column": {
          "type": "string",
          "pattern": "^[a-z_][a-z0-9_]{0,62}$"
        }
      },
      "required": [
        "fn"
      ],
      "additionalProperties": false
    },
    "where": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "column": {
            "type": "string",
            "pattern": "^[a-z_][a-z0-9_]{0,62}$"
          },
          "op": {
            "type": "string",
            "enum": [
              "eq",
              "ne",
              "lt",
              "lte",
              "gt",
              "gte"
            ],
            "default": "eq"
          },
          "value": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "number"
              }
            ]
          }
        },
        "required": [
          "column",
          "value"
        ],
        "additionalProperties": false
      },
      "maxItems": 8,
      "default": [],
      "description": "Conditions that are part of the definition, such as status = paid"
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[a-z_][a-z0-9_]{0,62}$"
      },
      "maxItems": 10,
      "default": [],
      "description": "Columns a reader may break the figure down by"
    },
    "timeColumn": {
      "type": "string",
      "pattern": "^[a-z_][a-z0-9_]{0,62}$",
      "description": "The date or time column a period applies to"
    },
    "unit": {
      "type": "string",
      "enum": [
        "count",
        "currency",
        "percent",
        "duration",
        "number"
      ],
      "default": "number"
    },
    "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$"
    }
  },
  "required": [
    "label",
    "sourceId",
    "table",
    "measure"
  ],
  "additionalProperties": false
}
```

## Responses

- `200`: Success
- `400`: The request was malformed
- `401`: No valid credential
- `403`: The credential lacks the scope, origin or address
- `429`: Over the key's rate limit; see Retry-After

## Example

```sh
curl -X PUT 'https://api.rivier.ai/datasources/metrics/{name}' \
  -H 'Authorization: Bearer $KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "label": "string",
  "sourceId": "string",
  "table": "string",
  "measure": {
    "fn": "count"
  }
}'
```
