Substack API endpoint
Returns one page of the public Notes feed for one tab. tab and type come as a pair from the Notes feed tabs endpoint. Pagination is cursor-based: pass the previous response's next_cursor back as cursor. Post-only rows in the upstream feed are omitted; every returned row is a Note.
/substack/notestab: optional feed tab id from
/api/v1/substack/notes/tabs. Defaults to
for-you.type: optional tab type from the same endpoint. Allowed values: base,
secondary, category. Defaults to base.cursor: optional opaque cursor from a previous response's
next_cursor.tab and type are a pair — the upstream rejects a tab whose type does
not match. for-you is base, bestseller is secondary, and every
numeric category id is category.
The upstream feed mixes Notes with post cards; post-only rows are omitted,
so every row returned here is a Note in the same shape as
substack-note.
Pagination is cursor-based. Page sizes are small and variable (3-8 notes per
page observed) — rely on next_cursor, not a fixed page size.
| Field | Filled in, of 5 checked | Values in the sample |
|---|---|---|
| id | 5 | |
| body | 5 | |
| author_id | 5 | |
| author_name | 5 | |
| author_handle | 5 | |
| author_url | 5 | substack.com |
| author_photo_url | 5 | substack-post-media.s3.amazonaws.com |
| url | 5 | substack.com |
| published_at | 5 | 2026-10-13 |
| reaction_count | 5 | 38 to 219, median 89 |
| restack_count | 5 | 1 to 11, median 7 |
| reply_count | 5 | 1 to 17, median 3 |
| reactions | 5 | |
| language | 5 | |
| is_ai_generated | 5 | true in 0 of 5 |
| edited_at | 1 | 2026-10-13 |
| author_bestseller_tier | 2 | 100 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| tab | string | No | Feed tab id from the Notes feed tabs endpoint | for-you | |
| type | string | No | Tab type from the Notes feed tabs endpoint Allowed values: base, secondary, category. | ||
| cursor | string | No | Opaque cursor from a previous response's next_cursor | ||
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/substack/notes?type=base" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"data": {
"tab": "for-you",
"type": "base",
"next_cursor": "eyJzZXNzaW9uX2lkIjoiMDU1...",
"has_more": true,
"notes": [
{
"id": 327800937,
"body": "A short note about something.",
"author_handle": "someone",
"author_url": "https://substack.com/@someone",
"url": "https://substack.com/@someone/note/c-327800937",
"published_at": "2026-09-07T12:33:56.367Z",
"reaction_count": 42,
"is_ai_generated": false
}
]
},
"msg": "success"
}Request schema
No body schema
Response schema
#/definitions/substack.notesFeedResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | substack.NotesFeedResult | No | ||||
| data.has_more | boolean | No | ||||
| data.next_cursor | string | No | ||||
| data.notes | array | No | Note record, 21 fields: attached_post, author_bestseller_tier, author_handle, author_id, author_name, author_photo_url, author_url, body, edited_at, id, is_ai_generated, language and 6 more. Described under Get one public Substack Note API. | |||
| data.tab | string | No | for-you | |||
| data.type | string | No | base | |||
| msg | string | No | success |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/substack/notes?type=base" \
-H "x-api-key: $CRAWLORA_API_KEY"