Create a contract
const url = 'https://api.ebitex.io/content/management/v1/contracts';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"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","referenceTree":"example","externalLinks":"example","systemParent":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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", "referenceTree": "example", "externalLinks": "example", "systemParent": "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.
A field’s allow-list settings (allowedContractIds, allowedTemplateIds, allowedCategoryGroupIds, allowedKinds, allowedInlineKinds, allowedProtocols, allowedContentTypes and markdownFeatures) have three states: leave the setting out and anything is allowed, give a list and exactly those are allowed, give an empty list and nothing is allowed. An empty list is never the same as leaving the setting out. allowedModes is the one exception: it must allow at least one mode, so leave it out to allow either, and an empty list is refused.
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.
referenceTree optionally tells the component editor to draw fields that reference components of the same kind, such as a pedigree’s sire and dam or a bill of materials’ components, as one editable tree. It is { "label": "Pedigree", "fields": ["sire", "dam"], "depth": 4, "repeats": "allow", "layout": "chart" }, where fields lists field external ids, depth is 2 to 6 (default 4), repeats is allow (default) or never (each component may appear once in the tree) and layout is chart or outline. It changes how the fields are edited and nothing else: it creates no contract version and changes no component or delivery response. A loop, where a component would become its own ancestor, is always refused when a component is written, including a loop that runs through a value described inline in one of the named fields: the editor draws through inline values, so the check follows them. An empty fields list opts out of a setting inherited from a parent. Only its shape is checked, so it may name a field that does not exist yet.
externalLinks optionally lists up to five links the component editor shows for a component of this contract, each { "label": "Print pedigree", "url": "{origin}/archive/{id}/certificate", "site": "Drakeshead", "requires": "published" }. The url is a template that begins with {origin}, https:// or http:// and may use {id}, {externalId}, {field:<path>} (a field external id, or up to four joined with .) and {key:<path>} (the key of the reference at that path; empty when none is chosen). {origin} stands for the address of the Site named in site and must be followed by /; a token is never allowed in the scheme or host of a literal address, so a field value cannot change where a link points. requires is none (default) or published, which enables the link once the component is published. Like referenceTree it is presentation only: no contract version, no component change and no delivery response. An empty list opts out of a setting inherited from a parent. A save replaces the whole setting, so send it on every update or it is cleared.
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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
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", "referenceTree": "example", "externalLinks": "example", "systemParent": "example"}Responses
Section titled “ Responses ”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.