blawgy-com Refresh API
Refresh requests for existing pages (sites with existing-content checks on).
Refresh requests for existing pages (sites with existing-content checks on).
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/blawgy-com:blawgy-com-refresh-api"
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.
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: 3.2.0
info:
title: Blawgy Refresh 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: Refresh
description: Refresh requests for existing pages (sites with existing-content checks on).
paths:
/sites/{site}/refresh:
post:
operationId: request_refresh
summary: Refresh a page that covers a keyword
description: 'Refresh one of the site''s pages to cover a keyword it already owns, instead of writing a new article that would compete with it (for a keyword get_keywords or keyword research shows as covered by a page). Give the keyword and the page as url (or blogId for an article Blawgy wrote, or sitePageId from list_existing_pages). The refresh is accepted at once: an article Blawgy wrote gets a smart-update draft that waits for review in Updates (Pro+), any other page gets its update brief (read it with get_refresh_brief). A page that already has a refresh on the plan returns that refresh with the keyword added. Does not use a posts-per-week slot.'
tags:
- Refresh
x-mcp-tool: request_refresh
x-access: write
x-min-plan: null
x-partner-only: false
security:
- bearerAuth: []
parameters:
- name: site
in: path
required: true
schema:
type: string
minLength: 1
description: The site, as its domain (example.com). See GET /sites.
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/DryRun'
responses:
'200':
description: The result, exactly what the matching MCP tool returns.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Idempotent-Replayed:
$ref: '#/components/headers/Idempotent-Replayed'
content:
application/json:
schema:
oneOf:
- type: object
additionalProperties: true
- type: object
description: 'With ?dryRun=true: every gate passed, nothing ran.'
properties:
dryRun:
type: boolean
const: true
tool:
type: string
summary:
type: string
valid:
type: boolean
required:
- dryRun
- summary
- valid
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'402':
$ref: '#/components/responses/402'
'403':
$ref: '#/components/responses/403'
'404':
$ref: '#/components/responses/404'
'409':
$ref: '#/components/responses/409'
'422':
$ref: '#/components/responses/422'
'429':
$ref: '#/components/responses/429'
'500':
$ref: '#/components/responses/500'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
keyword:
type: string
minLength: 1
maxLength: 200
description: The keyword the page should also cover
url:
type: string
minLength: 1
maxLength: 2048
description: Full URL of the page on this site
blogId:
type: string
minLength: 1
maxLength: 64
description: Article id, for a page written by Blawgy
sitePageId:
type: string
minLength: 1
maxLength: 64
description: Existing page id from list_existing_pages
required:
- keyword
additionalProperties: false
/sites/{site}/refresh/{refreshId}/brief:
get:
operationId: get_refresh_brief
summary: Get a page refresh brief
description: 'The update brief for a refresh of a page Blawgy did not write (refreshOwnerKind "page" in get_plan suggestions): a summary, the steps to change on the page, the searches to work in (keywordsToAdd) and what to keep. It is written only from the page itself and its Search Console searches, so apply it on the page in the site''s own CMS. Works once the refresh is accepted (accept_plan_suggestion) or when it fills an open slot; returns not_accepted for a refresh that is only suggested, and blawgy_post for a page Blawgy wrote (that refresh is a smart update, see list_update_opportunities). Call mark_refresh_done after the page is updated.'
tags:
- Refresh
x-mcp-tool: get_refresh_brief
x-access: read
x-min-plan: null
x-partner-only: false
security:
- bearerAuth: []
parameters:
- name: site
in: path
required: true
schema:
type: string
minLength: 1
description: The site, as its domain (example.com). See GET /sites.
- name: refreshId
in: path
required: true
schema:
type: string
minLength: 1
description: The refresh row id (suggestionId / refreshId in get_plan)
responses:
'200':
description: The result, exactly what the matching MCP tool returns.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
content:
application/json:
schema:
type: object
additionalProperties: true
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'404':
$ref: '#/components/responses/404'
'429':
$ref: '#/components/responses/429'
'500':
$ref: '#/components/responses/500'
/sites/{site}/refresh/{refreshId}/done:
post:
operationId: mark_refresh_done
summary: Mark a page refresh as done
description: Tell Blawgy the page in a refresh was updated (the dashboard's "I updated the page"). The refresh is marked done and Blawgy re-checks how the page ranks two weeks later. Only for an accepted refresh. Safe to call twice.
tags:
- Refresh
x-mcp-tool: mark_refresh_done
x-access: write
x-min-plan: null
x-partner-only: false
security:
- bearerAuth: []
parameters:
- name: site
in: path
required: true
schema:
type: string
minLength: 1
description: The site, as its domain (example.com). See GET /sites.
- name: refreshId
in: path
required: true
schema:
type: string
minLength: 1
description: The refresh row id (suggestionId / refreshId in get_plan)
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/DryRun'
responses:
'200':
description: The result, exactly what the matching MCP tool returns.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Idempotent-Replayed:
$ref: '#/components/headers/Idempotent-Replayed'
content:
application/json:
schema:
oneOf:
- type: object
additionalProperties: true
- type: object
description: 'With ?dryRun=true: every gate passed, nothing ran.'
properties:
dryRun:
type: boolean
const: true
tool:
type: string
summary:
type: string
valid:
type: boolean
required:
- dryRun
- summary
- valid
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'402':
$ref: '#/components/responses/402'
'403':
$ref: '#/components/responses/403'
'404':
$ref: '#/components/responses/404'
'409':
$ref: '#/components/responses/409'
'422':
$ref: '#/components/responses/422'
'429':
$ref: '#/components/responses/429'
'500':
$ref: '#/components/responses/500'
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'
'422':
description: '`idempotency_key_reused`: the Idempotency-Key was used for a different request.'
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The site is read-only until its billing is sorted out.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: The bearer token is missing, unknown, expired or revoked.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Something failed on our side. The `requestId` finds it in our logs.
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: Conflict, including `idempotency_in_progress` and `idempotency_secret_not_replayable` (a retry of a call that returned a one-time secret).
headers:
Request-Id:
$ref: '#/components/headers/Request-Id'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: 'The credential may not do this: read-only key, wrong scope, plan too low (`upgrade_required`), owner only.'
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'
parameters:
IdempotencyKey:
name: Idempotency-Key
in: header
required: false
schema:
type: string
maxLength: 255
description: Any unique string (a UUID works). A retry with the same key and request inside 24 hours replays the stored answer instead of running again.
DryRun:
name: dryRun
in: query
required: false
schema:
type: boolean
description: 'true: run every gate and validation, return a summary, change nothing.'
headers:
Request-Id:
schema:
type: string
description: Identifies this request in our logs and audit trail. Quote it to support.
RateLimit-Remaining:
schema:
type: integer
description: Calls left in the current window.
RateLimit-Reset:
schema:
type: integer
description: Seconds until the window resets.
Idempotent-Replayed:
schema:
type: boolean
description: true when this answer was replayed from an earlier request with the same Idempotency-Key.
RateLimit-Limit:
schema:
type: integer
description: Calls allowed in the current window.
schemas:
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.