---
title: "Add a rule for a customer or subscription metadata path"
description: "While the business's metadata_validation is on, every later write of that entity's metadata is checked against its rules."
canonical_url: "https://twominutebilling.com/help/developers/api-reference/metadata-rules/add-a-rule-for-a-customer-or-subscription-metada"
---
# Add a rule for a customer or subscription metadata path

> While the business's metadata_validation is on, every later write of that entity's metadata is checked against its rules.

<api-operation method="POST" path="/v1/businesses/{biz}/metadata_key_rules">
<template v-slot:docs="">

While the business's metadata_validation is on, every later write of that entity's `metadata` is checked against its rules. Stored records are not changed.

## Path parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        biz
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Business id (biz_…)
    </td>
  </tr>
</tbody>
</table>

## Headers

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        Idempotency-Key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Safely retry writes — repeats return the original response. If a write FAILED after it had already taken effect, that failure is what repeats: the key is spent, and a new attempt needs a new key.
    </td>
  </tr>
</tbody>
</table>

## Body

The request body is **required**.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        entity_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      The kind of record the rule applies to. One of <code>
        customer
      </code>
      
      , <code>
        subscription
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      A dot path into metadata: 1 to 5 levels, each 1 to 64 letters, digits, _ or -. Cannot change after create. A rule below another rule needs that rule to be an object. Every path is optional: a rule checks a value only when it is present and not null.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <strong>
        yes
      </strong>
    </td>
    
    <td>
      Checked as given; values are never converted. <code>
        object
      </code>
      
       asserts a JSON object, <code>
        array
      </code>
      
       a JSON array (items are checked only when item_type or item_enum_options is set). One of <code>
        string
      </code>
      
      , <code>
        number
      </code>
      
      , <code>
        boolean
      </code>
      
      , <code>
        date
      </code>
      
      , <code>
        email
      </code>
      
      , <code>
        enum
      </code>
      
      , <code>
        object
      </code>
      
      , <code>
        array
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enum_options
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Necessary when data_type is enum
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pattern
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Regular expression the whole value must match. Text types only.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max_length
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Text types only
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Number type only. The value must be a whole number.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Number type only. The lowest permitted value, inclusive.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Number type only. The highest permitted value, inclusive. Not less than min.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        item_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Array type only. The type each item must have. One of <code>
        string
      </code>
      
      , <code>
        number
      </code>
      
      , <code>
        boolean
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        item_enum_options
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Array type only. The values each item can have. Needs item_type string; on create, item_type defaults to string when this is set.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min_items
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Array type only. The fewest items, inclusive.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max_items
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Array type only. The most items, inclusive. Not less than min_items.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      A description of the rule.
    </td>
  </tr>
</tbody>
</table>

## Response

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        object
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The object type.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        id
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The metadata key rule's id (mkr_…).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        entity_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The kind of record the rule applies to. One of <code>
        customer
      </code>
      
      , <code>
        subscription
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The metadata key the rule applies to.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The type the key's value must have.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enum_options
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      The allowed values, for an <code>
        enum
      </code>
      
       key.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pattern
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      A regular expression the value must match.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max_length
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The longest allowed string.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      True if a number must be a whole number.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      The smallest allowed number.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      The largest allowed number.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        item_type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      The type of each item, for an array key. One of <code>
        string
      </code>
      
      , <code>
        number
      </code>
      
      , <code>
        boolean
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        item_enum_options
      </code>
    </td>
    
    <td>
      <code>
        array of string
      </code>
    </td>
    
    <td>
      The allowed values of each item, for an array key.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min_items
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The fewest items allowed, for an array key.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max_items
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      The most items allowed, for an array key.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      A description of the rule.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        archived
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      True if the rule is archived.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        created_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the metadata key rule was created (ISO-8601 UTC).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        updated_at
      </code>
    </td>
    
    <td>
      <code>
        string · ISO-8601
      </code>
    </td>
    
    <td>
      When the metadata key rule was last changed (ISO-8601 UTC).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        version
      </code>
    </td>
    
    <td>
      <code>
        integer
      </code>
    </td>
    
    <td>
      A number that goes up on every change. Send it as <code>
        expected_version
      </code>
      
       on update.
    </td>
  </tr>
</tbody>
</table>

## Status codes

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        201
      </code>
    </td>
    
    <td>
      Created
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      Invalid rule; <code>
        param
      </code>
      
       names the field
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      No such business
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload.
    </td>
  </tr>
</tbody>
</table>
</template>

<template v-slot:request="">

```bash [Request]
curl -X POST "$TMBILLING_URL/v1/businesses/biz_XXXXXXXXXXXX01/metadata_key_rules" \
  -H "Authorization: Bearer $TMBILLING_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "entity_type": "customer",
    "key": "billing.po",
    "data_type": "string",
    "description": "Everything a growing team needs."
  }'
```

</template>

<template v-slot:response="">
<code-group>

```json [201 Created]
{
  "object": "metadata_key_rule",
  "id": "mkr_XXXXXXXXXXXX01",
  "entity_type": "customer",
  "key": "seats",
  "data_type": "text",
  "enum_options": [
    "Enum option"
  ],
  "pattern": "^[A-Z]{2}-[0-9]{4}$",
  "max_length": 1,
  "integer": false,
  "min": 1,
  "max": 1,
  "item_type": "string",
  "item_enum_options": [
    "Item enum option"
  ],
  "min_items": 1,
  "max_items": 1,
  "description": "Everything a growing team needs.",
  "archived": false,
  "created_at": "2026-03-14T09:30:00Z",
  "updated_at": "2026-03-14T09:30:00Z",
  "version": 1
}
```

```json [400 Bad Request]
{
  "error": {
    "type": "invalid_request_error",
    "message": "Invalid rule; param names the field"
  }
}
```

```json [404 Not Found]
{
  "error": {
    "type": "invalid_request_error",
    "message": "No such business"
  }
}
```

```json [409 Conflict]
{
  "error": {
    "type": "idempotency_error",
    "message": "Idempotency-Key conflict — the key is already in flight, or was reused with a different request payload."
  }
}
```

</code-group>
</template>
</api-operation>


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
