Create Content Type
curl --request POST \
--url https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"layoutComponentId": "<string>",
"componentIdsAllowList": [
{}
],
"packageVersion": "<string>",
"templateContentIds": [
"<string>"
],
"permissions": {
"permissions.roles": [
"<string>"
],
"permissions.users": [
"<string>"
],
"permissions.publish": {}
},
"metadata": {
"metadata.tags": [
"<string>"
],
"metadata.locales": [
"<string>"
]
}
}
'import requests
url = "https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types"
payload = {
"name": "<string>",
"description": "<string>",
"layoutComponentId": "<string>",
"componentIdsAllowList": [{}],
"packageVersion": "<string>",
"templateContentIds": ["<string>"],
"permissions": {
"permissions.roles": ["<string>"],
"permissions.users": ["<string>"],
"permissions.publish": {}
},
"metadata": {
"metadata.tags": ["<string>"],
"metadata.locales": ["<string>"]
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
layoutComponentId: '<string>',
componentIdsAllowList: [{}],
packageVersion: '<string>',
templateContentIds: ['<string>'],
permissions: {
'permissions.roles': ['<string>'],
'permissions.users': ['<string>'],
'permissions.publish': {}
},
metadata: {'metadata.tags': ['<string>'], 'metadata.locales': ['<string>']}
})
};
fetch('https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types', 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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types",
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([
'name' => '<string>',
'description' => '<string>',
'layoutComponentId' => '<string>',
'componentIdsAllowList' => [
[
]
],
'packageVersion' => '<string>',
'templateContentIds' => [
'<string>'
],
'permissions' => [
'permissions.roles' => [
'<string>'
],
'permissions.users' => [
'<string>'
],
'permissions.publish' => [
]
],
'metadata' => [
'metadata.tags' => [
'<string>'
],
'metadata.locales' => [
'<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}"
response = http.request(request)
puts response.read_bodyContent Types
Create Content Type
Create a new content type definition
POST
/
app
/
v1
/
organizations
/
{organizationId}
/
projects
/
{projectId}
/
content-types
Create Content Type
curl --request POST \
--url https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"layoutComponentId": "<string>",
"componentIdsAllowList": [
{}
],
"packageVersion": "<string>",
"templateContentIds": [
"<string>"
],
"permissions": {
"permissions.roles": [
"<string>"
],
"permissions.users": [
"<string>"
],
"permissions.publish": {}
},
"metadata": {
"metadata.tags": [
"<string>"
],
"metadata.locales": [
"<string>"
]
}
}
'import requests
url = "https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types"
payload = {
"name": "<string>",
"description": "<string>",
"layoutComponentId": "<string>",
"componentIdsAllowList": [{}],
"packageVersion": "<string>",
"templateContentIds": ["<string>"],
"permissions": {
"permissions.roles": ["<string>"],
"permissions.users": ["<string>"],
"permissions.publish": {}
},
"metadata": {
"metadata.tags": ["<string>"],
"metadata.locales": ["<string>"]
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
layoutComponentId: '<string>',
componentIdsAllowList: [{}],
packageVersion: '<string>',
templateContentIds: ['<string>'],
permissions: {
'permissions.roles': ['<string>'],
'permissions.users': ['<string>'],
'permissions.publish': {}
},
metadata: {'metadata.tags': ['<string>'], 'metadata.locales': ['<string>']}
})
};
fetch('https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types', 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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types",
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([
'name' => '<string>',
'description' => '<string>',
'layoutComponentId' => '<string>',
'componentIdsAllowList' => [
[
]
],
'packageVersion' => '<string>',
'templateContentIds' => [
'<string>'
],
'permissions' => [
'permissions.roles' => [
'<string>'
],
'permissions.users' => [
'<string>'
],
'permissions.publish' => [
]
],
'metadata' => [
'metadata.tags' => [
'<string>'
],
'metadata.locales' => [
'<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
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.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/app/v1/organizations/{organizationId}/projects/{projectId}/content-types")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"layoutComponentId\": \"<string>\",\n \"componentIdsAllowList\": [\n {}\n ],\n \"packageVersion\": \"<string>\",\n \"templateContentIds\": [\n \"<string>\"\n ],\n \"permissions\": {\n \"permissions.roles\": [\n \"<string>\"\n ],\n \"permissions.users\": [\n \"<string>\"\n ],\n \"permissions.publish\": {}\n },\n \"metadata\": {\n \"metadata.tags\": [\n \"<string>\"\n ],\n \"metadata.locales\": [\n \"<string>\"\n ]\n }\n}"
response = http.request(request)
puts response.read_bodyPath Parameters
string
required
Organization ID
string
required
Project ID
Request Body
string
required
Display name for the content type (e.g., “Article”, “BlogPost”)
string
Structured markdown description for semantic search and LLM understanding
string
required
ID of the layout component that defines the structure
array
required
Array of component IDs or component groups that can be used within this content type
string
required
Version of package to use for component resolution
string[]
Array of pre-built content example IDs
object
Example Request
{
"name": "BlogPost",
"description": "Blog post content type for personal and corporate blogging.\n\n**Content structure:**\n- Featured image and title\n- Author bio section\n- Rich text with code snippets\n\n**Best for:**\n- Personal blogs\n- Technical tutorials\n\n**Typical length:** 800-2000 words\n**Supported platforms:** Web, iOS, Android, React",
"layoutComponentId": "c125",
"componentIdsAllowList": ["c126", "c127", "c128"],
"packageVersion": "1.0.0",
"templateContentIds": ["cont125"],
"permissions": {
"roles": ["blogger", "editor"]
},
"metadata": {
"tags": ["blog", "content"],
"locales": ["en-US"]
}
}
New content types are created with
draft status and null version. Use the publish endpoint to create the first published version.Response
Returns the created ContentType object.{
"id": "ct125",
"name": "BlogPost",
"description": "Blog post content type for personal and corporate blogging...",
"status": "draft",
"version": null,
"lastPublishedVersion": null,
"layoutComponentId": "c125",
"componentIdsAllowList": ["c126", "c127", "c128"],
"packageVersion": "1.0.0",
"schema": { ... },
"templateContentIds": ["cont125"],
"permissions": {
"roles": ["blogger", "editor"],
"users": [],
"publish": {
"roles": [],
"users": []
}
},
"metadata": {
"author": "user123",
"tags": ["blog", "content"],
"locales": ["en-US"]
},
"createdAt": "2024-03-20T10:00:00Z",
"updatedAt": "2024-03-20T10:00:00Z"
}
Error Responses
Component Not Found
{
"error": {
"code": "COMPONENT_NOT_FOUND",
"message": "Layout component not found",
"details": {
"componentId": "c125"
}
}
}
Invalid Package Version
{
"error": {
"code": "PACKAGE_NOT_FOUND",
"message": "Package version 1.0.0 not found"
}
}
Invalid Component Allow List
{
"error": {
"code": "VALIDATION_FAILED",
"message": "componentIdsAllowList validation failed",
"details": {
"invalidComponentIds": ["c999"],
"emptyGroups": ["media"]
}
}
}
Code Examples
curl -X POST "https://api.metabind.ai/app/v1/organizations/org123/projects/proj456/content-types" \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "BlogPost",
"layoutComponentId": "c125",
"componentIdsAllowList": ["c126", "c127"],
"packageVersion": "1.0.0"
}'
const response = await fetch(
'https://api.metabind.ai/app/v1/organizations/org123/projects/proj456/content-types',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'BlogPost',
layoutComponentId: 'c125',
componentIdsAllowList: ['c126', 'c127'],
packageVersion: '1.0.0'
})
}
);
const contentType = await response.json();
console.log(`Created content type: ${contentType.id}`);