The most complete unofficial Pinterest API client for Python
π Pin Β· π€ Upload Images & Videos Β· π Manage Boards Β· π₯ Follow Β· π Search Β· π¬ Comment & Message
No API key needed. Works by mimicking browser requests to Pinterest's internal endpoints.
The comeback release. Nearly every core feature has been fixed, modernized, or rewritten.
| Highlight | |
|---|---|
| π¬ | Video pin uploads β full Story Pin / Idea Pin support via S3 upload flow |
| πΌοΈ | Image uploads rewritten β old broken /upload-image/ replaced with working S3 flow |
| π | Pagination fixed β reset_bookmark bug fixed across all 12 paginated methods |
| π | Login hardened β cookie banner handling, language-independent selectors, proper cleanup |
| ποΈ | Board deletion β new delete_board() method |
| π | Board sections β now supports page_size (up to 100, was hardcoded to 25) |
| π‘οΈ | No more data loss β Registry no longer rmtree's your directories on init |
| π¦ | Dependency pins β selenium>=4.0.0, webdriver-manager>=4.0.0 |
π Full list of resolved issues (click to expand)
| Issue | Description | Status |
|---|---|---|
| #220 | Video upload not supported | β Fixed |
| #219 | Login β element not interactable (cookie banner) | β Fixed |
| #218 | Error in search (pin & board) | β Fixed |
| #217 | 403 Forbidden β _ngjs URL prefix |
β Fixed |
| #213 | Search page size & pagination | β Fixed |
| #209 | pin() unexpected keyword image_path |
β Fixed |
| #208 | load_pin KeyError v3GetPinQuery |
β Fixed |
| #207 | 404 on PinResource/create |
β Fixed |
| #205 | load_pin β __PWS_DATA__ / props error |
β Fixed |
| #204 | 401 Unauthorized on /upload-image/ |
β Fixed |
| #203 | get_user_pins stops short on large accounts |
β Fixed |
| #202 | Timeout <object> error (selenium 3 + urllib3 2) |
β Fixed |
| #200 | Downstream extruct issue |
β N/A (dependency removed) |
| #195 | Login error β ChromeDriver URL change | β Fixed |
| #193 | Login fails for non-English locales | β Fixed |
| #191 | ChromeDriver download 404 | β Fixed |
| #188 | 404 on PinResource/create |
β Fixed |
| #187 | get_board_sections limited to 25 |
β Fixed |
| #184 | Bad request β can't create pins | β Fixed |
| #181 | 403 Forbidden on PinResource/create |
β Fixed |
| #178 | Can't upload a new pin | β Fixed |
| #176 | Issue creating pins | β Fixed |
| #175 | Can't post a new pin | β Fixed |
| #174 | Pinning fails with HTML output | β Fixed |
| #156 | Credentials not storing | β Fixed |
| #148 | Facing problem with pinning image | β Fixed |
| #147 | How to create video pins? | β Fixed |
| #139 | data/ directory automatic removal |
β Fixed |
| #138 | KeyError resources in load_pin |
β Fixed |
| #137 | Pin from local file not working | β Fixed |
| #136 | Pin and delete function not working | β Fixed |
| #130 | Story pin creation | β Fixed |
| #108 | Login broken (API updates) | β Fixed |
pip install py3-pinterestRequirements: Python 3.8+ Β Β·Β Google Chrome (for login only)
from py3pin.Pinterest import Pinterest
pinterest = Pinterest(
email='you@email.com',
password='your_password',
username='your_username',
cred_root='cred_root' # cookies stored here, created automatically
)
# Login once β cookies are saved and reused automatically (~15 days)
pinterest.login()
# Pin an image
pinterest.pin(
board_id='123456789',
image_url='https://example.com/image.jpg',
title='My Pin',
description='Pinned with py3-pinterest'
)pinterest.upload_pin(
board_id='123456789',
image_file='photo.jpg',
title='My Pin',
description='Uploaded with py3-pinterest',
link='https://example.com'
)pinterest.upload_video_pin(
board_id='123456789',
video_file='video.mov',
title='My Video Pin',
description='Video uploaded with py3-pinterest',
link='https://example.com'
)π‘ Requires
ffmpegandffprobeon PATH. Or provideduration_ms,width,height, andcover_image_filemanually to skip the dependency.
pinterest.pin(
board_id='123456789',
image_url='https://example.com/image.jpg',
title='Pin Title',
description='Pin description'
)pinterest.repin(board_id='board_id', pin_id='pin_id')pinterest.load_pin(pin_id='pin_id') # Get full pin data
pinterest.delete_pin(pin_id='pin_id') # Delete a pin
pinterest.get_pinnable_images(url='...') # Get pinnable images from any website# List boards
boards = pinterest.boards(username='someone') # One page
boards = pinterest.boards_all(username='someone') # All boards
# Create & delete
pinterest.create_board(name='My Board', description='A new board')
pinterest.delete_board(board_id='board_id')
# Board feed β all pins in a board
pins = pinterest.board_feed(board_id='board_id', reset_bookmark=True)
# Recommendations ("More ideas")
recs = pinterest.board_recommendations(board_id='board_id', reset_bookmark=True)pinterest.create_board_section(board_id='board_id', section_name='My Section')
pinterest.delete_board_section(section_id='section_id')
pinterest.get_board_sections(board_id='board_id') # Supports page_size up to 100
pinterest.get_section_pins(section_id='section_id')
# Pin directly to a section
pinterest.pin(board_id='board_id', section_id='section_id', image_url='...')
pinterest.upload_pin(board_id='board_id', section_id='section_id', image_file='...')pinterest.get_user_overview(username='someone')
pinterest.get_user_pins(username='someone', reset_bookmark=True)# Users
pinterest.follow_user(user_id='user_id')
pinterest.unfollow_user(user_id='user_id')
# Boards
pinterest.follow_board(board_id='board_id')
pinterest.unfollow_board(board_id='board_id')
# Get following & followers (batched)
following = pinterest.get_following(username='someone', reset_bookmark=True)
followers = pinterest.get_user_followers(username='someone', reset_bookmark=True)
# Get all at once
all_following = pinterest.get_following_all(username='someone')
all_followers = pinterest.get_user_followers_all(username='someone')# Scopes: pins, buyable_pins, my_pins, videos, boards
results = pinterest.search(scope='pins', query='home decor', reset_bookmark=True)pin_data = pinterest.load_pin(pin_id='pin_id')
results = pinterest.visual_search(pin_data, x=10, y=50, w=100, h=100)pinterest.type_ahead(term='apple')pinterest.comment(pin_id='pin_id', text='Nice pin!')
pinterest.delete_comment(pin_id='pin_id', comment_id='comment_id')
pinterest.get_comments(pin_id='pin_id', reset_bookmark=True)conversations = pinterest.get_conversations()
messages = pinterest.load_conversation(conversation_id='conv_id')
# Send text, pin, or both
pinterest.send_message(conversation_id='conv_id', message='Hey!')
pinterest.send_message(conversation_id='conv_id', pin_id='pin_id')
pinterest.send_message(conversation_id='conv_id', pin_id='pin_id', message='Check this out')pins = pinterest.home_feed(reset_bookmark=True)Most list methods are batched β they return one page per call. Loop until empty:
all_pins = []
batch = pinterest.board_feed(board_id='board_id', reset_bookmark=True)
while batch:
all_pins += batch
batch = pinterest.board_feed(board_id='board_id')
print(f'Total: {len(all_pins)} pins')Always pass
reset_bookmark=Trueon the first call to start fresh.
proxies = {"http": "http://user:pass@proxy_ip:port"}
pinterest = Pinterest(
email='...', password='...', username='...',
cred_root='cred_root', proxies=proxies
)
pinterest.login(proxy='ip:port')pinterest.login() # Headless Chrome
pinterest.login(headless=False) # Visible browser (for debugging)
pinterest.login(proxy='ip:port') # Through a proxy
pinterest.login(lang='en') # Set browser language
pinterest.logout()Cookies persist to disk and are reused across runs. Re-login when you start seeing 401/403 errors (~every 15 days).
All methods return the raw Pinterest response:
resp = pinterest.upload_pin(board_id='...', image_file='photo.jpg', title='Test')
data = resp.json()
pin_id = data["resource_response"]["data"]["id"]
board_id = data["resource_response"]["data"]["board"]["id"]Full working examples in the Examples/ directory:
| File | Description |
|---|---|
examples.py |
ποΈ Comprehensive overview of all features |
upload_examples.py |
π€ Image and video upload |
board_sections_example.py |
π Board sections and section pins |
download_board_images.py |
β¬οΈ Download all images from boards |
follow_examples.py |
π₯ Search, follow users and boards |
mass_board_invites.py |
π¨ Bulk board invites from search |
messages_example.py |
βοΈ Conversations and messaging |
get_board_followers.py |
π€ Get board followers |
Found a bug or want to add a feature? Open an issue or submit a PR.
Thanks to all contributors: @alglez, @anonymustard, @Ashad001, @bahrmichaelj, @CapofWeird, @edersonff, @elmissouri16, @erenalpt, @evezus, @fratamico, @Gmanicus, @imgVOID, @kruvatz, @magicaltoast, @marcosfelt, @mfhassan22, @Nviard, @RKuttruff, @VeemPees, @victorviro, @vladradishevsky, @vriadlee, @vtni, @yaonur
- Get started with Pinterest automation β MarTechWithMe
- Automated posting to Pinterest (Russian) β Analitiq YouTube
MIT License Β· Made with β€οΈ by @bstoilov
