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.
related_terms string[] Related terms for Pinterest. Also accepts a comma-separated string.
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.

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:

  • queuedpublishingpublished 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 September 13, 2026Was this page helpful? Tell us →