Skip to main content
The CMS pillar is what turns a static AI-generated site into a real, editable property. Every text node and image you mark up with our conventions becomes a field in the project’s admin — no schemas, no migrations, no glue code.

What this gives you

  • Translation keys — dot-namespaced keys (hero.headline, pricing.tiers.0.title) with per-language values. One bulk endpoint feeds your build process.
  • Image keysdata-image-key="hero.background" on an <img>. The customer can swap the image in the admin; your build resolves the URL.
  • Brand context — voice, colors, fonts, audience exposed as a single resource. Read once at build time, or hot-fetch per request.
  • Register-component — turn AI-generated HTML into an admin-editable section in one call, with data-translate keys auto-discovered.

Quick example

Read a single key, then upsert one. The SDK exposes both as one-liners.
Bulk read response shape:
Seed many keys at once with bulkCreate (idempotent — existing keys are skipped, not failed):
CMS writes cost 1 credit each. PUT /v1/content/{key} (content_update), POST/PATCH /v1/pages (page_update), and registering an image via URL swap on PUT /v1/images/{key} or multipart upload on POST /v1/images (image_register) each consume 1 credit on success. AI generation (image, translation, blog, website) is metered separately at its own rate. Reads (GET) remain free. See pricing.

Common workflows

1. Build-time fetch for SSG

Static-site generators (Next.js, Astro, Nuxt, Hugo) call /v1/content/bulk once per locale at build time. Cache the response — re-fetch only when the content.changed webhook fires.

2. Click-to-edit overlay on a live site

Drop a tiny JS snippet into your HTML. It looks for data-translate attributes and turns them into inline-editable fields when the user is signed into the admin in the same browser.
The overlay calls /v1/content/{key} on save. Same backend, no rebuild.

3. AI registers a generated section

When the AI in your editor generates a hero, it calls register_component(html, intent) via MCP. The component appears in your admin instantly:
The admin auto-discovers hero.headline as an editable text field. No schema work.

4. Translate a key into N languages

SDK
cURL
Returns a Job reference. Poll /v1/jobs/{id} (or nd.jobs.poll(id)) until terminal, or subscribe to the content.changed webhook to get notified once each language lands. Charges 7 credits per target language (translate_language).

5. Brand context for AI prompts

Read brand once, pass it into your AI calls. The MCP server does this for you; if you’re calling the API directly:
SDK
cURL

Conventions

The two attributes the AI uses everywhere:
Keys are case-sensitive, dot-namespaced, and lowercase by convention. Index keys for arrays follow section.field.0.subfield.

Per-page SEO meta

Search engines and social cards need per-route metadata — <title>, <meta name=description>, and the og:* tags. Neural Draft stores this on the page itself so each route can have its own values without polluting the translation-key namespace. There are two surfaces depending on what kind of content you’re rendering:

CMS-managed pages — GET /v1/pages/{slug}

For everything that isn’t a blog post (homepage, about, services, legal, landing pages…), fetch the Page resource at build time and use the meta fields directly. Every field is nullable; an empty meta_title means the page title is used as the document title.
Use nd.pages.update(id, { meta_title: null }) (or pass null via cURL) to clear a single meta field. Untouched fields are preserved — the API merges the patch into the existing record.

Blog posts — GET /v1/blog-posts/{slug}

Posts have their own per-translation meta. The locale-aware response picks the matching translation for meta_title / meta_description. Use featured_image for og:image (it’s the canonical image associated with the post).
To patch SEO meta on a post (e.g. tighten the description after publish):

Where to put what in your <head>

For a blog post the same template applies, swapping page.og_image with post.featured_image.

Images

Three flavours, all routing through the same Image resource:
Both upload() and replaceFile() accept a Web File/Blob (browser, Bun, Node 20+) or a Node Buffer/Uint8Array. For raw buffers, supply opts.filename so the server can derive the file extension.

Reference

Forms — newsletter & contact

Most AI-built sites need two simple capture surfaces: an email-collector for newsletters and a free-form contact form. Neural Draft ships both as first-class endpoints — no schemas to design, no spam-handling glue, and free (no credits charged, since these are storage + delivery, not AI).

Public submit

The submit endpoints are public. Authenticate the project with a server-side API key in X-NeuralDraft-Project-Key (or pass ?project_id= for unauthenticated client-side embeds where you don’t want to ship a key):

Reading submissions

Form submissions are not in the outgoing-webhook event whitelist today — poll the admin list endpoints (GET /v1/newsletters, GET /v1/contact-forms) or use the MCP tools list_newsletter_subscribers / list_contact_form_submissions to inspect what came in. We may add newsletter.subscribed / contact_form.submitted topics to the webhook whitelist in a future release; subscribe to the changelog if you’d like to be notified.

Admin list & delete

Listing and deleting submissions requires an API key with forms:read / forms:write scope (or *). Both list endpoints support ?page / ?page_size (max 200) and ?search=; the newsletter list also accepts ?app_lead=true to filter out trial leads from your real subscriber list.