PostZen

Pinterest

Publish and schedule single-image pins to Pinterest boards with PostZen.

PostZen publishes and schedules image pins to Pinterest boards through the same Posts API used for other platforms. Each Pinterest target uses either an explicit board ID or the connected account's default board, and requires exactly one static image.

Pinterest supports only a single image per pin. Set a default board on the account or pass settings.boardId for the target. Video and GIF pins are coming soon and are not yet supported.

Quick reference

ItemPinterest limit or support
Platform valuepinterest
Supported post typeImage pin
Description (content)500 characters maximum
Media per pinExactly 1 image
Image formatsJPEG/JPG, PNG, WebP
Maximum image size32 MB
Recommended dimensions1000×1500 pixels
Recommended aspect ratio2:3 portrait
Pin title100 characters maximum
Alt text500 characters maximum
Video pinsNot yet supported — coming soon
GIF pinsNot yet supported — coming soon
SchedulingSupported

Before you start

You need a PostZen profile and a Pinterest account to authorize through OAuth 2.0. Use the board endpoints to list the account's boards, create a board, and save the board that PostZen should use by default.

Keep these requirements in mind:

  • Every pin needs a board. PostZen uses settings.boardId when provided, then falls back to the account's saved default board.
  • Attach exactly one static image. Pinterest rejects pins with no image, more than one image, a video, or a GIF.
  • Keep the description in content at or below 500 characters. The optional pin title is limited to 100 characters, and altText is limited to 500 characters.
  • If you set link, it must be a valid URL.
  • The free tier allows 2 connected accounts before a payment method is required. Connecting another account returns a 402 until you add a payment method.

Your media URL must be a publicly accessible direct link to the image file. Cloud-storage share links from Google Drive, Dropbox, OneDrive, or iCloud return HTML pages instead of files and will not work. You can upload an image through POST /v1/media/presign and use the returned publicUrl instead.

Connect your account

Request a Pinterest connect URL for the profile that will own the account. PostZen returns { authUrl, state }; redirect the user to authUrl to complete OAuth. The state expires after 10 minutes.

const { data } = await postzen.connect.createConnectUrl({
  path: { platform: 'pinterest' },
  query: {
    profileId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
    redirectUrl: 'https://yourapp.com/connected',
  },
});

console.log(data.authUrl); // redirect the user here
console.log(data.state);   // expires after 10 minutes
response = client.connect.create_connect_url(
    "pinterest",
    profile_id="jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
    redirect_url="https://yourapp.com/connected",
)

print(response.authUrl)  # redirect the user here
print(response.state)    # expires after 10 minutes
curl "https://api.postzen.dev/v1/connect/pinterest?profileId=jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e&redirectUrl=https://yourapp.com/connected" \
  -H "Authorization: Bearer $POSTZEN_API_KEY"

For an API-driven connect, keep the returned state. After OAuth completes, call GET /v1/connect/pinterest/select-board with that state to list the newly connected account's boards. Then call POST /v1/connect/pinterest/select-board to verify a board and save it as the account default. The board-selection handle remains available for 30 minutes from the start of the connect flow, even though OAuth itself must finish within 10 minutes.

For an account that is already connected, use GET /v1/accounts/{accountId}/pinterest-boards to list boards or POST /v1/accounts/{accountId}/pinterest-boards to create one. Save the default with PUT /v1/accounts/{accountId}/pinterest-boards. PostZen verifies the board with Pinterest before storing it.

Quick start

Create an image pin by passing one image in mediaItems and the Pinterest fields in the target's settings object. This example chooses a board explicitly; omit boardId to use the account's saved default. It publishes immediately; use scheduledFor instead of publishNow to schedule the pin.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'A quiet workspace for focused afternoons.',
    publishNow: true,
    mediaItems: [
      { url: 'https://cdn.example.com/images/workspace.jpg' },
    ],
    platforms: [
      {
        platform: 'pinterest',
        accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
        settings: {
          boardId: 'your-pinterest-board-id',
          title: 'A calm workspace',
          link: 'https://example.com/workspace',
          altText: 'A bright desk beside a window with a chair and a small plant.',
        },
      },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="A quiet workspace for focused afternoons.",
    publish_now=True,
    media_items=[
        {"url": "https://cdn.example.com/images/workspace.jpg"},
    ],
    platforms=[
        {
            "platform": "pinterest",
            "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
            "settings": {
                "board_id": "your-pinterest-board-id",
                "title": "A calm workspace",
                "link": "https://example.com/workspace",
                "alt_text": "A bright desk beside a window with a chair and a small plant.",
            },
        },
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "A quiet workspace for focused afternoons.",
    "publishNow": true,
    "mediaItems": [
      { "url": "https://cdn.example.com/images/workspace.jpg" }
    ],
    "platforms": [
      {
        "platform": "pinterest",
        "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
        "settings": {
          "boardId": "your-pinterest-board-id",
          "title": "A calm workspace",
          "link": "https://example.com/workspace",
          "altText": "A bright desk beside a window with a chair and a small plant."
        }
      }
    ]
  }'

Set exactly one creation mode on the post: publishNow, scheduledFor, or isDraft. A scheduled timestamp must be ISO-8601 and at least 60 seconds in the future.

Content types

Image pins

Image pins are the only Pinterest content type PostZen currently supports. Attach exactly one JPEG/JPG, PNG, or WebP image and provide a board ID in the Pinterest target or configure a default board on the account.

{
  mediaItems: [
    { url: 'https://cdn.example.com/images/pin.jpg' },
  ],
  platforms: [
    {
      platform: 'pinterest',
      accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
      settings: {
        boardId: 'your-pinterest-board-id',
        title: 'Pin title',
        link: 'https://example.com/destination',
        altText: 'A description of the image.',
      },
    },
  ],
}

The standard pin recommendation is a 1000×1500-pixel image with a 2:3 portrait aspect ratio.

Media requirements

Images

RequirementValue
Images per pinExactly 1
Accepted static formatsJPEG/JPG, PNG, WebP
Maximum file size32 MB
Recommended dimensions1000×1500 pixels
Recommended aspect ratio2:3 portrait
URL accessPublicly accessible direct file URL, or a PostZen publicUrl

The 1000×1500 size and 2:3 ratio are recommendations. The single-image count and 32 MB file-size limit are enforced.

Video and GIF

Media typeCurrent supportNotes
VideoNot supportedVideo pins are coming soon and are currently rejected.
GIFNot supportedGIF pins are coming soon and are currently rejected.

Platform settings

Place Pinterest settings inside the matching target object in platforms.

SettingTypeNotes
boardIdstringPinterest board to publish to. When omitted, PostZen uses the account's saved default board.
titlestringSearchable pin title, limited to 100 characters.
linkstring (URI)Destination link for the pin. Must be a valid URL.
altTextstringImage alt text, limited to 500 characters.
{
  platform: 'pinterest',
  accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
  settings: {
    boardId: 'your-pinterest-board-id',
    title: 'A calm workspace',
    link: 'https://example.com/workspace',
    altText: 'A bright desk beside a window with a chair and a small plant.',
  },
}

Rate limits

Pinterest applies its own rate limits on top of PostZen's API rate limits. Pinterest counts requests per user per app, so each connected Pinterest account has its own allowance — connecting more accounts does not reduce the headroom of the ones you already have.

Pinterest limitAllowanceApplies to
Writes (org_write)100 requests per minuteCreating pins and boards. This is the limit pin publishing consumes.
Reads (org_read)1,000 requests per minuteFetching the connected account, its boards, and its pins.
Universal ceiling100 requests per secondEvery Pinterest API request, across all categories.

Pinterest reports the current window in the x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset response headers. PostZen queues and spaces Pinterest publishes for you, and when Pinterest returns 429 it defers the retry until the window resets, honoring Retry-After or x-ratelimit-reset. Scheduled pins are never lost — they are deferred and publish once the limit clears. You do not need to do anything.

For the full category list, see Pinterest's rate limits reference.

PostZen analytics is live for Pinterest, including pin metrics, follower counts, and best-time-to-post suggestions. Pinterest reports impressions, clicks, saves, comments, and reactions per pin; it does not report reach or shares.

What you can't do

  • Post a video or GIF pin. Both are coming soon and are not yet supported.
  • Attach more than one image or create a multi-image pin or carousel.
  • Create Idea Pins.
  • Edit or delete a pin after it has published.
  • Create Rich Pins or publish shopping catalogs.
  • Read or manage DMs, inbox messages, or comments.
  • Manage ads or receive engagement webhooks.

Common errors

ErrorMeaningFix
Missing boardIdThe target omitted a board ID and the account has no saved default board.Pass settings.boardId, or list the account's boards and save one with the default-board endpoint.
Invalid media count or typeThe request has no image, more than one image, a video, or a GIF.Attach exactly one JPEG/JPG, PNG, or WebP image no larger than 32 MB.
Description is too longcontent exceeds 500 characters.Shorten the description to 500 characters or fewer.
Title is too longsettings.title exceeds 100 characters.Shorten the title to 100 characters or fewer.
Invalid linksettings.link is not a valid URL.Pass a valid destination URL or omit link.
429 from PinterestYou exceeded Pinterest's rate limit for the connected account.Nothing — PostZen retries automatically after the window resets.
Insufficient token permissionsThe connected account's token is missing a scope Pinterest requires to create pins.Reconnect the Pinterest account and accept every permission the consent screen requests.
402 while connectingYou already have 2 connected accounts on the free tier and do not have a payment method on file.Add a payment method, then start a new connect flow.
OAuth state expiredThe connect flow was not completed within 10 minutes.Request a new Pinterest connect URL and complete OAuth with the new authUrl.

On this page