Home / Docs / Schedule pins

Schedule pins

Publish a pin at a future time with POST /v1/schedules. A schedule carries the same media and pin details you’d send to Publish pins, plus a run_at timestamp. A background task materializes the pin when the time arrives.

Prerequisites

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

Fields a schedule supports

A ScheduleCreate accepts:

Field Required Notes
account_id yes Connected Pinterest account (UUID).
run_at yes Future ISO 8601 timestamp with a timezone offset (see below).
board_id yes Pinterest board id.
title yes Max 100 characters.
description no Max 800 characters.
link_url no Destination URL, max 2048 characters.
one of image_url / asset_id yes Exactly one, same rule as publishing.
cover_image_url / cover_image_asset_id no Video pins only; at most one.

Schedule fields vs. publish fields

Schedules carry fewer fields than a direct publish. These PinCreate fields are not part of ScheduleCreate:

  • related_terms
  • alt_text
  • dominant_color

If you need those, publish directly with Publish pins instead of scheduling.

run_at rules

  • Must include an explicit timezone offset (for example 2026-12-25T09:00:00-05:00 or ...Z). A naive timestamp is rejected with 422. It’s normalized to UTC on the server.
  • Must be in the future, else 400 run_at must be in the future.

Create a schedule

curl

curl -X POST https://api.pinbridge.io/v1/schedules \
  -H "X-API-Key: $PINBRIDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41",
    "board_id": "987654321098765432",
    "title": "Holiday promo pin",
    "image_url": "https://example.com/pin.png",
    "link_url": "https://example.com/promo",
    "run_at": "2026-12-25T09:00:00-05:00"
  }'

Response (201, trimmed):

{
  "id": "c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64",
  "pinterest_account_id": "6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41",
  "run_at": "2026-12-25T14:00:00Z",
  "status": "scheduled",
  "pin_id": null,
  "last_error": null
}

Python SDK

from datetime import datetime, timezone
from pinbridge_sdk import PinbridgeClient
from pinbridge_sdk.models import ScheduleCreate

with PinbridgeClient(api_key="$PINBRIDGE_API_KEY") as client:
    schedule = client.schedules.create(
        ScheduleCreate(
            account_id="6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41",
            board_id="987654321098765432",
            title="Holiday promo pin",
            image_url="https://example.com/pin.png",
            run_at=datetime(2026, 12, 25, 14, 0, tzinfo=timezone.utc),
        )
    )
    print(schedule.id, schedule.status)

run_at must be timezone-aware.

n8n

Use the PinBridge node with Resource: Schedule, Operation: Create. Set Run At (a dateTime), the Connection, Board, Title, and Media Source. Note the schedule form has no Alt Text, Related Terms, or Dominant Color fields, matching the API.

Schedule statuses

A schedule’s status is one of:

scheduledqueuedrunningdone on success. Retryable errors go to deferred; a hard failure is failed; a canceled schedule is canceled. Once the pin is created you can follow it with pin_id and the pin’s own publish states.

Manage schedules

List and fetch

curl "https://api.pinbridge.io/v1/schedules?limit=50&offset=0" \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

curl "https://api.pinbridge.io/v1/schedules/c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64" \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

Cancel, retry, delete

# Cancel a pending schedule
curl -X POST https://api.pinbridge.io/v1/schedules/c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64/cancel \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

# Retry a failed schedule
curl -X POST https://api.pinbridge.io/v1/schedules/c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64/retry \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

# Delete a schedule (returns 204 No Content)
curl -X DELETE https://api.pinbridge.io/v1/schedules/c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64 \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

Cancel, retry, and delete are status-dependent: you’ll get a 400 such as Cannot cancel schedule with status <status>, Cannot retry schedule with status <status>, or Cannot delete schedule with status <status>; cancel it first. when the current status doesn’t allow the action.

In the SDK: client.schedules.cancel(id), client.schedules.retry(id), client.schedules.delete(id).

Bulk actions

Each bulk endpoint takes { "ids": [...] } with up to 500 ids.

curl -X POST https://api.pinbridge.io/v1/schedules/bulk-cancel \
  -H "X-API-Key: $PINBRIDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64", "9f5b3d1e-2a7c-4b8d-a4e6-6c0f1b9d5e27"]}'

Response (200, trimmed):

{
  "succeeded_count": 1,
  "skipped_count": 1,
  "failed_count": 0,
  "results": [
    {"id": "c4e2a9b1-7d3f-4e6a-8b50-1f9d2c7e3a64", "status": "succeeded"},
    {"id": "9f5b3d1e-2a7c-4b8d-a4e6-6c0f1b9d5e27", "status": "skipped", "error_code": "ineligible_status"}
  ]
}

The same shape applies to POST /v1/schedules/bulk-retry and POST /v1/schedules/bulk-delete (SDK: client.schedules.bulk_cancel(ids), bulk_retry(ids), bulk_delete(ids)).

Verify it worked

  • The create response returns 201 with status: scheduled and the run_at normalized to UTC.
  • Fetch with GET /v1/schedules/{schedule_id} and watch status advance.
  • Once pin_id is set, follow the pin with GET /v1/pins/{pin_id} or a webhook.

Common errors

Status Cause
422 run_at missing a timezone offset, or a missing required field.
400 run_at must be in the future.
400 Cannot cancel / retry / delete schedule with status <status>.
403 feature_unavailable — used an asset_id on the Free plan.

Next steps

  • Publish pins — publish immediately, and the full field reference.
  • Upload media — host media and schedule an asset-backed pin.
  • Webhooks — get notified when a scheduled pin publishes or fails.
  • Rate limits and quotas — how scheduled publishes count against quota.
Last updated September 13, 2026Was this page helpful? Tell us →