Home / Docs / Bulk import

Bulk import pins in n8n

Bulk import turns a spreadsheet or table of rows into a batch of pins in one call. Feed rows from Google Sheets or Airtable into the PinBridge node, submit them as JSON or CSV, then poll the import job for per-row results.

Prerequisites

  • A paid plan. Bulk import requires the bulk_publishing feature, which is off on Free (Playground); a Free-plan import returns a 403. See PinBridge for n8n for plan notes.
  • The PinBridge credential set up. See Set up your PinBridge credential.
  • A source of rows (Google Sheets, Airtable, or any node that outputs items).

Row rules and limits

  • Max 500 rows per import (JSON or CSV).
  • Each row is a pin definition: it needs account_id, board_id, title, and idempotency_key, plus exactly one of image_url or asset_id.
  • Optional per row: description, related_terms, alt_text, dominant_color, cover_image_url, cover_image_asset_id, link_url, and run_at.
  • run_at (optional) schedules the row for a future time. It must be ISO 8601 with an explicit timezone offset (for example 2026-10-01T14:30:00+00:00) and must be in the future, or the row fails.
  • Deduplication is by (project, idempotency_key). A row whose key already exists is reported as existing rather than creating a duplicate. This makes re-running an import safe.

Path A: Import JSON (from Sheets or Airtable)

The Import JSON operation reads every incoming item’s JSON and posts them as one array. Shape each item so its fields match the row schema above.

  1. Add Google Sheets (or Airtable) and read your rows. Each row becomes one n8n item.
  2. Add a Set or Edit Fields node if you need to rename columns to account_id, board_id, title, idempotency_key, and image_url (or asset_id).
  3. Add a PinBridge node set to Pin → Import JSON. It has no field for the rows; it reads the incoming items directly.
  4. Execute. The node calls POST /v1/pins/imports/json and returns a single import job item.

Path B: Import CSV

The Import CSV operation uploads a CSV file as multipart.

  1. Produce a CSV as binary data (for example a Read Binary File node, or convert items to a file).
  2. Add a PinBridge node set to Pin → Import CSV.
  3. Set Binary Property to the property holding the CSV (default data).
  4. Execute. The node calls POST /v1/pins/imports/csv.

CSV required columns: account_id, board_id, title, idempotency_key. Allowed extra columns: description, related_terms, alt_text, dominant_color, cover_image_url, cover_image_asset_id, link_url, image_url, asset_id, run_at. Any column outside that set fails the whole file with a 400.

Check the import job status

Import runs asynchronously, so the submit call returns a job, not finished pins.

  1. Add a PinBridge node set to Pin → Get Import.
  2. Set Import Job ID to ={{$json["id"]}} to read the id from the submit node’s output.
  3. Execute (or poll on a loop). The node calls GET /v1/pins/imports/{importJobId}.

Job status moves through queued → processing → completed (or completed_with_errors if any row failed, or failed for a whole-job crash). The response carries counters (total_rows, created_rows, existing_rows, failed_rows) and a results array with a per-row status of created, existing, or failed, plus error_code and error_message for failures.

To list past jobs, use Pin → List Imports, optionally filtered by Import Status and Import Source (json or csv).

Retry failed rows

There is no retry operation for individual import rows in the node. To retry, re-import only the rows that failed:

  1. Read the job with Pin → Get Import and split out results.
  2. Filter to status === "failed" (an IF or Filter node).
  3. Fix the underlying data for those rows (a bad URL, a missing field).
  4. Re-run Import JSON or Import CSV with the corrected rows. Because dedupe is by (project, idempotency_key), rows that already succeeded are reported as existing and are not duplicated, so it is safe to resubmit the whole set if that is easier.

curl equivalent

# Submit a JSON import (raw array of row objects)
curl -sS -X POST "https://api.pinbridge.io/v1/pins/imports/json" \
  -H "X-API-Key: $PINBRIDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {"account_id":"6f1c2e4a-3b7d-4c9e-8a21-5d0f9b3e7c41","board_id":"987654321098765432","title":"Row 1","image_url":"https://placehold.co/1000x1500.png","idempotency_key":"import-row-1"}
  ]'

# Check the job
curl -sS "https://api.pinbridge.io/v1/pins/imports/<job_id>" \
  -H "X-API-Key: $PINBRIDGE_API_KEY"

Next steps

Last updated September 13, 2026Was this page helpful? Tell us →