Sharing hasil analisa Pinterest web client dan membangun ulang SDK-nya dengan TypeScript — murni dari capture HTTP/HTTPS via HTTP Toolkit. Tujuannya: memahami pola komunikasi web client Pinterest (resource API lama + GraphQL baru), lalu membungkusnya jadi SDK yang bisa dipakai untuk search, feed, pin detail, komentar, dan board.
Catatan: proyek edukasi/riset. Gunakan akun sendiri, hormati ToS Pinterest, jangan sekali-kali push token atau kredensial ke git publik.
Alat
- HTTP Toolkit — interceptor Chrome, capture semua traffic Pinterest (workflow
mcp-http-trace)
- Chrome + Proxy 8000 — browsing login, search, pin closeup, board, pin-creation-tool sambil direkam
- Node.js + TypeScript — implementasi SDK (zero runtime deps, native
fetch)
Tiga Permukaan API yang Ditangkap
Web client Pinterest tidak bicara ke satu endpoint saja. Dari capture muncul tiga pola:
| Permukaan | Transport | Contoh endpoint |
| Resource API (v1) | GET/POST /resource/<Name>/<action>/ dengan param data={options,context} | BaseSearchResource/get → v3_search_pins |
| GraphQL | POST /_/graphql/ + header x-pinterest-graphql-name | UnauthHomePageBrandBoardsEagerQuery |
| GraphQL SSE | POST /_/graphql/stream/ (text/event-stream) | CloseupDetailQuery |
| v3 REST proxy | ApiResource/{get,create,update} dengan options.url=/v3/... | /v3/users/me/, /v3/media/uploads/ |
Semua resource call membawa {options, context} di param data, plus header wajib: x-csrftoken (mirror dari cookie), x-pinterest-appstate: active, x-requested-with: XMLHttpRequest, x-pinterest-pws-handler, x-app-version.
Auth — Cookie, CSRF, dan Dua Jalur Login
Sesi dipegang cookie: csrftoken, _pinterest_sess, _auth, l_o, __Secure-s_a. x-csrftoken harus selalu mirror nilai cookie csrftoken. Login sukses set _auth=1 + rotasi _pinterest_sess.
- Login HTTP murni —
UserSessionResource/create → v3_login_user. Tanpa token challenge (Arkose/reCAPTCHA) biasanya ditolak bot protection.
- Login via super-puppeteer (opsional) — browser Chrome asli yang di-stealth-patch (
super-puppeteer), isi form login sungguhan, lalu cookie sesi diadopsi ke SDK. Deps-nya optional — pengguna yang tidak mau puppeteer tidak perlu install. Selector form otomatis menyesuaikan A/B test layout (streamlined vs classic).
const user = await client.auth.loginWithPuppeteer({
usernameOrEmail: "you@example.com",
password: "hunter2",
headless: false,
});
const me = await client.users.me();
const feed = await client.feed.homeFeed();
Struktur SDK
src/
client.ts PinterestClient — namespace resource + escape hatch
transport.ts resource()/graphql()/graphqlStream() + header CSRF
cookies.ts cookie jar (RFC 6265)
types.ts model hasil capture (Pin, Board, User, envelope)
errors.ts hierarki error (Http/Resource/Csrf/Auth)
resources/
auth.ts login (HTTP + puppeteer), sso_info
search.ts BaseSearchResource, typeahead
pins.ts PinResource (closeup), related, comments
feed.ts UserHomefeedResource + v3 proxy
boards.ts list/create/picker board
users.ts UserResource + /v3/users/me
Endpoint yang sudah di-map dari capture:
| Resource | endpoint_name | Fungsi |
BaseSearchResource | v3_search_pins | search pins + pagination bookmark |
PinResource | v3_get_pin | detail pin closeup |
RelatedModulesResource | v3_related_modules_for_pin | feed "More to explore" |
UnifiedCommentsResource | v3_get_aggregated_pin_data_unified_comments | komentar pin |
AggregatedCommentResource | — | post komentar |
UserHomefeedResource | v3_home_feed | home feed (auth) |
UserResource / BoardsResource | v3_get_user_handler / v3_user_profile_boards_feed | profil + board |
UserSessionResource | v3_login_user | login |
Hal Menarik dari Capture
- Pagination pakai bookmark base64 — tiap page berikutnya POST dengan
bookmarks dari resource_response.bookmark sebelumnya. Search GET untuk halaman pertama, POST untuk halaman lanjutan.
- GraphQL streaming — endpoint
/_/graphql/stream/ mengembalikan text/event-stream dengan frame event: message + data: {json}, dipakai query CloseupDetailQuery.
- A/B test form login — Pinterest punya dua layout form (
#streamlined-login-email vs #email); SDK probing selector otomatis.
- Penting soal deps — super-puppeteer + puppeteer sebagai peer dependency optional; dynamic import, error jelas kalau belum diinstall, HTTP login tetap jalan tanpa keduanya.
Verifikasi
- 23 unit test — replay fixture capture asli (wire-format request dibandingkan byte-per-byte, parsing envelope, error mapping, format SSE)
- Live smoke test — bootstrap guest session → search pins (17 hasil nyata) → typeahead → v3 proxy, semua 200
- Live puppeteer login — login browser asli ke akun,
me(), homefeed (25 pins), board — sukses sebelum kena rate-limit Pinterest ("Too many login attempts")
Status
| Fitur | Status |
| Search pins + pagination | jalan |
| Typeahead | jalan |
| Pin detail (closeup) | jalan |
| Related pins / "More to explore" | jalan |
| Komentar (lihat + post) | jalan |
| Home feed | jalan |
| Board list / create | jalan |
| Profil user / me | jalan |
| Login HTTP + puppeteer | jalan |
| Save/repin, follow | belum di-capture |
Sisa fitur tinggal capture aksinya sekali lewat HTTP Toolkit, lalu tempel ke resource yang sudah disiapkan.
Repo
https://github.com/ReverserID/Pinterest-Unofficial-API
Terbuka untuk diskusi soal pola endpoint Pinterest, tantangan bot protection, atau pengalaman menganalisa web app sejenis.