Skip to content
All pages
Developers · v1

API reference

Every article Mastheads writes for you is yours to take anywhere. The API hands your source-backed articles - full HTML, cover picture, byline and search details - to your own website, app or automation, on your schedule. With a full-access key, your own code can also commission articles, research reports and site audits, and publish a finished article to your site.

On this page
Base URLhttps://api.mastheads.app

What you can build

Sync articles into your own site

Pull every article - full HTML, cover picture, byline and search title - into your own website, app or database on a schedule. Mastheads writes and checks; your front end shows.

Commission work from your own tools

With a full-access key, your code can start an article or a batch of up to 100, a research report or a site audit, and publish a finished article to your connected site.

Connect an AI assistant

Claude, ChatGPT, Codex, Cursor and other MCP clients can read your articles - and ask what backs each one: its sources, what each desk recorded, and the editor of record.

Before you start

  • A Growth or Pro plan. The API is included on both, at no extra charge. See Plans.
  • A key. Create one in the dashboard under Settings → Account → Developer. Keys start with mh_live_. An MCP client that signs in with OAuth needs no key at all. See Authentication.
  • A domain with articles in it. The API serves what Mastheads has already written; it does not write anything until you ask with a full-access key.
  • A server to call from. A key is a secret. Never put it in browser code, a mobile app or a public repository.

Words the API uses

TermWhat it means
EditionA domain, as the dashboard calls it - one publication, with its own language, voice and connected site. The API keeps its original name. Its id is a UUID, returned as slug.
ArticleOne finished article. The API shows two statuses: draft (finished but not published) and published. An article still being written does not appear until it is done.
JobA piece of work you started through the API. You get its id back at once and check on it until it is done.
Read only keyThe default. Reads everything on your account and spends nothing.
Full access keyReads, and can also start work and publish. The choice is fixed when the key is created.
created_atWhen an article was written, in UTC. Pass the newest one you have seen as ?since= to fetch only newer articles.

Your first sync, step by step

  1. Create a key in Settings → Account → Developer, and leave it as Read only. Copy it straight into your secret store - it is shown once.
  2. List your domains and copy the slug of the one you want:
    curl https://api.mastheads.app/v1/editions \
      -H "Authorization: Bearer mh_live_your_key_here"
  3. Pull its articles. They come back oldest first, up to 100 a page, each with its full HTML body. This example asks for 50 written since 5 July:
    curl "https://api.mastheads.app/v1/editions/3f9c1e84-2b7a-4d6e-9c15-8a0d7e6b4f21/articles?since=2026-07-05T00:00:00Z&limit=50" \
      -H "Authorization: Bearer mh_live_your_key_here"
  4. Store the newest created_at you received, and pass it as ?since= on the next run. You then fetch only articles written since.
  5. Copy each picture. image.featured_url is a path on this API. Download it with your key and serve your own copy.

The same thing as a small Python script to run on a schedule. It is a skeleton: put your own storage behind load_last_seen, save and save_last_seen.

import requests

API = "https://api.mastheads.app"
HEADERS = {"Authorization": "Bearer mh_live_your_key_here"}

# 1. Find the domain (an "edition" in the API) to sync.
editions = requests.get(f"{API}/v1/editions", headers=HEADERS).json()["editions"]
edition = editions[0]["slug"]

# 2. Pull everything created since the last run, oldest first.
since = load_last_seen()          # your own storage; None on the first run
params = {"limit": 100}
if since:
    params["since"] = since

offset = 0
while True:
    r = requests.get(
        f"{API}/v1/editions/{edition}/articles",
        headers=HEADERS,
        params={**params, "offset": offset},
    )
    r.raise_for_status()
    page = r.json()
    for article in page["articles"]:
        save(article)             # title, body (HTML), byline, meta_title ...
        since = article["created_at"]
    offset += len(page["articles"])
    if not page["articles"] or offset >= page["total"]:
        break

# 3. Remember where you got to, for next time.
if since:
    save_last_seen(since)

Read your content

Four, all GET, open to every key. A read spends nothing.

Start work

Five doors that commission work or publish it, and the poll that tells you where a job got to. The five need a key created with Full access; the poll does not, so a read-only key can still watch. Work you start here goes through the same ten editorial desks, the same checks and the same allowance as work started in the dashboard.

Connect an AI assistant

The same account is reachable over MCP, the protocol AI assistants use for tools, at:

https://api.mastheads.app/v1/mcp

Any assistant connected this way can list your domains and articles, read one in full, and ask what backs it - the sources it was written from, what each desk recorded, and the editor of record. With spending allowed, it can also start work and publish. Codex, Claude and other clients that support OAuth sign in with your Mastheads login instead of a key. See Full access & MCP.

What costs, and what does not

  • Reading costs nothing, however often you pull the same article.
  • Starting an article, a batch row, a report or an audit uses your allowance, exactly as it would in the dashboard.
  • Publishing a finished article uses no article allowance - it was paid for when it was written.
  • Each key may make 120 requests a minute, and a full-access key may start 20 paid actions an hour. See Rate limits & errors.

Getting your whole archive

The read endpoints hand you your articles one page at a time, which is what you want for a running integration. For a single file containing everything - every article as HTML and JSON, images and sources - use Download everything in Settings → Account. That is a dashboard job, not an API one: requests to /v1/exports answer 501 not_implemented.