All pages
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
What you can build
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
| Term | What it means |
|---|---|
| Edition | A 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. |
| Article | One 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. |
| Job | A 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 key | The default. Reads everything on your account and spends nothing. |
| Full access key | Reads, and can also start work and publish. The choice is fixed when the key is created. |
| created_at | When 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
- Create a key in Settings → Account → Developer, and leave it as Read only. Copy it straight into your secret store - it is shown once.
- List your domains and copy the
slugof the one you want:curl https://api.mastheads.app/v1/editions \ -H "Authorization: Bearer mh_live_your_key_here" - 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" - Store the newest
created_atyou received, and pass it as?since=on the next run. You then fetch only articles written since. - Copy each picture.
image.featured_urlis 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.
/v1/editionsGET/v1/editions/{slug}/articlesGET/v1/editions/{slug}/articles/{article_id}GET/v1/editions/{slug}/articles/{article_id}/imageStart 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.
/v1/editions/{slug}/articlesPOST/v1/editions/{slug}/articles/batchPOST/v1/editions/{slug}/researchPOST/v1/editions/{slug}/auditGET/v1/jobs/{job_id}POST/v1/editions/{slug}/articles/{article_id}/publishConnect an AI assistant
The same account is reachable over MCP, the protocol AI assistants use for tools, at:
https://api.mastheads.app/v1/mcpAny 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.