# Substack API
> Live data for any Substack publication, served straight from the publication's own public API — no key, nothing cached. Substack is the newsletter-and-blogging social platform; this reads a writer's public posts and their engagement. The posts endpoint returns a publication's recent or top posts with the title, subtitle, slug, publish date, post type (newsletter, podcast or thread), audience (free or paywalled), the heart-reaction count, the comment count, the word count and the cover image — Noah Smith's Noahpinion shows posts pulling hundreds of reactions and dozens of comments. The search endpoint searches a publication's archive by keyword. The post endpoint returns one post in full, including a plain-text excerpt of the body, its reactions and comment count. Point it at any publication by its Substack subdomain (noahpinion) or its custom domain (astralcodexten.com) and it follows the publication wherever it lives. This is the writer-and-post engagement layer for any media-monitoring, newsletter-analytics, reading or social app. Live from Substack, nothing stored. Distinct from dev-community and microblog APIs — this is Substack newsletter posts and their engagement. 4 endpoints.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/substack-api/..."
```

## Pricing
- **Free** (Free) — 13,500 calls/Mo, 3 req/s
- **Starter** ($7/Mo) — 170,000 calls/Mo, 8 req/s
- **Pro** ($17/Mo) — 720,000 calls/Mo, 15 req/s
- **Scale** ($41/Mo) — 3,600,000 calls/Mo, 30 req/s

## Endpoints

### Substack

#### `GET /v1/post` — One post in full with excerpt

**Parameters:**
- `publication` (query, required, string) — Substack subdomain or custom domain Example: `noahpinion`
- `slug` (query, required, string) — Post slug Example: `roundup-83-i-told-you-so`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/substack-api/v1/post?publication=noahpinion&slug=roundup-83-i-told-you-so"
```

**Response:**
```json
{
    "data": {
        "url": "https://www.noahpinion.blog/p/roundup-83-i-told-you-so",
        "slug": "roundup-83-i-told-you-so",
        "type": "newsletter",
        "title": "Roundup #83: I told you so!",
        "excerpt": "Photo by B. Sutherton via Wikimedia Commons Howdy, folks! Today’s roundup is mostly a bunch of follow-ups to posts I wrote before. It’s very hard to decide when to post about a particular topic, and it often happens that some relevant news story or piece of data comes out a little bit later. These roundups are a good way of cleaning up those loose ends. Today we start with a truly wacky policy proposal by the esteemed Thomas Piketty… 1. What on Earth is Thomas Piketty talking about? Unlike many people, I never pretended to have read Thomas Piketty’s book, Capital in the Twenty-First Century . I simply didn’t read it. I did read a number of the papers that the book was based on , which is often a better and quicker way of getting the key points of a book like that. I thought those papers were a good and important addition to the economics literature, even if the messy reality of inequality didn’t always fit the simple story Piketty told, and the data he relied on was less reliable than we might want. Despite the limitations of Piketty’s work, it sparked a long-overdue and generally healthy debate about inequality. And Piketty’s basic policy solution — tax rich people more — was pretty reasonable, even if his proposed numbers were 
…(truncated, see openapi.json for full schema)
```

#### `GET /v1/posts` — A publication's recent or top posts

**Parameters:**
- `publication` (query, required, string) — Substack subdomain or custom domain Example: `noahpinion`
- `sort` (query, optional, string) — new | top (default new) Example: `new`
- `limit` (query, optional, string) — How many (default 20, max 50) Example: `20`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/substack-api/v1/posts?publication=noahpinion&sort=new&limit=20"
```

**Response:**
```json
{
    "data": {
        "sort": "new",
        "count": 20,
        "posts": [
            {
                "url": "https://www.noahpinion.blog/p/roundup-83-i-told-you-so",
                "slug": "roundup-83-i-told-you-so",
                "type": "newsletter",
                "title": "Roundup #83: I told you so!",
                "is_paid": false,
                "audience": "everyone",
                "subtitle": "Piketty gets wacky; Tokenmaxxing fails; Trump, drones, and Ukraine; Tariffs on China, again; India's growth; Borjas again",
                "post_date": "2026-06-08T07:42:08.344Z",
                "reactions": 334,
                "wordcount": 3113,
                "cover_image": "https://substackcdn.com/image/fetch/$s_!ltQ3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ee2c9c-5a0f-48ad-b3b0-862053f1a953_960x640.jpeg",
                "comment_count": 51
            },
            {
                "url": "https://www.noahpinion.blog/p/why-europe-should-put-up-trade-barriers",
                "slug": "why-europe-should-put-up-trade-barriers",
                "type": "newsletter",
                "title": "Why Europe should put up trade barriers against Chinese goods",
                "is_paid": false,
                "audience": "everyone",
                "subtitle": "There are benefits far beyond protectionism.",
                "post_date": "2026-06-06T08:10:50.949Z",
                "reacti
…(truncated, see openapi.json for full schema)
```

#### `GET /v1/search` — Search a publication's archive

**Parameters:**
- `publication` (query, required, string) — Substack subdomain or custom domain Example: `noahpinion`
- `q` (query, required, string) — Search query Example: `china`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/substack-api/v1/search?publication=noahpinion&q=china"
```

**Response:**
```json
{
    "data": {
        "count": 20,
        "posts": [
            {
                "url": "https://www.noahpinion.blog/p/roundup-83-i-told-you-so",
                "slug": "roundup-83-i-told-you-so",
                "type": "newsletter",
                "title": "Roundup #83: I told you so!",
                "is_paid": false,
                "audience": "everyone",
                "subtitle": "Piketty gets wacky; Tokenmaxxing fails; Trump, drones, and Ukraine; Tariffs on China, again; India's growth; Borjas again",
                "post_date": "2026-06-08T07:42:08.344Z",
                "reactions": 334,
                "wordcount": 3113,
                "cover_image": "https://substackcdn.com/image/fetch/$s_!ltQ3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ee2c9c-5a0f-48ad-b3b0-862053f1a953_960x640.jpeg",
                "comment_count": 51
            },
            {
                "url": "https://www.noahpinion.blog/p/why-europe-should-put-up-trade-barriers",
                "slug": "why-europe-should-put-up-trade-barriers",
                "type": "newsletter",
                "title": "Why Europe should put up trade barriers against Chinese goods",
                "is_paid": false,
                "audience": "everyone",
                "subtitle": "There are benefits far beyond protectionism.",
                "post_date": "2026-06-06T08:10:50.949Z",
                "reactions": 329,
            
…(truncated, see openapi.json for full schema)
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/substack-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "source": "Substack public per-publication API (live)",
        "service": "substack-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/post": "One post in full with excerpt (publication=, slug=…).",
            "GET /v1/posts": "A publication's recent or top posts (publication=noahpinion, sort=new|top, limit up to 50).",
            "GET /v1/search": "Search a publication's archive (publication=, q=economics)."
        },
        "description": "Live data for any Substack publication from its own public API: a publication's recent or top posts with title, subtitle, publish date, type (newsletter/podcast/thread), audience (free/paid), heart-reaction count, comment count, word count and cover image; search a publication's archive by keyword; or fetch one post in full with a plain-text excerpt. Point it at a Substack subdomain (noahpinion) or a custom domain (astralcodexten.com). Live, no key, nothing stored. Distinct from dev-community and microblog APIs — this is Substack newsletter posts and their engagement.",
        "upstream_status": "ok"
    },
    "meta": {
        "timestamp": "2026-06-09T11:39:48.286Z",
        "request_id": "3d39cf03-eae4-4831-873b-11abfdcf8aa5"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


---
Marketplace page: https://www.oanor.com/api/substack-api
OpenAPI spec: https://www.oanor.com/api/substack-api/openapi.json
