Pinterest
Overview
Visual discovery and bookmarking platform. Social media archetype.
Workflows
Search and explore pins
searchPins(query) → results with pin id, images, titles, board/pinner info
getPin(id) → full pin detail with description, link, engagement stats
Explore boards and users
searchPins(query) → results include pinner.username and board slug
getBoard(username, slug) → board detail with pin count, followers
getUserProfile(username) → user profile with follower/following counts, bio
Quick search suggestions
searchTypeahead(term) → autocomplete suggestions for pins, boards, users
Save a pin to a board (verified)
searchPins(query) or getHomeFeed() → find pin → id (= pin_id)
searchPins(query) → result includes pinner.username and board slug
getBoard(username, slug) → target board → board_id
savePin(pin_id ← searchPins, board_id ← getBoard) → response includes the saved-pin record id (NOT the same as pin_id) and the chosen board.id
Remove a saved pin (verified, requires cross-op chain)
savePin(...) → resource_response.data.id (saved-pin record id), resource_response.data.board.id
unsavePin(id ← savePin response, board_id ← savePin response) — PinResource/delete/ requires the saved-pin record id, not the original pin_id. In example.json use ${prev.savePin.resource_response.data.id} and ${prev.savePin.resource_response.data.board.id} so verify chains the IDs.
Follow and unfollow boards (verified)
searchPins(query) → result includes pinner.username and board slug
getBoard(username, slug) → board_id
followBoard(board_id) → wraps POST /v3/boards/{board_id}/follow/ inside /resource/ApiResource/update/
unfollowBoard(board_id) → wraps the same v3 URL inside /resource/ApiResource/delete/
Browse home feed and notifications
getHomeFeed() → personalized recommended pins
getNotifications() → recent activity (repins, follows, comments)
Operations
| Operation |
Intent |
Key Input |
Key Output |
Notes |
| searchPins |
search pins by keyword |
query, scope, page_size |
id, images, grid_title, description, pinner, board, bookmark |
entry point; paginated via bookmark |
| getPin |
get pin details |
id ← searchPins |
title, description, link, images, pinner, board, repin/reaction/comment counts |
|
| getBoard |
get board details |
username + slug (e.g. WhoWhatWear/travel) |
name, description, pin_count, follower_count, owner, cover images |
|
| getUserProfile |
get user profile |
username |
full_name, about, follower/following/pin/board counts, image |
|
| searchTypeahead |
typeahead suggestions |
term |
label, type, id, images |
|
| savePin |
save pin to board |
pin_id ← searchPins/getHomeFeed, board_id ← getBoard |
resource_response.data.id (saved-pin record), resource_response.data.board.id |
write; reverse: unsavePin |
| unsavePin |
remove saved pin from board |
id ← savePin (saved-pin record), board_id ← savePin |
status |
write; reverse: savePin. Use ${prev.savePin.resource_response.data.{id,board.id}} |
| followBoard |
follow a board |
board_id ← getBoard (URL /v3/boards/{board_id}/follow/) |
id, name, url, followed_by_me |
write; routed via /resource/ApiResource/update/; reverse: unfollowBoard |
| unfollowBoard |
unfollow a board |
board_id ← getBoard (URL /v3/boards/{board_id}/follow/) |
status |
write; routed via /resource/ApiResource/delete/; reverse: followBoard |
| getHomeFeed |
personalized home feed |
page_size |
id, images, grid_title, pinner, board, bookmark |
paginated via bookmark |
| getNotifications |
notification feed |
page_size |
id, type, message, timestamp, actors, target, bookmark |
paginated via bookmark |
Quick Start
# Search for cat pins
openweb pinterest exec searchPins '{"source_url":"/search/pins/?q=cats","data":"{\"options\":{\"query\":\"cats\",\"scope\":\"pins\",\"page_size\":25},\"context\":{}}"}'
# Get pin details
openweb pinterest exec getPin '{"source_url":"/pin/12345/","data":"{\"options\":{\"id\":\"12345\",\"field_set_key\":\"detailed\"},\"context\":{}}"}'
# Get board details
openweb pinterest exec getBoard '{"source_url":"/WhoWhatWear/travel/","data":"{\"options\":{\"slug\":\"WhoWhatWear/travel\",\"field_set_key\":\"detailed\"},\"context\":{}}"}'
# Get user profile
openweb pinterest exec getUserProfile '{"source_url":"/pinterest/","data":"{\"options\":{\"username\":\"pinterest\",\"field_set_key\":\"profile\"},\"context\":{}}"}'
# Save a pin to a board
openweb pinterest exec savePin '{"source_url":"/","data":"{\"options\":{\"pin_id\":\"PIN_ID\",\"board_id\":\"BOARD_ID\",\"section_id\":null},\"context\":{}}"}'
# Unsave a pin (uses PinResource/delete — id is the saved-pin record id from savePin response, NOT the original pin_id)
openweb pinterest exec unsavePin '{"source_url":"/","data":"{\"options\":{\"id\":\"SAVED_PIN_ID\",\"board_id\":\"BOARD_ID\"},\"context\":{}}"}'
# Follow a board (modern endpoint: /resource/ApiResource/update/ wrapping /v3/boards/{board_id}/follow/)
openweb pinterest exec followBoard '{"source_url":"/marthastewart/baking-and-dessert-recipes-and-ideas/","data":"{\"options\":{\"url\":\"/v3/boards/BOARD_ID/follow/\"},\"context\":{}}"}'
# Unfollow a board (same wrapped URL via /resource/ApiResource/delete/)
openweb pinterest exec unfollowBoard '{"source_url":"/marthastewart/baking-and-dessert-recipes-and-ideas/","data":"{\"options\":{\"url\":\"/v3/boards/BOARD_ID/follow/\"},\"context\":{}}"}'
# Get home feed
openweb pinterest exec getHomeFeed '{"source_url":"/","data":"{\"options\":{\"field_set_key\":\"hifi\",\"in_nux\":false,\"prependPartner\":false,\"page_size\":25},\"context\":{}}"}'
# Get notifications
openweb pinterest exec getNotifications '{"source_url":"/notifications/","data":"{\"options\":{\"field_set_key\":\"default\",\"page_size\":25},\"context\":{}}"}'
Known Limitations
unsavePin requires the saved-pin record id from savePin — PinResource/delete/ takes the id returned in savePin's resource_response.data.id (NOT the original pin_id). When chaining manually, save the response from savePin and pass its id + board.id to unsavePin. In example.json, use ${prev.savePin.resource_response.data.id} and ${prev.savePin.resource_response.data.board.id} (verify cross-op templating).
- Board follow lives behind the "More actions" menu — Pinterest deprecated
/resource/BoardFollowingResource/. The modern follow/unfollow click is wrapped: POST /resource/ApiResource/{update,delete}/ with body data={"options":{"url":"/v3/boards/{board_id}/follow/"},"context":{}}. The board's UI Follow button moved into the 3-dot menu — easy to miss when capturing HAR.
- Write ops use form-encoded bodies —
POST /resource/{ResourceName}/{create,update,delete}/ with form-encoded source_url + data fields (where data is a JSON-string of {"options":{...},"context":{}}). Mirror this for any new write op unless HAR proves otherwise.
source_url should match the page where the action would naturally happen — Pinterest sometimes rejects writes when source_url is just /. Use the board/pin URL the action targets (e.g. /<username>/<board-slug>/).
1---2name: pinterest3description: Pinterest4---5# Pinterest67## Overview8Visual discovery and bookmarking platform. Social media archetype.910## Workflows1112### Search and explore pins131. `searchPins(query)` → results with pin `id`, images, titles, board/pinner info142. `getPin(id)` → full pin detail with description, link, engagement stats1516### Explore boards and users171. `searchPins(query)` → results include `pinner.username` and `board` slug182. `getBoard(username, slug)` → board detail with pin count, followers193. `getUserProfile(username)` → user profile with follower/following counts, bio2021### Quick search suggestions221. `searchTypeahead(term)` → autocomplete suggestions for pins, boards, users2324### Save a pin to a board (verified)251. `searchPins(query)` or `getHomeFeed()` → find pin → `id` (= `pin_id`)262. `searchPins(query)` → result includes `pinner.username` and `board` slug273. `getBoard(username, slug)` → target board → `board_id`284. `savePin(pin_id ← searchPins, board_id ← getBoard)` → response includes the **saved-pin record** `id` (NOT the same as `pin_id`) and the chosen `board.id`2930### Remove a saved pin (verified, requires cross-op chain)311. `savePin(...)` → `resource_response.data.id` (saved-pin record id), `resource_response.data.board.id`322. `unsavePin(id ← savePin response, board_id ← savePin response)` — `PinResource/delete/` requires the **saved-pin record id**, not the original `pin_id`. In `example.json` use `${prev.savePin.resource_response.data.id}` and `${prev.savePin.resource_response.data.board.id}` so verify chains the IDs.3334### Follow and unfollow boards (verified)351. `searchPins(query)` → result includes `pinner.username` and `board` slug362. `getBoard(username, slug)` → `board_id`373. `followBoard(board_id)` → wraps `POST /v3/boards/{board_id}/follow/` inside `/resource/ApiResource/update/`384. `unfollowBoard(board_id)` → wraps the same v3 URL inside `/resource/ApiResource/delete/`3940### Browse home feed and notifications411. `getHomeFeed()` → personalized recommended pins422. `getNotifications()` → recent activity (repins, follows, comments)4344## Operations4546| Operation | Intent | Key Input | Key Output | Notes |47|-----------|--------|-----------|------------|-------|48| searchPins | search pins by keyword | query, scope, page_size | id, images, grid_title, description, pinner, board, bookmark | entry point; paginated via `bookmark` |49| getPin | get pin details | id ← searchPins | title, description, link, images, pinner, board, repin/reaction/comment counts | |50| getBoard | get board details | username + slug (e.g. `WhoWhatWear/travel`) | name, description, pin_count, follower_count, owner, cover images | |51| getUserProfile | get user profile | username | full_name, about, follower/following/pin/board counts, image | |52| searchTypeahead | typeahead suggestions | term | label, type, id, images | |53| savePin | save pin to board | pin_id ← searchPins/getHomeFeed, board_id ← getBoard | resource_response.data.id (saved-pin record), resource_response.data.board.id | write; reverse: unsavePin |54| unsavePin | remove saved pin from board | id ← savePin (saved-pin record), board_id ← savePin | status | write; reverse: savePin. Use `${prev.savePin.resource_response.data.{id,board.id}}` |55| followBoard | follow a board | board_id ← getBoard (URL `/v3/boards/{board_id}/follow/`) | id, name, url, followed_by_me | write; routed via `/resource/ApiResource/update/`; reverse: unfollowBoard |56| unfollowBoard | unfollow a board | board_id ← getBoard (URL `/v3/boards/{board_id}/follow/`) | status | write; routed via `/resource/ApiResource/delete/`; reverse: followBoard |57| getHomeFeed | personalized home feed | page_size | id, images, grid_title, pinner, board, bookmark | paginated via `bookmark` |58| getNotifications | notification feed | page_size | id, type, message, timestamp, actors, target, bookmark | paginated via `bookmark` |5960## Quick Start6162```bash63# Search for cat pins64openweb pinterest exec searchPins '{"source_url":"/search/pins/?q=cats","data":"{\"options\":{\"query\":\"cats\",\"scope\":\"pins\",\"page_size\":25},\"context\":{}}"}'6566# Get pin details67openweb pinterest exec getPin '{"source_url":"/pin/12345/","data":"{\"options\":{\"id\":\"12345\",\"field_set_key\":\"detailed\"},\"context\":{}}"}'6869# Get board details70openweb pinterest exec getBoard '{"source_url":"/WhoWhatWear/travel/","data":"{\"options\":{\"slug\":\"WhoWhatWear/travel\",\"field_set_key\":\"detailed\"},\"context\":{}}"}'7172# Get user profile73openweb pinterest exec getUserProfile '{"source_url":"/pinterest/","data":"{\"options\":{\"username\":\"pinterest\",\"field_set_key\":\"profile\"},\"context\":{}}"}'7475# Save a pin to a board76openweb pinterest exec savePin '{"source_url":"/","data":"{\"options\":{\"pin_id\":\"PIN_ID\",\"board_id\":\"BOARD_ID\",\"section_id\":null},\"context\":{}}"}'7778# Unsave a pin (uses PinResource/delete — id is the saved-pin record id from savePin response, NOT the original pin_id)79openweb pinterest exec unsavePin '{"source_url":"/","data":"{\"options\":{\"id\":\"SAVED_PIN_ID\",\"board_id\":\"BOARD_ID\"},\"context\":{}}"}'8081# Follow a board (modern endpoint: /resource/ApiResource/update/ wrapping /v3/boards/{board_id}/follow/)82openweb pinterest exec followBoard '{"source_url":"/marthastewart/baking-and-dessert-recipes-and-ideas/","data":"{\"options\":{\"url\":\"/v3/boards/BOARD_ID/follow/\"},\"context\":{}}"}'8384# Unfollow a board (same wrapped URL via /resource/ApiResource/delete/)85openweb pinterest exec unfollowBoard '{"source_url":"/marthastewart/baking-and-dessert-recipes-and-ideas/","data":"{\"options\":{\"url\":\"/v3/boards/BOARD_ID/follow/\"},\"context\":{}}"}'8687# Get home feed88openweb pinterest exec getHomeFeed '{"source_url":"/","data":"{\"options\":{\"field_set_key\":\"hifi\",\"in_nux\":false,\"prependPartner\":false,\"page_size\":25},\"context\":{}}"}'8990# Get notifications91openweb pinterest exec getNotifications '{"source_url":"/notifications/","data":"{\"options\":{\"field_set_key\":\"default\",\"page_size\":25},\"context\":{}}"}'92```9394## Known Limitations95- **`unsavePin` requires the saved-pin record id from `savePin`** — `PinResource/delete/` takes the id returned in `savePin`'s `resource_response.data.id` (NOT the original `pin_id`). When chaining manually, save the response from `savePin` and pass its `id` + `board.id` to `unsavePin`. In `example.json`, use `${prev.savePin.resource_response.data.id}` and `${prev.savePin.resource_response.data.board.id}` (verify cross-op templating).96- **Board follow lives behind the "More actions" menu** — Pinterest deprecated `/resource/BoardFollowingResource/`. The modern follow/unfollow click is wrapped: `POST /resource/ApiResource/{update,delete}/` with body `data={"options":{"url":"/v3/boards/{board_id}/follow/"},"context":{}}`. The board's UI Follow button moved into the 3-dot menu — easy to miss when capturing HAR.97- **Write ops use form-encoded bodies** — `POST /resource/{ResourceName}/{create,update,delete}/` with form-encoded `source_url` + `data` fields (where `data` is a JSON-string of `{"options":{...},"context":{}}`). Mirror this for any new write op unless HAR proves otherwise.98- **`source_url` should match the page where the action would naturally happen** — Pinterest sometimes rejects writes when `source_url` is just `/`. Use the board/pin URL the action targets (e.g. `/<username>/<board-slug>/`).