Retries and failures
When a pin does not publish, PinBridge either retries it for you or marks it failed with an error code you can act on. This page explains the pin state machine, when retries happen automatically, and how to retry manually.
The pin state machine
Every pin moves through these states:
- queued — created and waiting for a worker.
- publishing — the worker is calling Pinterest right now.
- published — success. The pin has a
pinterest_pin_idand apublished_at. - deferred — a retryable error kept failing, so the pin is parked for a longer retry.
- failed — terminal. The pin has an
error_codeanderror_message.
The happy path is queued → publishing → published. A retryable error sends the pin back to queued (and, after several attempts, to deferred). A non-retryable error goes straight to failed.
queued ──▶ publishing ──▶ published
▲ │
│ (retryable)│ (non-retryable)
└── deferred ◀── (after retries) failed
exhausted ──▶ failed
Automatic retry
PinBridge classifies each publish error as retryable or not.
Retryable errors (rate_limited, transient_upstream, media_url_temporarily_unavailable, and similar) are retried for you:
- The pin resets to
queuedand is re-enqueued after about 60 seconds (or the Pinterest-suppliedretry_after, capped at 300 seconds), plus up to 15 seconds of jitter. This happens up to 3 times. - If it is still failing after those attempts, the pin is parked as
deferredand retried after about 1 hour (orretry_afterif larger), with the attempt counter reset. - A pin can be deferred up to 8 times. After the 8th deferral it is set to
failed.
For a live Pinterest 429, the whole account is briefly paused for the retry_after window before the next attempt.
There is also a backstop: a reconciler runs every 120 seconds. Pins stuck in queued/publishing for more than 10 minutes are re-driven back to queued; pins stuck for more than 6 hours are failed with error_code = publish_timeout.
You do not call anything for automatic retries. They apply only to retryable errors. A non-retryable error fails immediately.
Manual retry
Only failed pins can be retried manually. Retrying a pin in any other state returns 409 “Only failed pins can be retried”.
Retry one pin:
curl -X POST https://api.pinbridge.io/v1/pins/8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93/retry \
-H "X-API-Key: $PINBRIDGE_API_KEY"
Expected response (trimmed):
{"id": "8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93", "status": "queued", "error_code": null, "error_message": null}
Retrying clears the error fields, pinterest_pin_id, and published_at, then re-queues the pin. You can override the board or account on retry, which is useful when the failure was board_access_denied:
curl -X POST https://api.pinbridge.io/v1/pins/8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93/retry \
-H "X-API-Key: $PINBRIDGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"board_id": "987654321098765433"}'
Bulk retry
Retry many failed pins in one call:
curl -X POST https://api.pinbridge.io/v1/pins/bulk-retry \
-H "X-API-Key: $PINBRIDGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids": ["8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93", "1d9b4e7f-6a2c-4f8e-b5d3-9c0a7e2f4b16", "5e7a1c3d-8b4f-4d2a-a6e9-3f1b8c5d7e20"]}'
Each item comes back in one of three buckets:
- succeeded — reset to
queuedand re-enqueued. - skipped with
error_codeineligible_status— the pin was not infailedstate. - failed with
error_codenot_found— no such pin in your project.
There is also POST /v1/pins/bulk-delete if you would rather remove failed pins than retry them.
Python SDK
from pinbridge_sdk import PinbridgeClient
from pinbridge_sdk.models import PinRetryRequest
with PinbridgeClient(api_key="pb_your_api_key") as client:
# Retry one, optionally moving it to another board
client.pins.retry("8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93", PinRetryRequest(board_id="987654321098765433"))
# Retry many
client.pins.bulk_retry(["8a3f6c12-4d5e-4b7a-9c01-2e6f8d4b7a93", "1d9b4e7f-6a2c-4f8e-b5d3-9c0a7e2f4b16"])
Failure error_code reference
When a pin is failed, its error_code tells you the cause. Codes marked “auto-retried” are attempted for you before the pin lands in failed.
| error_code | Cause | Fix |
|---|---|---|
rate_limited |
Pinterest returned a rate-limit (429). | Auto-retried, and the account is paused for the retry window. If it still fails, slow your publish rate. |
token_expired |
The Pinterest OAuth token has expired. | Reconnect the Pinterest account. |
token_revoked |
The token was revoked at Pinterest. | Reconnect the Pinterest account. |
scope_missing |
The OAuth token is missing a required permission scope. | Reconnect the account and grant all requested permissions. |
board_access_denied |
The account cannot write to that board. | Confirm the board belongs to the account, or retry with a different board_id. |
transient_upstream |
A temporary Pinterest 5xx or “temporarily unavailable” error. | Auto-retried; usually clears on its own. Retry manually if it reaches failed. |
media_url_temporarily_unavailable |
Pinterest could not yet fetch PinBridge-hosted media. | Auto-retried after about 120 seconds. |
media_url_unreachable |
Pinterest could not fetch the media URL at all. | Make the image or video URL publicly reachable (returns 200), then retry. |
resource_not_found |
A referenced Pinterest resource is missing. | Verify the board and account exist, then retry. |
invalid_payload |
Pinterest rejected the pin data. | Correct the pin fields (title, link, media) and retry. |
sandbox_board_not_allowed |
Board writes are disabled in the sandbox. | Use a simulated board, or enable sandbox board writes. |
pinterest_board_environment_mismatch |
The board belongs to a different (sandbox vs live) environment. | Use a board created in the same environment as the request. |
publish_timeout |
The pin was stuck too long (over 6 hours) and the reconciler failed it. | Retry the pin. |
account_not_found |
The connected account no longer exists or was revoked. | Reconnect the account, then retry. |
missing_video_asset |
A video pin was created without a video asset. | Provide a valid video asset_id and retry. |
asset_not_found |
The referenced asset is missing. | Re-upload the asset or correct the asset_id, then retry. |
queue_error |
The pin could not be enqueued. | Retry the pin. |
internal_error |
An unexpected error occurred. | Retry; if it persists, contact support. |
api_error |
An unclassified Pinterest error (fallback). | Read error_message, retry, and contact support if it repeats. |
One common cause of a “wrong” title is not a failure at all: Pinterest re-scrapes the destination URL and may override your pin title with the page’s Open Graph or meta tags. Control this by setting good OG tags on the destination page.
Get notified
Subscribe to the pin.failed webhook event to react to failures automatically. The payload is {pin_id, error_code, error_message}. In n8n, receive it with the generic Webhook node. See Receive pin events with a webhook.
Next steps
- Bulk imports (CSV and JSON) — import many pins and read per-row failures.
- Activity logs — audit publish successes and failures over time.
- Troubleshooting in n8n — fixes for credential and publish errors.
