Skip to Content
Pins APIUpdate Pin

Update Pin

Update pin content and metadata (real-time updates).

Endpoint

PUT /v1/pins/:pinId

Authentication

Requires API key with pins:write scope.

Authorization: Bearer pk_live_your_api_key

Path Parameters

ParameterTypeRequiredDescription
pinIdstringYesThe pin ID (e.g., p-abc123def456)

Request Body

Update pin content and/or metadata. All fields are optional - only include what you want to change.

FieldTypeRequiredDescription
pin_typestringNoChange pin type (must match pin_config)
pin_configobjectNoUpdated pin configuration (validated per type)
pin_layoutstringNoLayout size
is_publicbooleanNoMake pin public or private
metadataobjectNoPartial metadata (title, tags, or nested pin_config)

Metadata Update Example

{ "metadata": { "title": "Updated Dashboard Title", "tags": ["sales", "updated", "q4"] } }

Pin config update (root level)

{ "pin_config": { "cards": [{ "title": "Total Sales", "value": "$145,890", "change": "+32.1%", "trend": "up" }] } }

Or nest under metadata.pin_config — both are accepted.

Visibility

is_public can be set on update. For full sharing controls (allow_edit, require_sign_in, allow_comments), use the Share endpoint:

{ "is_public": true }

Response

Success (200 OK)

{ "success": true, "data": { "id": "p-abc123def456", "updated_at": 1730476800000 } }

Examples

Update Stat Card Value (Real-time)

curl -X PUT https://api.pindown.ai/v1/pins/p-abc123def456 \ -H "Authorization: Bearer pk_live_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "pin_config": { "cards": [{ "title": "Live Users", "value": "1,234", "change": "+5.2%", "trend": "up" }] } } }'

Update table data

curl -X PUT https://api.pindown.ai/v1/pins/p-def456ghi789 \ -H "Authorization: Bearer pk_live_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "pin_config": { "columns": [ { "id": "product", "name": "Product", "type": "text" }, { "id": "sales", "name": "Sales", "type": "number" } ], "rows": [ { "id": "r1", "cells": { "product": "Widget A", "sales": 1520 } }, { "id": "r2", "cells": { "product": "Widget B", "sales": 980 } } ] } }'

Update Only Metadata

curl -X PUT https://api.pindown.ai/v1/pins/p-abc123def456 \ -H "Authorization: Bearer pk_live_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "title": "Q4 Revenue Dashboard", "tags": ["revenue", "q4", "2024"] } }'

Code Examples

import { PindownClient } from '@pindownai/client-js' const client = new PindownClient({ apiKey: process.env.PINDOWN_API_KEY }) const pinId = 'p-abc123def456' // Update pin config (root-level pin_config) await client.pins.update(pinId, { pin_config: { cards: [{ title: 'Live Users', value: '1,234', change: '+5.2%', trend: 'up' }] } }) // Update metadata only await client.pins.update(pinId, { metadata: { title: 'Q4 Revenue Dashboard', tags: ['revenue', 'q4', '2024'] } }) // Real-time update every 5 seconds setInterval(async () => { const metrics = await fetchMetrics() // Your data source await client.pins.update(pinId, { pin_config: { cards: [{ title: 'Live Users', value: metrics.users.toString(), change: `+${metrics.change}%`, trend: 'up' }] } }) console.log(`Updated pin at ${new Date().toISOString()}`) }, 5000)

Error Responses

404 Not Found

{ "error": { "code": "NOT_FOUND", "message": "Pin not found or you don't have access" } }

400 Bad Request

{ "success": false, "error": { "code": "PIN_CONFIG_INVALID", "message": "Invalid pin_config for pin_type \"stat-cards\" at cards: …" } }

403 Forbidden

{ "error": { "code": "SCOPE_REQUIRED", "message": "This endpoint requires the 'pins:write' scope" } }

Rate limits

Write bucket: 90 requests / 60 seconds (shared with create, delete, batch, share). See Overview → Rate limits.

Real-time update tips

  1. Use appropriate intervals — every 5–30 seconds for live dashboards
  2. Batch updates — use Batch Update when updating many pins
  3. Error handling — retry on 429 RATE_LIMITED

Next Steps