# Model custom objects

> Define a reusable object type with metaobjects and create records from it.

This guide models a piece of data that **isn't a built-in resource** - a size guide - using [metaobjects](/api/product-management/metaobjects/). You declare the shape once as a [metaobject definition](/api/product-management/metaobject-definitions/), then create records from it.

Where a [custom field](/guides/add-a-custom-field/) adds **one value** to an existing product or variant, a metaobject is a **whole record of your own design** - reusable, and referenceable from many products.

## Prerequisites

You need an instance and a partner token. You don't need an existing product for the core steps (a product only comes in at the end, to reference a record).

As in the other guides, the commands below use:

- the organization `id` - shown as `<org_id>`
- the instance `handle` (the tenant) - shown as `<tenant>`

## Before you start

You need an OAuth 2.0 **bearer token** for a partner account. Sign in below: your token is dropped into every command on this page, and you can pick your organization and instance to fill `<org_id>` and `<tenant>` too. See [Authentication](/authentication/) for more.

## Steps

<Steps>

1. **Define the object type.**

   Create a [metaobject definition](/api/product-management/metaobject-definitions/). Give it a `type` slug, a `name`, the `fieldDefinitions` its records will carry, and a `displayNameField` (the key shown as a record's label). Capture the `@id`.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/metaobject_definitions' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "type": "size_guide",
       "name": "Size guide",
       "displayNameField": "title",
       "fieldDefinitions": [
         {
           "key": "title",
           "name": "Title",
           "type": "/rest/api/metafield_definition_types/single_line_text_field",
           "required": true
         },
         {
           "key": "body",
           "name": "Body",
           "type": "/rest/api/metafield_definition_types/multi_line_text_field",
           "required": false
         }
       ]
     }'
   ```

   ```json
   {
     "@id": "/rest/api/metaobject_definitions/019afc01-1a2b-7c3d-8e4f-0a1b2c3d4e5f",
     "type": "size_guide",
     "displayNameField": "title"
   }
   ```

2. **Create a record.**

   Create a [metaobject](/api/product-management/metaobjects/) of that type. Reference the `definition`, give it a unique `handle`, and supply the `fields` values - one per field key. Each value is validated against the field's type.

   ```bash
   curl -X POST 'https://<tenant>.product-management.flowkiwi.net/rest/api/metaobjects' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Content-Type: application/ld+json' \
     -d '{
       "definition": "/rest/api/metaobject_definitions/019afc01-1a2b-7c3d-8e4f-0a1b2c3d4e5f",
       "handle": "mens-shoes-eu",
       "status": "ACTIVE",
       "fields": [
         { "key": "title", "value": "EU men'"'"'s shoes" },
         { "key": "body", "value": "EU 40 = 25.5 cm, EU 41 = 26.2 cm, EU 42 = 27 cm" }
       ]
     }'
   ```

3. **Fetch it by handle.**

   You don't need the id to read a record back - the type and handle are enough:

   ```bash
   curl 'https://<tenant>.product-management.flowkiwi.net/rest/api/metaobjects/size_guide/mens-shoes-eu' \
     -H 'Authorization: Bearer {token}' \
     -H 'X-Flowkiwi-Organization-Id: <org_id>' \
     -H 'Accept: application/ld+json'
   ```

   You can also [list every record of the type](/api/product-management/metaobjects/list-by-type/) at `/rest/api/metaobject_definitions/size_guide/metaobjects`.

</Steps>

> **Why model it this way?**
>
> Defining `size_guide` once means every record shares the same fields and validation. Create one record per size chart, then attach the right one to many products - without duplicating the data on each product.

## Next steps

- **Attach a record to a product.** Create a [metafield definition](/api/product-management/metafield-definitions/) whose `type` is a metaobject reference, then set a [metafield](/api/product-management/metafields/) on a product pointing at your metaobject - that's how a size guide ends up on a product page. See [Add a custom field](/guides/add-a-custom-field/) for the metafield basics.
- **Grow the model.** Add `fieldDefinitions` to the definition as your records need more attributes.
- **Reference records by slug.** Use stable `handle`s so other systems can link to records by a readable key.
