Skip to main content

Quick reference

FieldValue
Title limit100 characters
Description limit500 characters
Images per pin1 (standard) or 2–5 (carousel)
Videos per pin0 (Pinterest video pins not exposed)
Image formatsJPEG, PNG
Max image size20 MB
Aspect ratio2:3 recommended (long pin)
Min resolution600 × 900
Carousel aspect ratio1:1 or 2:3 only
BoardRequired — pick at compose time
Outbound link✅ Per-pin click destination
First comment❌ Pinterest doesn’t expose comment API
Post typesPin (single), Carousel pin

Before you start

Pinterest requires every pin to land on a specific board. You must pass the board ID in platformOptions — there’s no default board at the API layer (the compose UI pre-fills one from the connected account, but the API does not). The compose dashboard fetches the available board list at connect time and stores it on the SocialAccount; pulling the list dynamically from the public API isn’t available in v1.
See Platform settings → Pinterest for the full schema and Media uploads for how to attach images. Required scopes (granted by the connect flow):
  • boards:read — list the boards you can pin to.
  • boards:read_secret — list secret boards.
  • pins:read, pins:write — read + create pins.
Pinterest carousel pins are image-only. Mixing video isn’t supported by the API at all (video pins go through a separate flow we haven’t shipped yet).

Quick start

Workspace is inferred from your API key — no workspaceId argument. Pinterest always needs platformOptions.board because every pin lands on a specific board — so even the flat-shape quickstart sets it. Drop to the nested shape when you want a different stylistic layout for the same request.
import Postbreeze from "@postbreeze/node";

const postbreeze = new Postbreeze({ apiKey: process.env.POSTBREEZE_API_KEY });

const post = await postbreeze.posts.create({
  content: "20 minimalist home office setups for 2026",
  scheduledFor: new Date(Date.now() + 30_000).toISOString(),
  mediaItems: [{ type: "IMAGE", url: "https://cdn.example.com/office.jpg" }],
  platforms: [
    {
      accountId: "soc_pinterest_…",
      platformOptions: {
        platform: "PINTEREST",
        board: "pinterest_board_id_…",
        title: "20 minimalist home office setups",
        link: "https://example.com/blog/home-office-setups",
      },
    },
  ],
});

Content types

Single-image pin

Default. Pass exactly one image — either inline via mediaItems or by reference via mediaIds (see Media uploads). Pass 2–5 image mediaIds (or mediaItems). All slides must share the same aspect ratio (1:1 OR 2:3) — Pinterest rejects mixed aspects at the API.
const post = await postbreeze.posts.create({
  content: "Bathroom renovation — before & after",
  scheduledFor: new Date(Date.now() + 30_000).toISOString(),
  mediaIds: ["med_before_1", "med_after_1", "med_before_2", "med_after_2"],
  platforms: [
    {
      accountId: "soc_pinterest_…",
      platformOptions: {
        platform: "PINTEREST",
        board: "pinterest_board_id_…",
        title: "Bathroom before & after",
        link: "https://example.com/case-study/bath",
      },
    },
  ],
});

Media requirements

Images

PropertyRequirement
Images per pin1 (standard), 2–5 (carousel)
FormatsJPEG, PNG
Max file size20 MB
Min resolution600 × 900
Aspect ratio (single)2:3 recommended; 1:2.1 is “long pin” cutoff
Aspect ratio (carousel)1:1 OR 2:3 (consistent across all slides)
Pinterest down-scales anything above 1,200 × 1,800. Higher resolutions are accepted but offer no display advantage.

Platform-specific fields

See the full schema at Platform settings → Pinterest.
FieldTypeRequiredDescription
platform"PINTEREST"YesDiscriminator.
boardstringYesPinterest board ID where the pin lands. No default at the API layer.
titlestringNoPin title (≤ 100 chars).
linkURLNoOutbound click destination. Tracked as outbound_click_rate in analytics.
The pin’s description comes from the post-level content field — Pinterest caps it at 500 chars. firstComment is not supported on Pinterest — the platform doesn’t expose a commercial comment API. Passing one is rejected at validation.

Analytics

Pinterest analytics include some signature metrics not exposed elsewhere:
MetricAvailable
Impressions
Closeups (pin detail page opens)
Saves
Save rate (saves / impressions)
Engagement
Engagement rate
Outbound clicks
Outbound click rate
Monthly viewers (account)
Video views❌ (video pins not yet exposed)
Refresh cadence: every 14 days.

Common errors

ErrorMeaningFix
PIN_BOARD_REQUIREDboard missing from platformOptionsPass a board ID.
PIN_BOARD_NOT_FOUNDThe board ID isn’t owned by this Pinterest accountList boards via the API and pick a valid one.
PIN_CAROUSEL_SIZECarousel with < 2 or > 5 imagesTrim to 2–5.
PIN_MIXED_ASPECTCarousel slides have different aspect ratiosResize so every slide is 1:1 OR 2:3.
PIN_VIDEO_NOT_SUPPORTEDVideo in mediaIdsPinterest video pins are deferred.
PIN_LINK_INVALIDThe link URL didn’t resolveVerify the URL works in an incognito browser.
PIN_RATE_LIMITEDPinterest per-account rate limitPostbreeze retries with backoff.

What you can’t do

  • ❌ Video pins (planned for v2)
  • ❌ Idea pins (deprecated by Pinterest)
  • ❌ Story pins
  • ❌ Schedule via Pinterest’s native scheduler
  • ❌ Edit a pin after publish (Pinterest deleted that API)
  • ❌ Add to multiple boards at once (one pin = one board; create multiple posts)
  • ❌ Section pins (sub-boards) at the API
  • ❌ Tag products (catalog feature, separate API)
  • ❌ First comment (no commercial comment API)

Full control: nested shape

The nested shape (caption + targets + scheduledAt + socialAccountId) is functionally identical to the flat shape — pick whichever reads better in your codebase. Every Pinterest target still requires platformOptions.board.
Node.js
import Postbreeze from "@postbreeze/node";

const postbreeze = new Postbreeze({ apiKey: process.env.POSTBREEZE_API_KEY });

const post = await postbreeze.posts.create({
  caption: "20 minimalist home office setups for 2026",
  scheduledAt: new Date(Date.now() + 30_000).toISOString(),
  mediaIds: ["med_image_…"],
  targets: [
    {
      socialAccountId: "soc_pinterest_…",
      platformOptions: {
        platform: "PINTEREST",
        board: "pinterest_board_id_…",
        title: "20 minimalist home office setups",
        link: "https://example.com/blog/home-office-setups",
      },
    },
  ],
});