This workflow lets you publish Pinterest Pins in bulk from a Google Sheet using PinBridge as the publishing layer.
It is designed for builders who want a practical, repeatable workflow instead of manually creating Pins one by one. The flow reads rows from Google Sheets, skips rows that are already complete, validates the required fields, downloads each image, uploads that image through PinBridge, submits the Pinterest publish job, and writes the result back into the same sheet.
The goal is not just to publish. The goal is to publish in a way that is operationally clean, easy to review, and safe to run repeatedly.
A lot of Pinterest automation starts simple and then becomes messy very quickly:
This workflow solves that by turning Google Sheets into a lightweight publishing queue.
You prepare rows in a sheet, run the workflow, and the workflow does the following:
Pins sheetThat gives you a simple but effective operational loop.
This workflow is intentionally built around PinBridge rather than direct Pinterest API glue.
PinBridge is the publishing layer in the middle. In this workflow, PinBridge is responsible for the Pinterest-facing publish operation while n8n remains the orchestration layer.
That separation is useful because it keeps the workflow focused on:
instead of forcing the workflow to also become a Pinterest delivery engine.
In other words:
That is the architecture this template is meant to demonstrate.
You need four things before importing and running this workflow:
You also need a Google Sheet that matches the expected format described below.
Create your PinBridge account first.
Head to pinbridge.io and click register at the top right corner. You can start with just a free account and upgrade later if you need more volume.
You will need two things from PinBridge for this workflow:
Inside PinBridge, create an API key that will be used by the n8n workflow.
To create a new key, go to App > API Keys > Create. Make sure that you:
n8n-bulk-publishAfter the key is created, go into n8n and create the PinBridge credential used by the PinBridge nodes in this workflow.
Before this workflow can run, your n8n instance must have the PinBridge community node installed.
This workflow uses the following PinBridge nodes:
If the PinBridge node is not installed, these nodes will either be missing or show as unknown after import.
If your n8n instance allows community nodes:
n8n-nodes-pinbridgeAfter installation, re-open the workflow and confirm that the PinBridge nodes load correctly.
Some hosted or restricted n8n environments do not allow custom community nodes. If that applies to your environment, you will need either:
Create a Google Sheet with a tab named:
Pins
The workflow expects one row per Pin.
Use this exact header structure:
| row_id | title | description | link_url | image_url | board_id | alt_text | dominant_color | status | job_id | published_at | error_message |
|---|
row_idA unique identifier for the row.
Use something stable and simple, for example:
pin-001spring-cake-012026-03-15-001This value is important because the workflow uses it to update the correct row later.
titleThe Pinterest Pin title.
descriptionThe Pinterest Pin description.
link_urlThe destination URL users should visit when they click the Pin.
This should be a full public URL such as:
https://example.com/post-name
image_urlA public image URL that n8n can download.
This must point directly to a reachable image file. If the image URL requires login, expires quickly, or redirects badly, the workflow may fail.
board_idThe Pinterest board ID to publish to.
This must be the board ID expected by PinBridge, not just a board name.
alt_textOptional, but recommended.
This should describe the image in plain language for accessibility.
dominant_colorOptional.
If empty, the workflow falls back to #ffffff.
If you provide a value, use a hex color such as:
#ffffff#f4d03f#d35400statusUsed by the workflow to track state.
Leave it empty before first run.
The workflow writes values such as:
submittedinvalidYou may later extend the system to include:
publishedfailedjob_idFilled by the workflow after a successful PinBridge job submission.
Leave it empty initially.
published_atFilled by the workflow when the publish job is submitted.
Leave it empty initially.
error_messageFilled by the workflow when validation fails or when you later add failure branches.
Leave it empty initially.
Here is a safe example layout:
| row_id | title | description | link_url | image_url | board_id | alt_text | dominant_color | status | job_id | published_at | error_message |
|---|---|---|---|---|---|---|---|---|---|---|---|
| pin-001 | Easy Lemon Pasta Dinner | Bright lemon pasta with garlic and parmesan. Click through for the full recipe. | https://example.com/lemon-pasta | https://example.com/images/lemon-pasta.jpg | 1234567890 | Bowl of lemon pasta with parmesan and herbs | #f7dc6f | ||||
| pin-002 | Small Kitchen Pantry Shelves | Space-saving pantry shelf ideas for small kitchens. | https://example.com/pantry-shelves | https://example.com/images/pantry-shelves.jpg | 1234567890 | Organized pantry shelves in a small kitchen | #d5dbdb |
Import the workflow JSON into your n8n instance.
After import, open the workflow and go through each credentialed node.
You will need to connect:
Do not assume imported placeholder IDs will work. They will not.
Open the Read Sheet Rows node and configure:
PinsMake sure the Google account connected to n8n has permission to read and update that sheet.
Then open the two update nodes:
Point them to the same spreadsheet and the same Pins tab.
These update nodes are designed to write values back into the same row using row_id as the matching key.
That means your row_id values must be unique.
If you duplicate row_id values, updates become unreliable.
There are two PinBridge nodes in this workflow:
This node uploads the binary image that was downloaded from the image_url column.
No extra row mapping is needed here beyond having a valid downloaded image.
This node submits the Pin publish job.
You must configure:
accountIdThe following fields are taken from the sheet row:
boardIdtitledescriptionlinkUrlaltTextdominantColorBefore running the workflow, replace the placeholder account ID with your real PinBridge Pinterest account ID.
The workflow expects a real board ID, not a board name.
There are several ways to get it depending on how you operate PinBridge:
Do not type human board names into the board_id column unless your system explicitly uses board names as IDs, which is usually not the case.
A wrong board ID will cause the publish step to fail.
This section explains exactly why the workflow is built the way it is.
This keeps the first version simple.
You decide when to run the batch. That is useful during setup, testing, and controlled publishing.
This can later be replaced with:
But manual trigger is the right default for a community template.
This reads all rows from the Pins tab.
The sheet acts as the batch source.
This prevents rows already marked as published from being processed again.
Even if your first version only writes submitted, this node is still useful because it gives you a clear place to define re-run behavior later.
This is one of the most important operational protections in the workflow.
This checks that the row has the minimum required information before any external work is done.
The required fields are:
titledescriptionlink_urlimage_urlboard_idThis matters because you do not want to waste requests on rows that are obviously incomplete.
This downloads the image from image_url.
The workflow assumes this URL is directly reachable from the n8n runtime.
If the image cannot be fetched, the flow will stop at this step unless you add explicit failure handling.
This sends the binary image into PinBridge.
This step matters because the Pinterest publish job should reference a clean asset path handled by the PinBridge side of the system.
This submits the publish job using PinBridge.
At this point the workflow is not pretending the job is fully completed end-to-end on Pinterest. It is recording that the publish job was successfully submitted.
That distinction matters.
A clean job submission and a final publish confirmation are not the same thing.
This template intentionally focuses on submission.
If the PinBridge publish request succeeds, the workflow creates a result object with:
status = submittedjob_idpublished_aterror_message = ''This object is then written back to the sheet.
This writes the successful submission result back to the original row.
That gives you traceability immediately.
If required fields are missing, this branch marks the row as invalid and explains why.
That makes the sheet self-correcting: you can scan invalid rows and fix them directly.
This writes the invalid result back into the sheet.
That closes the loop for bad inputs instead of silently dropping them.
This is deliberate.
A lot of people try to put the entire world into one n8n template:
That makes the template harder to understand and harder to run successfully the first time.
This workflow is intentionally scoped to:
That makes it easier to import, understand, and run.
A separate workflow should handle:
That separation is cleaner and easier to operate.
When you run the workflow for the first time:
invalidstatus = submittedjob_idpublished_atIf a row was already manually marked published, it should be skipped.
Do not start with 100 rows.
Start with 2 or 3 rows only:
That lets you confirm all branches work as expected.
A good first test looks like this:
board_idThen run the workflow manually and inspect the sheet afterwards.
You should see:
If the image requires cookies, auth, a signed session, or expired CDN tokens, the download node will fail.
Use stable public URLs.
A human-readable board name is not enough. Use the real board ID.
This usually means:
row_id is missingrow_id is duplicatedIf the account ID does not match the expected Pinterest account context, the publish node can fail even if everything else looks correct.
PinsIf you rename the tab, update all Google Sheets nodes accordingly.
To keep this workflow reliable, follow these rules:
row_id per rowNever reuse IDs.
status workflow-ownedLet the workflow write status values. Do not overload the field with random notes.
Once a row is submitted, do not casually change title, description, or image in place. Create a new row if the Pin is materially different.
Especially if your image links come from a CMS or CDN.
Do not treat the first live run like a stress test.
Once this base workflow is working, the best next extensions are:
Use a separate workflow to:
status from submitted to published or failedWrap the download, upload, and publish nodes with explicit failure branches so bad rows are marked failed instead of stopping the run.
Create a small helper workflow that lists available boards and writes them to a reference sheet.
Replace manual trigger with a cron or scheduled trigger once the flow is stable.
You can validate that:
link_url starts with httpimage_url starts with httpdominant_color looks like a hex codeA row is publishable only if all of the following are true:
row_id existstitle existsdescription existslink_url existsimage_url existsboard_id existsIf any of those are false, the row should not be considered publish-ready.
This workflow is a practical bulk-publishing starter template.
It uses:
That makes it useful as both a real operational workflow and a clear demonstration of where PinBridge fits inside an automation stack.
If you configure the Google Sheet correctly, connect your Google Sheets and PinBridge credentials, set the right Pinterest account ID, and provide valid public image URLs and board IDs, you should be able to run this workflow from start to finish successfully with no additional context.
Before running the workflow, confirm all of the following:
Pinsrow_idtitledescriptionlink_urlimage_urlboard_idIf all of that is true, the workflow is ready to run.