Unofficial wrapper for the Substack API
Project description
Substack API
An unofficial Python client library for interacting with Substack newsletters and content.
Overview
This library provides Python interfaces for interacting with Substack's unofficial API, allowing you to:
- Retrieve newsletter posts, podcasts, and recommendations
- Get user profile information and subscriptions
- Fetch post content and metadata
- Search for posts within newsletters
- Access paywalled content that you have written or paid for with user-provided authentication
Installation
# Using pip
pip install substack-api
# Using poetry
poetry add substack-api
Usage Examples
Working with Newsletters
from substack_api import Newsletter
# Initialize a newsletter by its URL
newsletter = Newsletter("https://example.substack.com")
# Get recent posts (returns Post objects)
recent_posts = newsletter.get_posts(limit=5)
# Get posts sorted by popularity
top_posts = newsletter.get_posts(sorting="top", limit=10)
# Search for posts
search_results = newsletter.search_posts("machine learning", limit=3)
# Get podcast episodes
podcasts = newsletter.get_podcasts(limit=5)
# Get recommended newsletters
recommendations = newsletter.get_recommendations()
# Get newsletter authors
authors = newsletter.get_authors()
Working with Posts
from substack_api import Post
# Initialize a post by its URL
post = Post("https://example.substack.com/p/post-slug")
# Get post metadata
metadata = post.get_metadata()
# Get the post's HTML content
content = post.get_content()
Accessing Paywalled Content with Authentication
To access paywalled content, you need to provide your own session cookies from a logged-in Substack session:
from substack_api import Newsletter, Post, SubstackAuth
# Set up authentication with your cookies
auth = SubstackAuth(cookies_path="path/to/your/cookies.json")
# Use authentication with newsletters
newsletter = Newsletter("https://example.substack.com", auth=auth)
posts = newsletter.get_posts(limit=5) # Can now access paywalled posts
# Use authentication with individual posts
post = Post("https://example.substack.com/p/paywalled-post", auth=auth)
content = post.get_content() # Can now access paywalled content
# Check if a post is paywalled
if post.is_paywalled():
print("This post requires a subscription")
Getting Your Cookies
To access paywalled content, you need to export your browser cookies from a logged-in Substack session. The cookies should be in JSON format with the following structure:
[
{
"name": "substack.sid",
"value": "your_session_id",
"domain": ".substack.com",
"path": "/",
"secure": true
},
{
"name": "substack.lli",
"value": "your_lli_value",
"domain": ".substack.com",
"path": "/",
"secure": true
},
...
]
Important: Only use your own cookies from your own authenticated session. This feature is intended for users to access their own subscribed or authored content programmatically.
Working with Users
from substack_api import User
# Initialize a user by their username
user = User("username")
# Get user profile information
profile_data = user.get_raw_data()
# Get user ID and name
user_id = user.id
name = user.name
# Get user's subscriptions
subscriptions = user.get_subscriptions()
Handling Renamed Accounts
Substack allows users to change their handle (username) at any time. When this happens, the old API endpoints return 404 errors. This library automatically handles these redirects by default.
Automatic Redirect Handling
from substack_api import User
# This will automatically follow redirects if the handle has changed
user = User("oldhandle") # Will find the user even if they renamed to "newhandle"
# Check if a redirect occurred
if user.was_redirected:
print(f"User was renamed from {user.original_username} to {user.username}")
Disable Redirect Following
If you prefer to handle 404s yourself:
# Disable automatic redirect following
user = User("oldhandle", follow_redirects=False)
Manual Handle Resolution
You can also manually resolve handle redirects:
from substack_api import resolve_handle_redirect
new_handle = resolve_handle_redirect("oldhandle")
if new_handle:
print(f"Handle was renamed to: {new_handle}")
Limitations
- This is an unofficial library and not endorsed by Substack
- APIs may change without notice, potentially breaking functionality
- Rate limiting may be enforced by Substack
- Authentication requires users to provide their own session cookies
- Users are responsible for complying with Substack's terms of service when using authentication features
Development
Running Tests
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This package is not affiliated with, endorsed by, or connected to Substack in any way. It is an independent project created to make Substack content more accessible through Python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file substack_api-1.1.3.tar.gz.
File metadata
- Download URL: substack_api-1.1.3.tar.gz
- Upload date:
- Size: 122.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4eda526ffe7b78f342fb4748623594b1f717553f4ddd78fbc51e5ca74fc37d57
|
|
| MD5 |
5c75c79d912eefb1f853a566d6d64f3b
|
|
| BLAKE2b-256 |
89259c06fca7583dc47d99c8f36761e5dbf59990f9b6e73934fee7a61702448b
|
File details
Details for the file substack_api-1.1.3-py3-none-any.whl.
File metadata
- Download URL: substack_api-1.1.3-py3-none-any.whl
- Upload date:
- Size: 14.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ac7725934aa33a182f910a276554cca744f28567ac3ba5d170b0ca6a48361d5
|
|
| MD5 |
83dcc3be902b3cddd1b9a87f0590c423
|
|
| BLAKE2b-256 |
3827ce34396a608629b79b5a4d220a787ca567db55cc4ec5dd95a18dabdf5970
|