Skip to content

Create a contract

POST
/content/management/v1/contracts
curl --request POST \
--url https://api.ebitex.io/content/management/v1/contracts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "name": "example", "externalId": "example", "parentContractId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "isAbstract": true, "fields": [ { "name": "example", "externalId": "example", "fieldTypeKey": "example", "isMandatory": true, "isEnumerable": true, "isLocalizable": true, "isContextual": true, "isPersonalizable": true, "settings": "example", "defaultValue": "example" } ], "defaultFolderId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "titleFieldPath": "example" }'

Creates a contract: a content type and the ordered list of fields its components carry. Send name, externalId (lowercase kebab-case, 3 to 64 characters, unique in the environment), isAbstract, an optional parentContractId to inherit another contract’s fields, and fields. Each field names its fieldTypeKey (see listFieldTypes), its own kebab-case externalId, its modifiers (isMandatory, isEnumerable, isLocalizable, isContextual, isPersonalizable), settings matching that field type’s settings schema, and an optional defaultValue. A field may not reuse an external id an ancestor already declares.

titleFieldPath optionally names the field that titles this contract’s pages in navigation: a field external id, or up to four joined with . to reach into inline values. Only its shape is checked, so a path may name a field that does not exist yet; a path that never resolves falls back to the page’s own name.

A new contract always starts at version 1. Add ?dryRun=true to run the same validation and change classification without saving anything. The response is { classification, currentLatestVersionNumber, resultingVersionNumber, breakingReasons }, where classification is new, additive, breaking or noChange, and each breaking reason is { fieldExternalId, reason }.

Key: a management key with content.management.authoring.

dryRun
boolean
Media typeapplication/json
object
name
required
string
externalId
required
string
parentContractId
required
null | string format: uuid
isAbstract
required
boolean
fields
required
Array<object>
object
name
required
string
externalId
required
string
fieldTypeKey
required
string
isMandatory
required
boolean
isEnumerable
required
boolean
isLocalizable
required
boolean
isContextual
required
boolean
isPersonalizable
required
boolean
settings
required
One of:
null
defaultValue
defaultFolderId
null | string format: uuid
titleFieldPath
null | string
Examplegenerated
{
"name": "example",
"externalId": "example",
"parentContractId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"isAbstract": true,
"fields": [
{
"name": "example",
"externalId": "example",
"fieldTypeKey": "example",
"isMandatory": true,
"isEnumerable": true,
"isLocalizable": true,
"isContextual": true,
"isPersonalizable": true,
"settings": "example",
"defaultValue": "example"
}
],
"defaultFolderId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"titleFieldPath": "example"
}

The new contract, shaped like getContract, with 201 Created. With dryRun=true, 200 and the change classification instead.

validation_failed: the body is invalid. errors maps each failing member (such as externalId or fields[2].settings) to a message. Common causes: an unknown field type, settings that do not match the field type’s schema, a missing or cyclic parent, or a duplicate external id.

missing_api_key or invalid_api_key: no key was sent, or it is unknown, revoked or expired.

payment_required: the organization’s subscription needs attention.

permission_denied: the key’s role lacks content.contracts.manage.

scope_denied: the key lacks this route’s scope. tier_required: the Content Management API needs the Pro plan or above. ip_denied: the caller’s address is outside the key’s allowed ranges. app_not_available: Content is not enabled for the organization.

duplicate_external_id: another contract in this environment already has this external id.

Rate limit or quota exceeded; Retry-After says how long to wait. too_many_failed_authentications: too many bad keys from this address.