DonutworkHelp Center
Api ReferenceContenuti e media
Documentazione Donutwork

Content Box

Manage content types and content entities with scalable custom schemas.

Content Box API

The Content Box system provides a schematized storage layer for unstructured or custom-structured data. It allows organizations to define complex data models (Types) and instantiate them as managed content entities (Contents), suitable for blogs, product catalogs, and internal metadata repositories.


Content Entity Management

Manage the lifecycle of data entries within your defined content structures.

List Content Entities

Retrieve a paginated collection of content entities. Results can be filtered by state, content type, or via a full-text search query.

GET
/2026-02-01/contentbox/contents.json
Required permissioncontentbox_contents:read

Path, query, and header parameters

sizeinteger· query
Maximum records to return (up to 100). Default is 50.
pageinteger· query
The page index for pagination.
type_idstring· query
Filter by a specific Content Type ID.
statestring· query
Filter by lifecycle state (e.g., 'public', 'draft', 'archived').
searchstring· query
Perform a text search across content titles and data fields.

Responses

Collection of content entities retrieved.

{
  "entities": "Contents",
  "count": 12,
  "per_page": 50,
  "elements": [
    {
      "id": "6768...",
      "type_id": "6751...",
      "title": "Q1 Product Launch",
      "state": "public",
      "data": {
        "headline": "Introducing the 2026 Fleet",
        "hero_image": "https://cdn.acme.com/img/l1.jpg",
        "featured": true
      }
    }
  ]
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Create Content Entity

Provision a new content entry. The data payload must adhere to the requirements of the associated type_id.

POST
/2026-02-01/contentbox/contents.json
Required permissioncontentbox_contents:write

Path, query, and header parameters

No path, query, or additional header parameters.

Request Body

JSON
{
  "content": {
    "title": "Annual Sustainability Report",
    "type_id": "675112233b498f30",
    "state": "draft",
    "data": {
      "period": "2025",
      "impact_score": 92
    }
  }
}
content.titlestringRequired
Internal-facing title for the content entry.
content.type_idstringRequired
The unique identifier of the target Content Type schema.
content.statestring
Operational state (default: 'draft').
content.dataobject
Dictionary of custom fields defined in the type schema.

Responses

Content entity successfully provisioned.

{
  "id": "6768..."
}

Request examples

curl --request POST 'https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "content": {
    "title": "Annual Sustainability Report",
    "type_id": "675112233b498f30",
    "state": "draft",
    "data": {
      "period": "2025",
      "impact_score": 92
    }
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "content": {
      "title": "Annual Sustainability Report",
      "type_id": "675112233b498f30",
      "state": "draft",
      "data": {
        "period": "2025",
        "impact_score": 92
      }
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/contents.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "content": {
    "title": "Annual Sustainability Report",
    "type_id": "675112233b498f30",
    "state": "draft",
    "data": {
      "period": "2025",
      "impact_score": 92
    }
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Update Content Entity

Modify an existing content entry. This endpoint supports partial updates; only the fields provided in the content object will be modified.

PUT
/2026-02-01/contentbox/contents/{contentId}.json
Required permissioncontentbox_contents:write

Path, query, and header parameters

contentIdstring· pathRequired
The unique identifier of the content entry.

Request Body

JSON
{
  "content": {
    "state": "public",
    "data": {
      "revised_at": "2026-03-01T10:00:00Z"
    }
  }
}
content.titlestring
Update the internal title.
content.statestring
Transition the lifecycle state.
content.dataobject
Update specific keys within the data object.

Responses

Content entity successfully updated.

{
  "id": "6768...",
  "updated": true
}

Request examples

curl --request PUT 'https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "content": {
    "state": "public",
    "data": {
      "revised_at": "2026-03-01T10:00:00Z"
    }
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "content": {
      "state": "public",
      "data": {
        "revised_at": "2026-03-01T10:00:00Z"
      }
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "content": {
    "state": "public",
    "data": {
      "revised_at": "2026-03-01T10:00:00Z"
    }
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Retrieve Content Entity

Fetch the full payload for a single content entry.

GET
/2026-02-01/contentbox/contents/{contentId}.json
Required permissioncontentbox_contents:read

Path, query, and header parameters

contentIdstring· pathRequired
The unique identifier of the content entry.

Responses

Content entity retrieved.

{
  "id": "6768...",
  "title": "Q1 Product Launch",
  "state": "public",
  "data": {}
}

Content entry does not exist.

{
  "error": "Content Box not found"
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Decommission Content Entity

Permanently delete a content entry. This action is irreversible.

DELETE
/2026-02-01/contentbox/contents/{contentId}.json
Required permissioncontentbox_contents:write

Path, query, and header parameters

contentIdstring· pathRequired
The content identifier.

Responses

Deletion request processed.

{
  "id": "6768...",
  "deleted": true
}

Request examples

curl --request DELETE 'https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/contents/CONTENTID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.


Content Type Modeling (Schema Definition)

Define and manage the structural blueprints that govern how content is stored and validated.

List Content Types

Retrieve the catalog of all defined content schemas for your organization.

GET
/2026-02-01/contentbox/types.json
Required permissioncontentbox_types:read

Path, query, and header parameters

sizeinteger· query
Results per page.
pageinteger· query
Page index.

Responses

Collection of content type definitions.

{
  "entities": "Types",
  "count": 1,
  "elements": [
    {
      "id": "6751...",
      "title": "Corporate Blog",
      "description": "Schema for official news",
      "fields": {
        "author": {
          "label": "Author",
          "type": "string"
        }
      }
    }
  ]
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/contentbox/types.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/types.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/types.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Create Content Type

Define a new organizational schema. Specify the attributes and UI input types for each field in the model.

POST
/2026-02-01/contentbox/types.json
Required permissioncontentbox_types:write

Path, query, and header parameters

No path, query, or additional header parameters.

Request Body

JSON
{
  "type": {
    "title": "E-Commerce Product",
    "description": "Standardized schema for catalog items.",
    "fields": {
      "sku": {
        "label": "SKU",
        "type": "string"
      },
      "price": {
        "label": "Unit Price",
        "type": "string"
      },
      "in_stock": {
        "label": "Inventory Status",
        "type": "checkbox"
      }
    }
  }
}
type.titlestringRequired
Human-readable name for the schema.
type.descriptionstring
Internal description of the schema's purpose.
type.fieldsobjectRequired
A map of field definitions (key -> {label, type}).

Responses

Content type definition created.

{
  "id": "6751...",
  "title": "E-Commerce Product"
}

Request examples

curl --request POST 'https://api.hub.donutwork.com/2026-02-01/contentbox/types.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "type": {
    "title": "E-Commerce Product",
    "description": "Standardized schema for catalog items.",
    "fields": {
      "sku": {
        "label": "SKU",
        "type": "string"
      },
      "price": {
        "label": "Unit Price",
        "type": "string"
      },
      "in_stock": {
        "label": "Inventory Status",
        "type": "checkbox"
      }
    }
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/types.json', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "type": {
      "title": "E-Commerce Product",
      "description": "Standardized schema for catalog items.",
      "fields": {
        "sku": {
          "label": "SKU",
          "type": "string"
        },
        "price": {
          "label": "Unit Price",
          "type": "string"
        },
        "in_stock": {
          "label": "Inventory Status",
          "type": "checkbox"
        }
      }
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/types.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "type": {
    "title": "E-Commerce Product",
    "description": "Standardized schema for catalog items.",
    "fields": {
      "sku": {
        "label": "SKU",
        "type": "string"
      },
      "price": {
        "label": "Unit Price",
        "type": "string"
      },
      "in_stock": {
        "label": "Inventory Status",
        "type": "checkbox"
      }
    }
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Retrieve Type Definition

Fetch the precise structural definition for a specific content type.

GET
/2026-02-01/contentbox/types/{typeId}.json
Required permissioncontentbox_types:read

Path, query, and header parameters

typeIdstring· pathRequired
The unique identifier for the content type.

Responses

Full schema definition retrieved.

{
  "id": "6751...",
  "title": "Corporate Blog",
  "fields": {}
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Update Type Definition

Update metadata or fields for a specific content schema. When fields is provided, each field must include both label and type and use allowed input types.

PUT
/2026-02-01/contentbox/types/{typeId}.json
Required permissioncontentbox_types:write

Path, query, and header parameters

typeIdstring· pathRequired
The unique identifier for the content type.

Request Body

JSON
{
  "type": {
    "title": "Corporate Blog",
    "description": "Schema for official company news",
    "fields": {
      "author": {
        "label": "Author",
        "type": "string"
      },
      "hero_image": {
        "label": "Hero Image",
        "type": "url"
      }
    }
  }
}
type.titlestring
Updated schema title.
type.descriptionstring
Updated schema description.
type.fieldsobject
Updated field map. Each field requires `label` and `type`.

Responses

Content type updated.

{
  "id": "6751...",
  "title": "Corporate Blog",
  "description": "Schema for official company news",
  "fields": {}
}

Invalid fields payload or field type.

{
  "error": "Fields must be an associative array"
}

Request examples

curl --request PUT 'https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "type": {
    "title": "Corporate Blog",
    "description": "Schema for official company news",
    "fields": {
      "author": {
        "label": "Author",
        "type": "string"
      },
      "hero_image": {
        "label": "Hero Image",
        "type": "url"
      }
    }
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "type": {
      "title": "Corporate Blog",
      "description": "Schema for official company news",
      "fields": {
        "author": {
          "label": "Author",
          "type": "string"
        },
        "hero_image": {
          "label": "Hero Image",
          "type": "url"
        }
      }
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/contentbox/types/TYPEID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "type": {
    "title": "Corporate Blog",
    "description": "Schema for official company news",
    "fields": {
      "author": {
        "label": "Author",
        "type": "string"
      },
      "hero_image": {
        "label": "Hero Image",
        "type": "url"
      }
    }
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

On this page