Publishing to Pinterest via API: A technical guide

Understanding OAuth, boards, pin creation, video uploads, and API endpoints for Pinterest content publishing.

Publishing to Pinterest via API: A technical guide

Before you start: App access

Before your app can create pins on Pinterest, you need to set up API access:

  1. Create a Pinterest app at developers.pinterest.com and obtain your app_id and app_secret
  2. Request access — New apps start in trial mode with access limited to the app owner’s account. Submit your app for review to publish on behalf of other users.

Required permissions

To create pins and access analytics, your app needs these OAuth scopes:

  • user_accounts:read — Access basic account information
  • pins:read — Read pin data and analytics
  • pins:write — Create and manage pins
  • boards:read — List and read board data
  • boards:write — Create and manage boards

Request all required scopes during the OAuth authorization flow.

Authentication

Pinterest uses standard OAuth 2.0. Exchange an authorization code for tokens by POSTing to https://api.pinterest.com/oauth/token with HTTP Basic Auth (app_id:app_secret):

POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=<AUTH_CODE>&redirect_uri=<REDIRECT_URI>

Returns:

{
"access_token": "pina_...",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "pinr_...",
"refresh_token_expires_in": 5184000,
"scope": "user_accounts:read pins:read pins:write boards:read boards:write"
}

Refresh tokens expire after 60 days but can be refreshed indefinitely using grant_type=refresh_token.

Listing boards

Pins must be published to a board. List the user’s boards with a GET to https://api.pinterest.com/v5/boards:

GET /v5/boards?page_size=25
Authorization: Bearer <ACCESS_TOKEN>

Returns paginated results with id, name, privacy, and pin_count for each board. Use the bookmark parameter for pagination.

Creating an image pin

POST to https://api.pinterest.com/v5/pins:

{
"board_id": "1234567890",
"title": "Pin title",
"description": "Pin description",
"link": "https://example.com/page",
"media_source": {
"source_type": "image_url",
"url": "https://example.com/image.jpg"
}
}

The media_source object supports several source types:

  • image_url — Provide a publicly accessible image URL
  • image_base64 — Provide base64-encoded image data with content_type (image/jpeg or image/png)
  • pin_url — Repin from an existing pin URL

Title is limited to 100 characters, description to 800 characters.

Carousels contain 2–5 images in a single pin. Use the multiple_image_urls source type:

{
"board_id": "1234567890",
"title": "Carousel pin",
"description": "Multiple images in one pin",
"media_source": {
"source_type": "multiple_image_urls",
"items": [
{ "url": "https://example.com/image1.jpg" },
{ "url": "https://example.com/image2.jpg" },
{ "url": "https://example.com/image3.jpg" }
]
}
}

Unlike Instagram carousels, Pinterest carousels are created in a single request — no separate container steps.

Publishing videos

Video pins require a multi-step upload flow:

Step 1: Register the media upload

POST to https://api.pinterest.com/v5/media:

{
"media_type": "video"
}

Returns an upload_url and upload_parameters:

{
"media_id": "12345",
"media_type": "video",
"upload_url": "https://pinterest-media-upload.s3-accelerate.amazonaws.com/",
"upload_parameters": {
"Content-Type": "multipart/form-data",
"key": "uploads/...",
"policy": "eyJ...",
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-credential": "...",
"x-amz-date": "...",
"x-amz-security-token": "...",
"x-amz-signature": "..."
}
}

Step 2: Upload the video file

POST the video as multipart/form-data to the upload_url, including all upload_parameters as form fields alongside the file. This uploads directly to S3.

Step 3: Poll for processing status

GET https://api.pinterest.com/v5/media/{media_id} until status is succeeded:

{
"media_id": "12345",
"media_type": "video",
"status": "succeeded"
}

Possible status values:

  • registered — Upload registered, file not yet uploaded
  • processing — File uploaded, being processed
  • succeeded — Ready to use in pin creation
  • failed — Processing failed

Step 4: Create the video pin

POST to https://api.pinterest.com/v5/pins with the video_id source type:

{
"board_id": "1234567890",
"title": "Video pin",
"description": "Video description",
"media_source": {
"source_type": "video_id",
"media_id": "12345"
}
}

Pin analytics

GET https://api.pinterest.com/v5/pins/{pin_id}/analytics with required query parameters:

GET /v5/pins/{pin_id}/analytics?start_date=2026-01-01&end_date=2026-01-31&metric_types=IMPRESSION,PIN_CLICK,SAVE

Available metrics include IMPRESSION, OUTBOUND_CLICK, PIN_CLICK, SAVE, SAVE_RATE, TOTAL_COMMENTS, and TOTAL_REACTIONS. Video pins also support VIDEO_MRC_VIEW and watch time metrics.

Analytics data is available for up to 90 days back from today.

Rate limits

Pinterest enforces rate limits per app and per user across three categories:

  • org_read — Board listing, media status checks
  • org_write — Pin creation, media registration
  • org_analytics — Pin analytics

Exceeding limits returns HTTP 429. Specific numeric limits are not published in the API documentation.

The same pin, through Postproxy

Here’s how it’s done with Postproxy. One simple request with only what matters:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "3 tips that changed how we approach customer onboarding"
},
"profiles": ["pinterest"],
"media": ["https://example.com/image.jpg"]
}'

One request. Postproxy handles the board selection, media upload, processing status polling, and pin creation.

What Postproxy handles

Postproxy maintains approved access and handles the complexity:

  • OAuth token exchange and continuous refresh
  • Board listing and selection
  • Direct image pins and multi-step video uploads
  • Carousel pin creation from multiple images
  • Upload status polling for video processing
  • Rate limit monitoring and request pacing

Your system sends content. Postproxy handles the Pinterest-specific implementation.

Connect your Pinterest account and start publishing through the Postproxy API.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.