Skip to main content
The Draft Package Workflow provides a development environment for testing components, content types, and content before creating formal package versions. This workflow enables teams to iterate on their work while maintaining a clear development-to-production path.

Concepts

The workflow follows these principles:
  1. Development Lifecycle
    • Draft components → Draft package → Draft content type → Draft content
    • Each stage requires the previous to be in place
    • Formal publishing follows the same sequence
    • Dependencies flow downward through the chain
  2. Draft Package
    • Virtual package composed of latest components (both draft and modified)
    • Includes all draft components (never published)
    • Includes all modified components (unpublished changes)
    • Acts as a working copy within the project
    • Not formally versioned or published
    • Used for development and testing
  3. Publishing Constraints
    • Content type cannot be published unless its package is published
    • Content cannot be published unless its content type is published
    • Enforces stability in the production chain
    • Prevents referencing unstable components

Workflow Diagram

Using Draft Package in Content Types

Content types can reference the draft package during development to use the latest component versions without needing to create a formal package.

Create Content Type with Draft Package

POST /v1/organizations/:organizationId/projects/:projectId/content-types
Request Body:
{
  "name": "Blog Post",
  "description": "Standard blog post layout",
  "layoutComponentId": "comp125",
  "componentIdsAllowList": ["comp123", "comp124"],
  "packageVersion": "draft",
  "permissions": {
    "roles": ["editor"]
  }
}
When using "packageVersion": "draft", the content type is tied to the current working state of components. This content type cannot be published until an actual package version is created and the content type is updated to reference it.

Creating Content from Draft Content Types

Content can be created from draft content types, but it will also remain in draft state until its content type is published.

Create Content with Draft Content Type

POST /v1/organizations/:organizationId/projects/:projectId/content
Request Body:
{
  "typeId": "ct123",
  "name": "My First Blog Post",
  "content": {
    "title": "Hello World",
    "body": "This is my first post..."
  }
}

Publishing Workflow

Step 1: Publish Package

First, create and publish a formal package version. This will:
  • Publish all draft components (never published) with version 1
  • Publish all modified components with incremented version
  • Create an immutable package snapshot
POST /v1/organizations/:organizationId/projects/:projectId/packages
Request Body:
{
  "version": "1.0.0",
  "metadata": {
    "description": "Initial release"
  }
}

Step 2: Update Content Type to Use Published Package

PUT /v1/organizations/:organizationId/projects/:projectId/content-types/:id/package-version
Request Body:
{
  "packageVersion": "1.0.0"
}

Step 3: Publish Content Type

POST /v1/organizations/:organizationId/projects/:projectId/content-types/:id/publish

Step 4: Publish Content

POST /v1/organizations/:organizationId/projects/:projectId/content/:id/publish

Code Example

Complete workflow from development to production:
// 1. Create components (they start as drafts)
await fetch('/v1/organizations/org123/projects/proj456/components', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'HeroSection',
    type: 'view',
    content: 'const body = (props) => { ... }'
  })
});

// 2. Create content type referencing draft package
await fetch('/v1/organizations/org123/projects/proj456/content-types', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'Landing Page',
    layoutComponentId: 'comp123',
    packageVersion: 'draft'
  })
});

// 3. Create and test content with draft content type
await fetch('/v1/organizations/org123/projects/proj456/content', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    typeId: 'ct123',
    name: 'Homepage',
    content: { headline: 'Welcome' }
  })
});

// 4. When ready, publish the package
await fetch('/v1/organizations/org123/projects/proj456/packages', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({ version: '1.0.0' })
});

// 5. Update content type to use published package
await fetch('/v1/organizations/org123/projects/proj456/content-types/ct123/package-version', {
  method: 'PUT',
  headers: { 'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({ packageVersion: '1.0.0' })
});

// 6. Publish content type
await fetch('/v1/organizations/org123/projects/proj456/content-types/ct123/publish', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN' }
});

// 7. Publish content
await fetch('/v1/organizations/org123/projects/proj456/content/cont123/publish', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer TOKEN' }
});