blawgy-com Public content API

Published posts for headless frontends and static builds. No key; callable from browsers; cacheable.

Operations 2

GET /public/sites/{site}/posts List published posts #
GET /public/sites/{site}/posts/{slugOrId} Get a published post #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/blawgy-com:blawgy-com-public-content-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

blawgy-com-public-content-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Blawgy Public content API
  version: 1.0.0
  description: 'The Blawgy API: everything the Blawgy dashboard and MCP server can do, over HTTPS. Every endpoint is also an MCP tool (`x-mcp-tool`); both transports share keys, site scoping, plan gating, rate limits and the audit log.


    **Authentication.** `Authorization: Bearer blk_live_...` with an API key from Settings > Account > AI agents in the Blawgy dashboard (or an OAuth access token issued for this host). Keys are server-side only: there is no CORS on /v1, except the keyless public content endpoints under `/public`.


    **Arguments.** GET endpoints take theirs as query parameters; POST, PATCH, PUT and DELETE take a JSON body (`Content-Type: application/json`), and their query string carries only `dryRun`. Unknown arguments are a 400, never silently dropped.


    **Errors.** Every non-2xx answer is `{ "error": { "code", "message", "details"?, "requestId" } }`. Every response carries `Request-Id`.


    **Pagination.** Lists answer `{ data, nextCursor, total? }` and take `?limit=` and `?cursor=` (the previous page''s `nextCursor`). `limit` is capped per endpoint (never above 200); a larger value is clamped to the cap.


    **Idempotency.** Send `Idempotency-Key` on POST, PATCH, PUT or DELETE to make a retry safe for 24 hours: the same key and request replays the stored answer (`Idempotent-Replayed: true`); the same key with a different request is a 422.


    **Dry runs.** `?dryRun=true` on any write runs every gate (auth, scope, plan, validation) and returns a one-line summary without doing anything.


    **Rate limits.** 240 calls a minute and 6,000 a day per key, shared with MCP. Responses carry `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`; a 429 adds `Retry-After`. The public content endpoints need no key and are limited per client IP instead.


    **Async work.** Research, writing, scans and syncs return as soon as the job is queued; poll `GET /sites/{site}/jobs/{kind}`.


    **Versioning.** `/v1` is frozen for breaking changes; additive changes ship freely.'
  termsOfService: https://blawgy.com/terms
  contact:
    url: https://blawgy.com/developers
servers:
- url: https://app.blawgy.com/v1
security:
- bearerAuth: []
tags:
- name: Public content
  description: Published posts for headless frontends and static builds. No key; callable from browsers; cacheable.
paths:
  /public/sites/{site}/posts:
    get:
      operationId: list_public_posts
      summary: List published posts
      description: 'Published posts on a Blawgy site, newest first, 20 a page. Each slug appears once (its freshest version); drafts, scheduled and held articles never appear. Bodies are left out unless `include=content`. No key: the content is public, so a browser may call it directly (CORS for any origin, no credentials). Answers carry a weak `ETag`; send it back as `If-None-Match` and an unchanged answer is a 304 with no body. `Cache-Control: public, max-age=60, stale-while-revalidate=300`. Rate limited per client IP (a 429 says when to retry in `Retry-After`).'
      tags:
      - Public content
      security: []
      x-paged: true
      parameters:
      - name: site
        in: path
        required: true
        schema:
          type: string
        description: The site, as its domain (example.com).
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
        description: 'Posts per page: 20 by default, at most 100 (50 with include=content). Values above the maximum are clamped to it.'
      - name: cursor
        in: query
        required: false
        schema:
          type: string
        description: The previous page's nextCursor.
      - name: include
        in: query
        required: false
        schema:
          type: string
          enum:
          - content
        description: 'content: add blogContent and articleSummary to every post.'
      responses:
        '200':
          description: A page of published posts.
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
          content:
            application/json:
              schema:
                type: object
                description: One page. Pass nextCursor as ?cursor= for the next one; null means this was the last page.
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/PublicPost'
                  nextCursor:
                    type:
                    - string
                    - 'null'
                  total:
                    type: integer
                    description: Published posts on the site (each slug once).
                required:
                - data
                - nextCursor
                - total
        '304':
          description: 'Not modified: the copy you hold (If-None-Match) is current. No body.'
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
        '400':
          $ref: '#/components/responses/400'
        '404':
          $ref: '#/components/responses/404'
        '429':
          $ref: '#/components/responses/429'
  /public/sites/{site}/posts/{slugOrId}:
    get:
      operationId: get_public_post
      summary: Get a published post
      description: 'One published post on a Blawgy site by its slug (the freshest version, the one the list shows) or its id, with its body. No key: the content is public, so a browser may call it directly (CORS for any origin, no credentials). Answers carry a weak `ETag`; send it back as `If-None-Match` and an unchanged answer is a 304 with no body. `Cache-Control: public, max-age=60, stale-while-revalidate=300`. Rate limited per client IP (a 429 says when to retry in `Retry-After`).'
      tags:
      - Public content
      security: []
      parameters:
      - name: site
        in: path
        required: true
        schema:
          type: string
        description: The site, as its domain (example.com).
      - name: slugOrId
        in: path
        required: true
        schema:
          type: string
        description: The post's slug, or its id.
      responses:
        '200':
          description: The post.
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicPost'
        '304':
          description: 'Not modified: the copy you hold (If-None-Match) is current. No body.'
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
        '400':
          $ref: '#/components/responses/400'
        '404':
          $ref: '#/components/responses/404'
        '429':
          $ref: '#/components/responses/429'
components:
  responses:
    '429':
      description: Rate limited; `Retry-After` says when to try again.
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '404':
      description: 'Not found: the route, the site (`site_not_found`) or the thing inside it.'
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '400':
      description: The request is malformed or the arguments failed validation (`details.issues` lists them).
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    Request-Id:
      schema:
        type: string
      description: Identifies this request in our logs and audit trail. Quote it to support.
    Cache-Control:
      schema:
        type: string
      description: 'How long a browser or CDN may reuse the answer (public content: `public, max-age=60, stale-while-revalidate=300`).'
    ETag:
      schema:
        type: string
      description: A weak validator for this answer (public content). Send it back as If-None-Match.
  schemas:
    PublicPost:
      type: object
      description: A published post. Fields without a value are left out.
      required:
      - id
      properties:
        id:
          type: string
          description: The post id. Works as {slugOrId}.
        title:
          type: string
        blogTitle:
          type: string
          description: The title as written on the article.
        slug:
          type: string
        blogContent:
          type: string
          description: The article body (HTML). On the list only with include=content.
        articleSummary:
          type: string
          description: A short summary of the article. On the list only with include=content.
        metaDescription:
          type: string
        metaKeywords:
          type: string
        keywords:
          description: The keywords the article targets (usually an array of strings).
        resources:
          description: Sources and references the article cites.
        imageUrl:
          type: string
          description: The featured image.
        imageDescription:
          type: string
          description: Alt text for the featured image.
        publishDate:
          type: string
          format: date-time
        lastUpdated:
          type: string
          format: date-time
          description: When the content last changed.
        published:
          type: boolean
        blogStatus:
          type: string
          enum:
          - published
        category:
          type: string
        url:
          type: string
          description: The live URL, once known.
        publishedUrl:
          type: string
          description: Same as url.
      additionalProperties: false
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          - requestId
          properties:
            code:
              type: string
              description: Stable machine-readable reason (site_not_found, invalid_request, upgrade_required, rate_limited, ...).
            message:
              type: string
            details:
              type: object
              additionalProperties: true
              description: 'Extra context; validation errors carry `issues: [{ path, code, message }]`.'
            requestId:
              type: string
              description: Same as the Request-Id header.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: blk_live_... API key or OAuth access token
      description: An API key from Settings > Account > AI agents in the Blawgy dashboard. Read keys may only call GET endpoints; keys scoped to specific sites cannot reach other sites or change the account.