WrytzeWrytze Docs
API Reference

Blogs

Fetch published blog posts from your Wrytze workspace.

The Blogs endpoints let you retrieve published blog posts from your Wrytze workspace. Use them to display blog content on your website, build a headless blog, or integrate with third-party platforms.

List blogs

GET /api/v1/blogs

Returns a paginated list of published blogs for your organization. Results are ordered by publish date (newest first).

Parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number
limitintegerNo20Results per page (max: 100)
categorystringNo--Filter by category slug
tagstringNo--Filter by tag slug
searchstringNo--Search by title (case-insensitive)
website_idstringNo--Filter to a specific website

Response

Returns an array of blog objects wrapped in data, with a pagination object.

List responses do not include the contentHtml field. Use the Get blog by ID or Get blog by slug endpoints to retrieve the full HTML content.

Cache TTL: 5 minutes.

Examples

curl "https://app.wrytze.com/api/v1/blogs?page=1&limit=10&category=engineering" \
  -H "X-API-Key: wrz_sk_abc123..."
import { WrytzeClient } from "@wrytze/sdk";

const client = new WrytzeClient({ apiKey: "wrz_sk_abc123..." });

const { data, pagination } = await client.blogs.list({
  page: 1,
  limit: 10,
  category: "engineering",
});

console.log(`Found ${pagination.total} blogs`);
for (const blog of data) {
  console.log(blog.title);
}
const response = await fetch(
  "https://app.wrytze.com/api/v1/blogs?page=1&limit=10&category=engineering",
  {
    headers: {
      "X-API-Key": "wrz_sk_abc123...",
    },
  }
);

const { data, pagination } = await response.json();

console.log(`Found ${pagination.total} blogs`);
for (const blog of data) {
  console.log(blog.title);
}

Response example

{
  "data": [
    {
      "id": "cm5abc123def456",
      "title": "Building a Modern Blog with Wrytze",
      "slug": "building-a-modern-blog-with-wrytze",
      "excerpt": "Learn how to set up a headless blog using the Wrytze API and Next.js.",
      "metaTitle": "Building a Modern Blog with Wrytze | Acme Inc.",
      "metaDescription": "Step-by-step guide to building a headless blog with Wrytze API.",
      "featuredImageUrl": "https://cdn.wrytze.com/images/blog-hero.jpg",
      "featuredImageAlt": "A developer working on a blog layout",
      "wordCount": 1450,
      "readingTimeMinutes": 6,
      "publishedAt": "2026-02-15T10:30:00.000Z",
      "websiteId": "ws_abc123",
      "categories": [
        { "name": "Engineering", "slug": "engineering" }
      ],
      "tags": [
        { "name": "Next.js", "slug": "nextjs" },
        { "name": "Tutorial", "slug": "tutorial" }
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 42,
    "pages": 5
  }
}

Get blog by ID

GET /api/v1/blogs/:id

Returns a single published blog by its unique ID, including the full HTML content.

Parameters

ParameterTypeRequiredDescription
idstringYesThe blog's unique ID (path parameter)

Response

Returns a single blog object wrapped in data, including the contentHtml field with the full blog content as HTML.

Cache TTL: 15 minutes.

Examples

curl "https://app.wrytze.com/api/v1/blogs/cm5abc123def456" \
  -H "X-API-Key: wrz_sk_abc123..."
import { WrytzeClient } from "@wrytze/sdk";

const client = new WrytzeClient({ apiKey: "wrz_sk_abc123..." });

const { data } = await client.blogs.get("cm5abc123def456");

console.log(data.title);
console.log(data.contentHtml); // Full HTML content
const response = await fetch(
  "https://app.wrytze.com/api/v1/blogs/cm5abc123def456",
  {
    headers: {
      "X-API-Key": "wrz_sk_abc123...",
    },
  }
);

const { data } = await response.json();

console.log(data.title);
console.log(data.contentHtml); // Full HTML content

Response example

{
  "data": {
    "id": "cm5abc123def456",
    "title": "Building a Modern Blog with Wrytze",
    "slug": "building-a-modern-blog-with-wrytze",
    "excerpt": "Learn how to set up a headless blog using the Wrytze API and Next.js.",
    "metaTitle": "Building a Modern Blog with Wrytze | Acme Inc.",
    "metaDescription": "Step-by-step guide to building a headless blog with Wrytze API.",
    "contentHtml": "<h2>Introduction</h2><p>In this guide, we will walk through...</p>",
    "featuredImageUrl": "https://cdn.wrytze.com/images/blog-hero.jpg",
    "featuredImageAlt": "A developer working on a blog layout",
    "wordCount": 1450,
    "readingTimeMinutes": 6,
    "publishedAt": "2026-02-15T10:30:00.000Z",
    "websiteId": "ws_abc123",
    "categories": [
      { "id": "cat_abc123", "name": "Engineering", "slug": "engineering" }
    ],
    "tags": [
      { "id": "tag_abc123", "name": "Next.js", "slug": "nextjs" },
      { "id": "tag_def456", "name": "Tutorial", "slug": "tutorial" }
    ]
  }
}

Get blog by slug

GET /api/v1/blogs/slug/:slug

Returns a single published blog by its URL-friendly slug, including the full HTML content. Since slugs are unique per website (not globally), the website_id query parameter is required.

Parameters

ParameterTypeRequiredDescription
slugstringYesThe blog's URL-friendly slug (path parameter)
website_idstringYesThe website ID to look up the blog in (query parameter)

The website_id query parameter is required for this endpoint. Slugs are unique within a website but may be duplicated across websites in the same organization.

Response

Returns a single blog object wrapped in data, including the contentHtml field.

Cache TTL: 15 minutes.

Examples

curl "https://app.wrytze.com/api/v1/blogs/slug/building-a-modern-blog-with-wrytze?website_id=ws_abc123" \
  -H "X-API-Key: wrz_sk_abc123..."
import { WrytzeClient } from "@wrytze/sdk";

const client = new WrytzeClient({ apiKey: "wrz_sk_abc123..." });

const { data } = await client.blogs.getBySlug(
  "building-a-modern-blog-with-wrytze",
  { websiteId: "ws_abc123" }
);

console.log(data.title);
console.log(data.contentHtml);
const response = await fetch(
  "https://app.wrytze.com/api/v1/blogs/slug/building-a-modern-blog-with-wrytze?website_id=ws_abc123",
  {
    headers: {
      "X-API-Key": "wrz_sk_abc123...",
    },
  }
);

const { data } = await response.json();

console.log(data.title);
console.log(data.contentHtml);

Response example

{
  "data": {
    "id": "cm5abc123def456",
    "title": "Building a Modern Blog with Wrytze",
    "slug": "building-a-modern-blog-with-wrytze",
    "excerpt": "Learn how to set up a headless blog using the Wrytze API and Next.js.",
    "metaTitle": "Building a Modern Blog with Wrytze | Acme Inc.",
    "metaDescription": "Step-by-step guide to building a headless blog with Wrytze API.",
    "contentHtml": "<h2>Introduction</h2><p>In this guide, we will walk through...</p>",
    "featuredImageUrl": "https://cdn.wrytze.com/images/blog-hero.jpg",
    "featuredImageAlt": "A developer working on a blog layout",
    "wordCount": 1450,
    "readingTimeMinutes": 6,
    "publishedAt": "2026-02-15T10:30:00.000Z",
    "websiteId": "ws_abc123",
    "categories": [
      { "id": "cat_abc123", "name": "Engineering", "slug": "engineering" }
    ],
    "tags": [
      { "id": "tag_abc123", "name": "Next.js", "slug": "nextjs" },
      { "id": "tag_def456", "name": "Tutorial", "slug": "tutorial" }
    ]
  }
}

TypeScript Interfaces

Use these interfaces when working with Wrytze API responses in TypeScript:

// Returned in list responses (no contentHtml)
interface Blog {
  id: string;
  title: string;
  slug: string;
  excerpt: string | null;
  metaTitle: string | null;
  metaDescription: string | null;
  featuredImageUrl: string | null;
  featuredImageAlt: string | null;
  wordCount: number;
  readingTimeMinutes: number;
  publishedAt: string;
  websiteId: string;
  categories: { name: string; slug: string }[];
  tags: { name: string; slug: string }[];
}

// Returned in single-resource responses (includes contentHtml)
// Categories and tags also include the `id` field
interface BlogDetail extends Omit<Blog, "categories" | "tags"> {
  contentHtml: string;
  categories: { id: string; name: string; slug: string }[];
  tags: { id: string; name: string; slug: string }[];
}

// List response envelope
interface BlogListResponse {
  data: Blog[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    pages: number;
  };
}

// Single resource response envelope
interface BlogDetailResponse {
  data: BlogDetail;
}

On this page