• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
pinjasaur

pinjasaur

letterboxd

Public
Like
letterboxd
Home
Code
3
README.md
H
index.ts
test.html
Environment variables
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
1/16/2026
Viewing readonly version of main branch: v45
View latest version
README.md

Letterboxd Diary API

A simple API to fetch the most recent diary entry from a Letterboxd user's diary page.

Overview

This API scrapes the Letterboxd diary page for user "pinjasaur" and returns the most recent film entry in a clean JSON format. Perfect for displaying your latest watched movie on a personal website or blog.

API Endpoints

GET /

Returns the most recent diary entry as JSON.

GET /poster?url=<encoded_image_url>

Proxies Letterboxd poster images to avoid CORS restrictions. Returns a placeholder SVG if the original image is unavailable. The main API automatically returns proxied URLs, but you can use this endpoint directly if needed.

Response Format

{ "title": "Long Story Short", "year": 2021, "rating": 3, "watchDate": "2026-01-15", "posterUrl": null, "filmUrl": "https://letterboxd.com/pinjasaur/film/long-story-short-2021/", "scrapedAt": "2026-01-16T15:31:10.959Z" }

Note: posterUrl will be null when no poster image is available, or a proxied URL when an image exists.

Fields

  • title: Film title (string | null)
  • year: Release year (number | null)
  • rating: Star rating from 0.5 to 5 stars (number | null)
  • watchDate: Date watched in YYYY-MM-DD format (string | null)
  • posterUrl: Proxied poster image URL that works around CORS restrictions (string | null)
  • filmUrl: Link to the film's Letterboxd page (string | null)
  • scrapedAt: ISO timestamp of when the data was scraped (string)

Usage Examples

JavaScript/Fetch

fetch('https://your-val-town-url.web.val.run/') .then(response => response.json()) .then(data => { console.log(`Latest watched: ${data.title} (${data.year})`); console.log(`Rating: ${data.rating}/5 stars`); });

HTML Integration

<div id="latest-movie"></div> <script> async function loadLatestMovie() { try { const response = await fetch('https://your-val-town-url.web.val.run/'); const movie = await response.json(); document.getElementById('latest-movie').innerHTML = ` <div class="movie-card"> ${movie.posterUrl ? `<img src="${movie.posterUrl}" alt="${movie.title}" width="150">` : '<div style="width:150px;height:225px;background:#2c3440;display:flex;align-items:center;justify-content:center;color:#9ab;font-size:24px;">🎬</div>'} <h3>${movie.title} (${movie.year})</h3> <p>Rating: ${'β˜…'.repeat(movie.rating)}${'β˜†'.repeat(5-movie.rating)}</p> <p>Watched: ${movie.watchDate}</p> <a href="${movie.filmUrl}" target="_blank">View on Letterboxd</a> </div> `; } catch (error) { console.error('Failed to load latest movie:', error); } } loadLatestMovie(); </script>

Caching

The API includes caching headers:

  • Cache-Control: public, max-age=300 (5 minutes)
  • CORS: Enabled for all origins

Error Handling

The API returns appropriate HTTP status codes:

  • 200: Success
  • 404: No diary entries found
  • 500: Server error (network issues, parsing errors, etc.)

Error responses include a descriptive message:

{ "error": "No diary entries found", "message": "The diary appears to be empty or the page structure has changed." }

Technical Details

  • Built with TypeScript on Val Town
  • Scrapes HTML from https://letterboxd.com/pinjasaur/diary/
  • Uses regex patterns to extract structured data
  • Handles various edge cases and fallbacks
  • Image Proxy: Automatically proxies poster images to avoid CORS issues
  • Fallback Images: Returns placeholder SVG when original posters are unavailable
  • Returns high-resolution poster images (300px width) when available

Limitations

  • Only works for public Letterboxd profiles
  • Currently hardcoded to user "pinjasaur"
  • Dependent on Letterboxd's HTML structure (may break if they change their layout)
  • Rate limited by Letterboxd's servers
  • No authentication or private diary support

Future Enhancements

Potential improvements could include:

  • Support for multiple users via query parameters
  • Pagination to get multiple recent entries
  • Additional metadata extraction (genres, director, etc.)
  • Webhook support for real-time updates
  • Better error handling and retry logic
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2026 Val Town, Inc.