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
| Item | Pinterest limit or support |
|---|---|
| Platform value | pinterest |
| Supported post type | Image pin |
Description (content) | 500 characters maximum |
| Media per pin | Exactly 1 image |
| Image formats | JPEG/JPG, PNG, WebP |
| Maximum image size | 32 MB |
| Recommended dimensions | 1000×1500 pixels |
| Recommended aspect ratio | 2:3 portrait |
| Pin title | 100 characters maximum |
| Alt text | 500 characters maximum |
| Video pins | Not yet supported — coming soon |
| GIF pins | Not yet supported — coming soon |
| Scheduling | Supported |
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.boardIdwhen 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
contentat or below 500 characters. The optional pin title is limited to 100 characters, andaltTextis 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
402until 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 minutesresponse = 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 minutescurl "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
| Requirement | Value |
|---|---|
| Images per pin | Exactly 1 |
| Accepted static formats | JPEG/JPG, PNG, WebP |
| Maximum file size | 32 MB |
| Recommended dimensions | 1000×1500 pixels |
| Recommended aspect ratio | 2:3 portrait |
| URL access | Publicly 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 type | Current support | Notes |
|---|---|---|
| Video | Not supported | Video pins are coming soon and are currently rejected. |
| GIF | Not supported | GIF pins are coming soon and are currently rejected. |
Platform settings
Place Pinterest settings inside the matching target object in platforms.
| Setting | Type | Notes |
|---|---|---|
boardId | string | Pinterest board to publish to. When omitted, PostZen uses the account's saved default board. |
title | string | Searchable pin title, limited to 100 characters. |
link | string (URI) | Destination link for the pin. Must be a valid URL. |
altText | string | Image 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 limit | Allowance | Applies to |
|---|---|---|
Writes (org_write) | 100 requests per minute | Creating pins and boards. This is the limit pin publishing consumes. |
Reads (org_read) | 1,000 requests per minute | Fetching the connected account, its boards, and its pins. |
| Universal ceiling | 100 requests per second | Every 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
| Error | Meaning | Fix |
|---|---|---|
Missing boardId | The 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 type | The 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 long | content exceeds 500 characters. | Shorten the description to 500 characters or fewer. |
| Title is too long | settings.title exceeds 100 characters. | Shorten the title to 100 characters or fewer. |
Invalid link | settings.link is not a valid URL. | Pass a valid destination URL or omit link. |
429 from Pinterest | You exceeded Pinterest's rate limit for the connected account. | Nothing — PostZen retries automatically after the window resets. |
| Insufficient token permissions | The 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 connecting | You 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 expired | The connect flow was not completed within 10 minutes. | Request a new Pinterest connect URL and complete OAuth with the new authUrl. |