> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dottxt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Generation

> Generate marketing or product copy in a strict, publishable structure.

Content generation without structure produces a blob of text that someone has to manually split into headline, body, and a call to action (CTA). If the model writes a 200-character headline, your page layout breaks. If it forgets the call to action, your marketing page has no conversion path. If the tone drifts from professional to casual mid-paragraph, the brand voice is inconsistent.

Wrapping content generation in a schema solves all of this. Each section becomes a separate field with its own length bounds. Tone becomes an enum, not a suggestion. The CTA is a required object with a label and URL. The model fills in the creative content while the schema enforces the structural and editorial constraints.

## Goal

Generate a product launch blurb with a headline, subheadline, key points, call to action (CTA), and tone, all bounded and validated for direct web publishing.

## Schema contract

<CodeGroup>
  ```json JSON Schema theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "type": "object",
    "properties": {
      "headline": { "type": "string", "minLength": 15, "maxLength": 80 },
      "subheadline": { "type": "string", "minLength": 25, "maxLength": 140 },
      "key_points": {
        "type": "array",
        "minItems": 3,
        "maxItems": 5,
        "items": { "type": "string", "minLength": 20, "maxLength": 140 }
      },
      "cta": {
        "type": "object",
        "properties": {
          "label": { "type": "string", "minLength": 2, "maxLength": 24 },
          "url": { "type": "string", "pattern": "^https://" }
        },
        "required": ["label", "url"],
        "additionalProperties": false
      },
      "tone": { "type": "string", "enum": ["professional", "friendly", "technical"] }
    },
    "required": ["headline", "subheadline", "key_points", "cta", "tone"],
    "additionalProperties": false
  }
  ```

  ```python Pydantic theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  from typing import Annotated, Literal
  from pydantic import BaseModel, ConfigDict, Field

  KeyPoint = Annotated[str, Field(min_length=20, max_length=140)]

  class Cta(BaseModel):
      model_config = ConfigDict(extra="forbid")
      label: str = Field(..., min_length=2, max_length=24)
      url: str = Field(..., pattern=r"^https://")

  class ContentPayload(BaseModel):
      model_config = ConfigDict(extra="forbid")
      headline: str = Field(..., min_length=15, max_length=80)
      subheadline: str = Field(..., min_length=25, max_length=140)
      key_points: list[KeyPoint] = Field(..., min_length=3, max_length=5)
      cta: Cta
      tone: Literal["professional", "friendly", "technical"]
  ```

  ```typescript Zod theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  import { z } from "zod";

  const contentPayloadSchema = z.object({
    headline: z.string().min(15).max(80),
    subheadline: z.string().min(25).max(140),
    key_points: z.array(z.string().min(20).max(140)).min(3).max(5),
    cta: z.object({
      label: z.string().min(2).max(24),
      url: z.string().regex(/^https:\/\//),
    }).strict(),
    tone: z.enum(["professional", "friendly", "technical"]),
  }).strict();
  ```

  ```bash curl theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  curl https://api.dottxt.ai/v1/chat/completions \
    -H "Authorization: Bearer $DOTTXT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-oss-20b",
      "messages": [{ "role": "user", "content": "Announce a new schema audit service for engineering teams.\nTone should be professional and concrete." }],
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "content_payload",
          "schema": {
            "type": "object",
            "properties": {
              "headline": { "type": "string", "minLength": 15, "maxLength": 80 },
              "subheadline": { "type": "string", "minLength": 25, "maxLength": 140 },
              "key_points": {
                "type": "array",
                "minItems": 3,
                "maxItems": 5,
                "items": { "type": "string", "minLength": 20, "maxLength": 140 }
              },
              "cta": {
                "type": "object",
                "properties": {
                  "label": { "type": "string", "minLength": 2, "maxLength": 24 },
                  "url": { "type": "string", "pattern": "^https://" }
                },
                "required": ["label", "url"],
                "additionalProperties": false
              },
              "tone": { "type": "string", "enum": ["professional", "friendly", "technical"] }
            },
            "required": ["headline", "subheadline", "key_points", "cta", "tone"],
            "additionalProperties": false
          }
        }
      }
    }'
  ```
</CodeGroup>

## Example input

```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
Announce a new schema audit service for engineering teams.
Tone should be professional and concrete.
```

## Example output

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "headline": "Ship More Reliable Structured Outputs With Schema Audit",
  "subheadline": "Get a concrete review of your JSON Schema constraints, failure modes, and production readiness before rollout.",
  "key_points": [
    "Identify underconstrained fields that lead to invalid or noisy model output.",
    "Receive practical schema rewrites tied to your real production use cases.",
    "Validate compatibility and behavior before launching high-volume workflows."
  ],
  "cta": {
    "label": "Start Schema Audit",
    "url": "https://example.com/audit"
  },
  "tone": "professional"
}
```

## Implementation tips

* **Tone enum controls voice.** `"professional"`, `"friendly"`, `"technical"`: the model adopts the specified style without you embedding tone instructions in the prompt. Add or remove values as your brand guidelines evolve.
* **Length bounds match your layout.** The headline is capped at 80 characters (fits a single line on desktop), the subheadline at 140 (fits two lines), and key points at 140 each. These bounds should come from your actual CSS/layout constraints.
* **Key points array is bounded.** `minItems: 3` ensures enough substance for a marketing page. `maxItems: 5` prevents the model from listing fifteen points that nobody reads.
* **CTA is required and structured.** The `cta` object guarantees every generated blurb has a clear action. The `pattern: "^https://"` on `url` prevents relative paths, `mailto:` links, or other formats your publishing system doesn't support.
* **Human review is still needed.** The schema handles structure and bounds, but brand voice, factual accuracy, and legal compliance still need human eyes. Schema-constrained output makes this review faster because the structure is predictable.

## Related docs

* [String bounds](/json-schema/string-bounds): control minLength, maxLength, pattern, and format on text fields
* [Bounded arrays](/json-schema/bounded-arrays): set min/max item counts on key points, bullet lists, etc.
* [Enum with fallback](/json-schema/enum-with-fallback): extend tone or category enums with an escape hatch
* [String reference](/json-schema/reference/string) | [Object reference](/json-schema/reference/object)
