Assistant Blog API

This endpoint lets ChatGPT, Claude, Claude cowork, or another assistant create blog drafts, scheduled posts, or published posts through the hosted Netlify site. It can also upload blog images into the same Netlify Blob image library used by the admin portal.

Endpoint

POST https://www.thedetourgym.com/api/assistant/blogs

A schema/help response is available at:

GET https://www.thedetourgym.com/api/assistant/blogs/schema

Required Netlify environment variable

Set this in Netlify before using the endpoint:

ASSISTANT_BLOG_API_KEY=<a long random secret>

Never put the secret in the repo or front-end code.

Optional extra hardening for remote image URLs:

ASSISTANT_IMAGE_ALLOWED_HOSTS=example.com,images.examplecdn.com

If this optional allowlist is set, remote sourceUrl images are accepted only from those hostnames or their subdomains.

Authentication

Use either header:

Authorization: Bearer <ASSISTANT_BLOG_API_KEY>

or:

X-Detour-Assistant-Key: <ASSISTANT_BLOG_API_KEY>

The endpoint uses constant-time secret comparison and returns 401 Unauthorized for invalid keys. It also has a simple per-client rate limit of 30 POST requests per hour.

Request body

{
  "title": "SEO title under 60 characters",
  "headline": "Display headline",
  "slug": "optional-url-slug",
  "description": "Meta description under 155 characters",
  "author": "Matthew Arnold",
  "categories": ["Training Tips"],
  "keywords": "comma-separated SEO keywords",
  "image": "",
  "imageUpload": {
    "filename": "featured-image.webp",
    "contentType": "image/webp",
    "base64": "base64 image bytes without data URL prefix",
    "dataUrl": "or data:image/webp;base64,...",
    "sourceUrl": "or approved public HTTPS image URL",
    "alt": "Featured image alt text",
    "featured": true
  },
  "images": [
    {
      "filename": "inline-image.webp",
      "sourceUrl": "https://example.com/image.webp",
      "alt": "Inline image alt text",
      "placeholder": ""
    }
  ],
  "status": "draft",
  "publishAt": "2026-07-01T09:00:00-05:00",
  "content": "Markdown blog content. Use  where an uploaded inline image should appear."
}

status can be:

Image upload behavior

Images are uploaded into the existing Netlify Blob image library and served back from /api/images/<key>.

Supported input forms:

Featured image behavior:

Inline image behavior:

CTA rules for assistants

Use these rules whenever generating posts:

Example curl with image URL upload

curl -X POST "https://www.thedetourgym.com/api/assistant/blogs" \
  -H "Authorization: Bearer $ASSISTANT_BLOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Best Gym for Beginners in Rochester MN",
    "headline": "How to Start at a Gym in Rochester MN",
    "slug": "gym-for-beginners-rochester-mn-guide",
    "description": "A beginner-friendly guide to starting at a Rochester MN gym with coaching, structure, and a free first class.",
    "author": "Matthew Arnold",
    "categories": ["Training Tips", "Rochester MN"],
    "keywords": "gym for beginners Rochester MN, beginner gym Rochester MN",
    "status": "draft",
    "imageUpload": {
      "sourceUrl": "https://example.com/featured.webp",
      "filename": "beginner-gym-rochester.webp",
      "alt": "Beginner-friendly group fitness class at The Detour Gym",
      "featured": true
    },
    "images": [
      {
        "sourceUrl": "https://example.com/coach-demo.webp",
        "filename": "coach-demo.webp",
        "alt": "Coach helping a new member learn movement technique",
        "placeholder": ""
      }
    ],
    "content": "# How to Start at a Gym in Rochester MN\n\nIntro paragraph...\n\n\n\nMore blog content..."
  }'

Prompt for ChatGPT or Claude

Create a blog post for The Detour Gym and send it to this API as JSON.

Endpoint: https://www.thedetourgym.com/api/assistant/blogs
Auth header: Authorization: Bearer <secret>

Return or POST this JSON shape:
{
  "title": "SEO title under 60 characters",
  "headline": "Display headline",
  "slug": "url-slug-with-no-leading-slash",
  "description": "Meta description under 155 characters",
  "author": "Matthew Arnold",
  "categories": ["Training Tips"],
  "keywords": "comma-separated SEO keywords",
  "image": "",
  "imageUpload": {
    "sourceUrl": "approved public HTTPS image URL, or omit this and use base64/dataUrl",
    "filename": "featured-image.webp",
    "alt": "Descriptive featured image alt text",
    "featured": true
  },
  "images": [
    {
      "sourceUrl": "approved public HTTPS image URL, or base64/dataUrl",
      "filename": "inline-image.webp",
      "alt": "Descriptive inline image alt text",
      "placeholder": ""
    }
  ],
  "status": "draft",
  "publishAt": "YYYY-MM-DDTHH:MM:SS-05:00",
  "content": "Markdown blog post. Use  where the inline image should be inserted."
}

Rules:
- Keep claims accurate and local to Rochester, MN.
- Do not imply affiliation with Mayo Clinic, CrossFit, or other businesses unless explicitly stated.
- Free class / intro / getting started links go to /getting-started/.
- Drop-in purchase links go to https://detour.wodify.com/OnlineSalesPage/Main?q=Memberships.
- Contact/call/directions links go to /contact/.