Builder
Generate and manage website builder content.
Get every content type and the blocks allowed in it
/builder/content-typesLists every content type you can create or edit — website pages, posts, landings, headers, footers, sidebars, dialogs and layouts; kb articles and landings; developer docs and landings; forms; emails and their headers and footers — with the builder context each belongs to and the exact block types allowed inside it. Use it to answer 'what can I put in this?' before building. The reverse lookup, 'where can I use this block?', is the contexts field on listBuilderBlocks.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const { contentTypes } = await gc.builder.getContentTypes();
Get the styles schema shared by every block
/builder/stylesReturns the one styles object every block, column and section accepts — margin, padding, width, background, border, box shadow, position, per-breakpoint visibility, entrance animation and cssId/cssClasses. It is identical for every block type, so call this once and reuse it. getBlock omits styles and refers here rather than repeating them on every block. The schema carries its own value-format guidance: which fields take per-breakpoint objects, when a bare number means a theme spacing multiple rather than pixels, and exactly which colour tokens resolve.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const { data: blockStyles } = await gc.builder.getBlockStyles();
Get one block type's own fields and hints; shared styles come from getBlockStyles
/builder/blocks/{blockType}Returns the JSON schema for a single block type plus its per-field authoring hints, scoped to (and validated against) the content type's palette. The styles object is identical for every block and is served by getBlockStyles instead of being repeated here. Follow this exactly when building block data for insertBlock/updateBlock.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const { data: block } = await gc.builder.getBlock({ blockType: "example-block-type", contentType: "example-content-type",});
Delete a section and every block inside it; recoverable from version history
/organizations/{organizationId}/projects/{projectId}/content/sections/deleteRemoves a section (and its blocks) from a content tree and records a version. Returns the removed section. The prior state is recoverable via restoreContentVersion.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.deleteSection({ organizationId: org.id, projectId: projects[0].id, data: { id: "section-id" }});
Insert a section into a content tree
/organizations/{organizationId}/projects/{projectId}/content/sections/insertInserts a new section (validated against the section schema, including any blocks it carries) and records a version. Every field on the supplied section is kept; only id and type are server-owned. Ids are generated for the section and for any columns/blocks that omit one. Omit an anchor to append at the end.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const section = await gc.builder.insertSection({ organizationId: org.id, projectId: projects[0].id, data: {}});
Update a section's own properties; blocks stay untouched and columns cannot be patched
/organizations/{organizationId}/projects/{projectId}/content/sections/updatePatches a section's own properties and records a version. Any section field may be patched; id, type and columns are refused with an error rather than ignored. Does not touch its blocks — use the block tools for those.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "default-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.updateSection({ organizationId: org.id, projectId: projects[0].id, data: {}});
Delete a block, returning it; the prior tree stays in version history
/organizations/{organizationId}/projects/{projectId}/content/blocks/deleteRemoves a block from a content tree and records a version. Returns the removed block, plus columnRemoved or sectionRemoved when deleting the block emptied its container: an empty column is pruned (it renders a gap) and, when that empties the whole section, the section is pruned too (it paints an orphan background band). Non-destructive at the history level — the prior state is recoverable via restoreContentVersion.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.deleteBlock({ organizationId: org.id, projectId: projects[0].id, data: { id: "block-123" }});
Insert a block into a content tree
/organizations/{organizationId}/projects/{projectId}/content/blocks/insertInserts a new block into a content entity's tree and records a version. The block's data is validated against its type's schema and the content's block palette. Returns the created block (with its generated id).
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const block = await gc.builder.insertBlock({ organizationId: org.id, projectId: projects[0].id, data: { type: "text", content: "Hello World" }});
Update a block's data and/or styles by merging only the fields you send; null clears a field
/organizations/{organizationId}/projects/{projectId}/content/blocks/updateMerges the supplied fields into a block's data and/or its styles and records a version. Send data, styles, or both; fields you omit keep their current value; send null to clear one. Styles cover padding, margins, borders, background, alignment and hideOnMobile — previously settable only at insertBlock, now editable here. Locale maps merge per locale, so writing one language leaves the others intact. Validated against the block type's schema.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.updateBlock({ organizationId: org.id, projectId: projects[0].id, data: { content: "Updated block content" }});
Move a section before or after a sibling, or append it at the end
/organizations/{organizationId}/projects/{projectId}/content/sections/moveReorders a section to a new position (relative to a sibling, or appended) and records a version. Returns the moved section.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.moveSection({ organizationId: org.id, projectId: projects[0].id, data: { sectionId: "sec_123", index: 1 }});
Move a block beside a sibling or into a section, leaving its data unchanged
/organizations/{organizationId}/projects/{projectId}/content/blocks/moveRelocates a block to a new anchor (next to a sibling, or into a section) and records a version. Returns the moved block.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.moveBlock({ organizationId: org.id, projectId: projects[0].id, data: { blockId: "block-123", targetIndex: 2 }});
Return a published item to draft — status only, never the body
/organizations/{organizationId}/projects/{projectId}/content/unpublishSets a content item's status back to draft, taking it off the public site while leaving its content, slug and metadata intact so it can be published again unchanged. The first-published date is kept, not cleared. Unpublishing tells the search engines the URL is gone and purges the public cache, so a page removed this way stops being served rather than lingering in a cache or an index.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.unpublishContent({ organizationId: org.id, projectId: projects[0].id, data: {},});
Publish a page, post, article, doc or email — status only, never the body
/organizations/{organizationId}/projects/{projectId}/content/publishSets a content item's status to published and leaves everything else untouched: not its content, slug, layout or metadata. Works for every content type that has a draft/published lifecycle — website pages and posts, KB articles, developer docs and emails. Structural pieces (headers, footers, layouts, landings, forms) are always live and are refused by name. Publishing re-indexes the item for AI search, signals the search engines, and purges the public cache. Re-publishing something already published is not an error; the response says alreadyInState. Pass publishAt with a future timestamp to schedule instead of publishing: the item stays a draft until a job takes it live, and the response returns scheduledPublishAt with status still draft.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.publishContent({ organizationId: org.id, projectId: projects[0].id, data: { content: "example" }});
Find a string or a block type inside content
/organizations/{organizationId}/projects/{projectId}/content/searchSearch the content of pages, posts, KB articles and developer docs in a project — by exact case-insensitive string (query), by block type (blockTypes), or both. A text query also searches each section's heading and subheading, not just block copy. Filter by content type and by draft/published status. Every match reports its full location — contentId (canonical type), sectionId, columnId and blockId — plus matchIn (block, heading or subheading), so a hit feeds straight into a structural op (deleteSection, moveBlock, updateBlock, updateSection) with no tree read. The field path, locale and snippet are populated for a text query and null for a pure block-type match. Use searchSources instead when looking for material by meaning rather than by exact wording or structure.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const result = await gc.builder.searchContent({ organizationId: org.id, projectId: projects[0].id,});
Get a content tree for editing
/organizations/{organizationId}/projects/{projectId}/contentReturns the full Section[] content tree (with every section/column/block id) for a content entity — pages, posts, landings, etc. Fetch this before granular edits so you have the ids to target.
import { createGiantContext } from "@giantcontext/sdk-typescript";
const gc = createGiantContext({ apiKey: process.env.GIANTCONTEXT_API_KEY! });
const org = await gc.organizations.getOrganizationBySlug({ slug: "my-org" });const { projects } = await gc.projects.listProjects({ organizationId: org.id });
const content = await gc.builder.getContent({ organizationId: org.id, projectId: projects[0].id, contentType: "page", contentId: "content-123",});