Skip to content
Home / Docs / Publish pins

Publish pins

Create a pin with POST /v1/pins. This page covers every field on the request, the media options, and the state a pin moves through after you submit it.

Prerequisites

  • An API key in the X-API-Key header. See Authentication.
  • A connected Pinterest account (account_id) and a board on it (board_id).
  • Media: either a public image_url, or an uploaded asset_id. See Upload media.

Pin fields

Every request is a PinCreate object.

Required

Field Type Notes
account_id UUID The connected Pinterest account to publish with.
board_id string The Pinterest board id.
title string Max 100 characters.
idempotency_key string Max 255 characters. Required, never auto-generated. Reusing a key returns the existing pin instead of creating a duplicate.
one of image_url / asset_id string Exactly one is required (see Media options).

Optional

Field Type Notes
description string Max 800 characters.
alt_text string Max 500 characters. Accessibility text.
dominant_color string 6-digit hex, optional leading # (for example #6E7874); normalized to upper-case.
link_url string Destination URL, max 2048 characters.
cover_image_url string Public cover image URL. Video pins only.
cover_image_asset_id UUID Uploaded image asset used as a video cover. Video pins only.

related_terms is deprecated. Pinterest doesn’t list it for creating or reading a pin, so PinBridge stopped sending it in API 1.65.1. A request that still includes it keeps working and the value is ignored. Pin responses keep the field for now: null for new pins, the stored value for older ones. To find keyword ideas for your titles and descriptions, use List Related Terms.

Media options

Provide the pin’s media in exactly one way:

  • Public image URL — set image_url. Works on every plan.
  • Uploaded asset — set asset_id from an uploaded image or video. Paid plans only; see Upload media.

Notes:

  • Provide exactly one of image_url / asset_id. Both missing or both present each return 422.
  • A video pin is created by referencing an uploaded video asset_id. There is no video_url field.
  • Cover images (cover_image_url / cover_image_asset_id) apply only to video pins, and you may set at most one of the two.

Heads up: Pinterest can change your title. When your pin has a link_url, Pinterest re-scrapes that destination page and may override your pin title with the page’s Open Graph / meta tags. If your published title doesn’t match what you sent, this is almost always why. Control it by setting good og:title (and og:description) meta tags on the destination page. This is the most common “my title changed” surprise.

Publish a pin

curl

curl -X POST https://api.pinbridge.io/v1/pins \
  -H "X-API-Key: $PINBRIDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41",
    "board_id": "987654321098765432",
    "title": "My first PinBridge pin",
    "description": "A short, useful description.",
    "link_url": "https://example.com/product",
    "image_url": "https://example.com/pin.png",
    "idempotency_key": "publish-demo-001"
  }'

Response (201, trimmed):

{
  "id": "8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93",
  "status": "queued",
  "media_type": "image",
  "title": "My first PinBridge pin",
  "board_id": "987654321098765432",
  "idempotency_key": "publish-demo-001",
  "pinterest_pin_id": null,
  "error_code": null
}

The pin is accepted as queued and published by a background worker. Poll its status or use a webhook to learn the outcome.

Python SDK

from pinbridge_sdk import PinbridgeClient
from pinbridge_sdk.models import PinCreate

with PinbridgeClient(api_key="$PINBRIDGE_API_KEY") as client:
    pin = client.pins.create(
        PinCreate(
            account_id="6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41",
            board_id="987654321098765432",
            title="My first PinBridge pin",
            image_url="https://example.com/pin.png",   # or asset_id="e3a7c5f9-1b4d-4c8e-a2f6-7d9b3e5a1c80"
            link_url="https://example.com/product",
            idempotency_key="publish-demo-001",
        )
    )
    print(pin.id, pin.status)

idempotency_key is a required field on PinCreate. To publish a video pin, drop image_url and pass asset_id for an uploaded video.

n8n

Use the PinBridge node with Resource: Pin, Operation: Publish. Choose the Media Source (Uploaded Asset or Public Image URL) and fill in Title, Board, and the account Connection. The Idempotency Key field defaults to ={{$execution.id + "-" + $itemIndex}}, which gives each item a stable, unique key.

Pin states

A pin moves through these statuses:

  • queued → publishing → published on success (sets pinterest_pin_id and published_at).
  • failed on a non-retryable error (sets error_code and error_message).
  • Retryable errors move the pin to deferred and auto-retry, up to 8 deferrals, before finally becoming failed.

Common failure error_code values include rate_limited, token_expired, token_revoked, scope_missing, board_access_denied, transient_upstream, media_url_unreachable, invalid_payload, and publish_timeout. See Rate limits and quotas for how retries and quota interact.

To reprocess failures: POST /v1/pins/{pin_id}/retry (only failed pins; otherwise 409), or the bulk endpoints POST /v1/pins/bulk-retry and POST /v1/pins/bulk-delete.

Verify it worked

  • Fetch the pin with GET /v1/pins/{pin_id} (SDK: client.pins.get(pin_id)) and check status.
  • When status is published, pinterest_pin_id holds the id of the live Pinterest pin.
  • For push notifications instead of polling, subscribe to pin.published and pin.failed webhooks.

Common errors

Status Cause
422 Either image_url or asset_id must be provided / Provide either image_url or asset_id, not both.
422 Missing a required field such as account_id, or title over 100 chars.
403 feature_unavailable — used an asset_id on the Free plan. Use a public image_url or upgrade.
400 cover_image_url is only supported for video pins.

Next steps

Last updated October 30, 2026 Was this page helpful? Tell us →