Create Metafield Definition
curl --request POST \
--url https://api.launchmystore.io/metafield-definitions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"namespace": "<string>",
"key": "<string>",
"name": "<string>",
"type": "<string>",
"ownerType": "<string>",
"description": "<string>",
"validations": {},
"pinned": true
}
'import requests
url = "https://api.launchmystore.io/metafield-definitions"
payload = {
"namespace": "<string>",
"key": "<string>",
"name": "<string>",
"type": "<string>",
"ownerType": "<string>",
"description": "<string>",
"validations": {},
"pinned": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
namespace: '<string>',
key: '<string>',
name: '<string>',
type: '<string>',
ownerType: '<string>',
description: '<string>',
validations: {},
pinned: true
})
};
fetch('https://api.launchmystore.io/metafield-definitions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.launchmystore.io/metafield-definitions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'namespace' => '<string>',
'key' => '<string>',
'name' => '<string>',
'type' => '<string>',
'ownerType' => '<string>',
'description' => '<string>',
'validations' => [
],
'pinned' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.launchmystore.io/metafield-definitions"
payload := strings.NewReader("{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.launchmystore.io/metafield-definitions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.launchmystore.io/metafield-definitions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}"
response = http.request(request)
puts response.read_bodyDefinitions
Create Metafield Definition
Create a new metafield definition. Admin API only.
POST
/
metafield-definitions
Create Metafield Definition
curl --request POST \
--url https://api.launchmystore.io/metafield-definitions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"namespace": "<string>",
"key": "<string>",
"name": "<string>",
"type": "<string>",
"ownerType": "<string>",
"description": "<string>",
"validations": {},
"pinned": true
}
'import requests
url = "https://api.launchmystore.io/metafield-definitions"
payload = {
"namespace": "<string>",
"key": "<string>",
"name": "<string>",
"type": "<string>",
"ownerType": "<string>",
"description": "<string>",
"validations": {},
"pinned": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
namespace: '<string>',
key: '<string>',
name: '<string>',
type: '<string>',
ownerType: '<string>',
description: '<string>',
validations: {},
pinned: true
})
};
fetch('https://api.launchmystore.io/metafield-definitions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.launchmystore.io/metafield-definitions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'namespace' => '<string>',
'key' => '<string>',
'name' => '<string>',
'type' => '<string>',
'ownerType' => '<string>',
'description' => '<string>',
'validations' => [
],
'pinned' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.launchmystore.io/metafield-definitions"
payload := strings.NewReader("{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.launchmystore.io/metafield-definitions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.launchmystore.io/metafield-definitions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"namespace\": \"<string>\",\n \"key\": \"<string>\",\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"ownerType\": \"<string>\",\n \"description\": \"<string>\",\n \"validations\": {},\n \"pinned\": true\n}"
response = http.request(request)
puts response.read_bodyCreate Metafield Definition
Admin API only — requires a merchant JWT. Not exposed to OAuth apps.
(ownerType, namespace, key) are
validated against it.
Request
curl -X POST "https://api.launchmystore.io/metafield-definitions" \
-H "Authorization: Bearer <merchant-jwt>" \
-H "Content-Type: application/json" \
-d '{
"namespace": "custom",
"key": "warranty_years",
"name": "Warranty (years)",
"description": "How many years of warranty are included",
"type": "number_integer",
"ownerType": "product",
"validations": { "min": 0, "max": 25 },
"pinned": true
}'
Auth
Merchant JWT (owner, or staff with admin/manager access).Body parameters
Namespace (e.g.
custom, your app handle, or anything else).Machine name. Unique per
(storeId, ownerType, namespace).Human label shown in the admin UI.
One of the 22 supported types.
One of the 9 owner types.
Tooltip / helper text shown in admin.
Type-dependent validation rules. See
validation rules per type.
If true, the field appears on the resource detail page in admin without
the merchant having to click “Add custom data”.
Examples
Number with bounds
{
"namespace": "custom",
"key": "warranty_years",
"name": "Warranty (years)",
"type": "number_integer",
"ownerType": "product",
"validations": { "min": 0, "max": 25 },
"pinned": true
}
Single-line text with regex
{
"namespace": "custom",
"key": "sku_internal",
"name": "Internal SKU",
"type": "single_line_text_field",
"ownerType": "product",
"validations": { "regex": "^[A-Z0-9-]{6,12}$" }
}
List of references
{
"namespace": "custom",
"key": "related_products",
"name": "Related products",
"type": "list.product_reference",
"ownerType": "product",
"validations": { "list_min": 0, "list_max": 10 }
}
URL with restricted schemes
{
"namespace": "custom",
"key": "demo_link",
"name": "Demo link",
"type": "url",
"ownerType": "product",
"validations": { "allowed_schemes": ["https"] }
}
Response
{
"status": 201,
"state": "success",
"data": {
"id": "f7e3a920-...",
"namespace": "custom",
"key": "warranty_years",
"name": "Warranty (years)",
"type": "number_integer",
"owner_type": "product",
"validations": { "min": 0, "max": 25 },
"pinned": true,
"app_id": null,
"created_at": "2026-05-09T13:30:00.000Z",
"updated_at": "2026-05-09T13:30:00.000Z"
}
}
Error codes
| Code | Description |
|---|---|
UNAUTHORIZED | Invalid or missing JWT |
FORBIDDEN | Wrong store / insufficient role |
VALIDATION_ERROR | Invalid type, owner type, or validation key |
DUPLICATE_KEY | A definition with this (ownerType, namespace, key) already exists |
⌘I