0.0
The project is in a healthy, maintained state
Ruby wrapper for the Pinterest REST API v5
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 3.0
~> 3.13
~> 3.23

Runtime

 Project Readme

Pinterest API

Ruby wrapper for the Pinterest REST API v5.

Installation

Add to your Gemfile:

gem "pinterest-ads"

Then run:

bundle install

Configuration

Global configuration

Pinterest.configure do |c|
  c.client_id     = ENV["PINTEREST_CLIENT_ID"]
  c.client_secret = ENV["PINTEREST_CLIENT_SECRET"]
  c.access_token  = ENV["PINTEREST_ACCESS_TOKEN"]
  c.redirect_uri  = ENV["PINTEREST_REDIRECT_URI"]
end

Per-client configuration

You can also pass credentials directly when instantiating a client. Per-client values take precedence over the global configuration.

client = Pinterest::Client.new(
  client_id:     "your_app_id",
  client_secret: "your_app_secret",
  access_token:  "your_bearer_token",
  redirect_uri:  "https://example.com/callback"
)

Optional settings

Option Default Description
base_url https://api.pinterest.com/v5 API base URL
auth_url https://www.pinterest.com/oauth/ OAuth authorization URL
timeout 30 Request timeout in seconds
open_timeout 10 Connection open timeout in seconds

These can be set via Pinterest.configure or passed as keyword arguments to Pinterest::Client.new.

Usage

OAuth

1. Generate the authorization URL

url = client.oauth.authorization_url(
  redirect_uri: "https://example.com/callback",
  scope: %w[ads:read ads:write],
  state: SecureRandom.hex(16)
)
# Redirect the user to this URL

2. Exchange the authorization code for tokens

tokens = client.oauth.exchange_code(
  code: params[:code],
  redirect_uri: "https://example.com/callback"
)
# tokens => { "access_token" => "...", "refresh_token" => "...", "expires_in" => 86400, ... }

3. Refresh an access token

tokens = client.oauth.refresh(refresh_token: "your_refresh_token")
client.access_token = tokens["access_token"]

4. Revoke a token

client.oauth.revoke(token: "token_to_revoke", token_type_hint: "access_token")

5. Generate a conversion API token

result = client.oauth.conversion_token
# result => { "access_token" => "...", "token_type" => "conversion" }

Audiences

All audience methods require an ad_account_id.

# List audiences
audiences = client.audiences.list(ad_account_id: "123456")
# audiences => { "items" => [...], "bookmark" => "..." }

# Create an audience
audience = client.audiences.create(
  ad_account_id: "123456",
  name: "My Audience",
  audience_type: "CUSTOMER_LIST",
  rule: { ... }
)

# Get a specific audience
audience = client.audiences.find(ad_account_id: "123456", audience_id: "789")

# Update an audience
client.audiences.update(ad_account_id: "123456", audience_id: "789", name: "New Name")

Customer Lists

# List customer lists
lists = client.customer_lists.list(ad_account_id: "123456")

# Create a customer list
list = client.customer_lists.create(
  ad_account_id: "123456",
  name: "Email Subscribers",
  list_type: "EMAIL",
  records: "user1@example.com\nuser2@example.com"
)

# Get a specific customer list
list = client.customer_lists.find(ad_account_id: "123456", customer_list_id: "789")

# Add or remove records
client.customer_lists.update(
  ad_account_id: "123456",
  customer_list_id: "789",
  operation_type: "ADD",
  records: "user3@example.com"
)

Customer List Uploads (Multipart S3)

For large customer lists, use the multipart upload workflow:

# 1. Create the upload (returns presigned S3 URLs)
upload = client.customer_list_uploads.create(
  ad_account_id: "123456",
  customer_list_id: "789",
  operation: "ADD",
  total_parts: 3
)
# upload => { "customer_list_upload" => {...}, "s3_multipart_upload_data" => {...} }

# 2. Upload parts to S3 using the presigned URLs (outside this gem)

# 3. Trigger processing
client.customer_list_uploads.run(
  ad_account_id: "123456",
  customer_list_id: "789",
  customer_list_upload_id: upload.dig("customer_list_upload", "id")
)

# Check upload status
status = client.customer_list_uploads.find(
  ad_account_id: "123456",
  customer_list_id: "789",
  customer_list_upload_id: "upload_id"
)

Pagination

List endpoints return a bookmark value for cursor-based pagination:

all_audiences = []
bookmark = nil

loop do
  result = client.audiences.list(ad_account_id: "123456", bookmark: bookmark, page_size: 25)
  all_audiences.concat(result["items"])
  bookmark = result["bookmark"]
  break if bookmark.nil?
end

Error Handling

The gem raises typed exceptions for HTTP errors:

Status Exception
400 Pinterest::BadRequestError
401 Pinterest::AuthenticationError
403 Pinterest::ForbiddenError
404 Pinterest::NotFoundError
429 Pinterest::RateLimitError
5xx Pinterest::ServerError

All exceptions inherit from Pinterest::Error and expose status, code, and response attributes.

begin
  client.audiences.find(ad_account_id: "123", audience_id: "bad_id")
rescue Pinterest::NotFoundError => e
  puts e.message # API error message
  puts e.status  # 404
rescue Pinterest::Error => e
  puts "Unexpected error: #{e.message} (HTTP #{e.status})"
end

Requirements

  • Ruby >= 3.0.0

License

MIT