PHPackages                             pinterest/laravel-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. pinterest/laravel-sdk

ActiveLibrary[API Development](/categories/api)

pinterest/laravel-sdk
=====================

A Laravel-native SDK for the Pinterest API v5

1.0.0(4mo ago)13[2 PRs](https://github.com/amarneche/pinterest-laravel/pulls)MITPHPPHP ^8.2CI passing

Since Feb 14Pushed 2mo agoCompare

[ Source](https://github.com/amarneche/pinterest-laravel)[ Packagist](https://packagist.org/packages/pinterest/laravel-sdk)[ Docs](https://github.com/pinterest/laravel-sdk)[ GitHub Sponsors](https://github.com/:vendor_name)[ RSS](/packages/pinterest-laravel-sdk/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (15)Versions (5)Used By (0)

Laravel Pinterest SDK
=====================

[](#laravel-pinterest-sdk)

A Laravel-native SDK for the Pinterest API v5. Provides a clean, expressive interface for interacting with Pinterest's boards, pins, ads, and user accounts using Laravel's HTTP client.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11.0+ or 12.0+

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require pinterest/laravel-sdk
```

The service provider and facade are auto-discovered by Laravel.

### Publish Configuration

[](#publish-configuration)

```
php artisan vendor:publish --tag="pinterest-config"
```

This publishes `config/pinterest.php` to your application.

Configuration
-------------

[](#configuration)

Add the following to your `.env` file:

```
PINTEREST_CLIENT_ID=your-app-id
PINTEREST_CLIENT_SECRET=your-app-secret
PINTEREST_REDIRECT_URI=https://your-app.com/pinterest/callback
PINTEREST_ACCESS_TOKEN=your-access-token
PINTEREST_REFRESH_TOKEN=your-refresh-token
```

### Full Configuration Options

[](#full-configuration-options)

KeyEnv VariableDefaultDescription`client_id``PINTEREST_CLIENT_ID``''`Pinterest App ID`client_secret``PINTEREST_CLIENT_SECRET``''`Pinterest App Secret`redirect_uri``PINTEREST_REDIRECT_URI``''`OAuth callback URL`access_token``PINTEREST_ACCESS_TOKEN``''`Bearer access token`refresh_token``PINTEREST_REFRESH_TOKEN``''`OAuth refresh token`api_version``PINTEREST_API_VERSION``v5`API version`base_url``PINTEREST_BASE_URL``https://api.pinterest.com`API base URL`oauth_url``PINTEREST_OAUTH_URL``https://www.pinterest.com/oauth/`OAuth URL`scopes``PINTEREST_SCOPES``boards:read,pins:read,user_accounts:read`OAuth scopes`timeout``PINTEREST_TIMEOUT``30`Request timeout (seconds)`retry.times`-`3`Max retry attempts`retry.sleep`-`100`Retry delay (milliseconds)Usage
-----

[](#usage)

All API interactions are available through the `Pinterest` facade.

### Boards

[](#boards)

```
use Pinterest\Facades\Pinterest;

// List boards
$boards = Pinterest::boards()->list(['page_size' => 25]);
foreach ($boards->items() as $board) {
    echo $board['name'];
}

// Get a specific board
$board = Pinterest::boards()->get('board-id');

// Create a board
$board = Pinterest::boards()->create([
    'name' => 'My Recipes',
    'description' => 'Favorite recipes collection',
    'privacy' => 'PUBLIC',
]);

// Update a board
Pinterest::boards()->update('board-id', [
    'name' => 'Updated Name',
]);

// Delete a board
Pinterest::boards()->delete('board-id');

// Board sections
Pinterest::boards()->createSection('board-id', ['name' => 'Desserts']);
Pinterest::boards()->listSections('board-id');
Pinterest::boards()->updateSection('board-id', 'section-id', ['name' => 'New Name']);
Pinterest::boards()->deleteSection('board-id', 'section-id');

// List pins on a board
$pins = Pinterest::boards()->listPins('board-id');
```

### Pins

[](#pins)

```
// List pins
$pins = Pinterest::pins()->list(['page_size' => 10]);

// Get a pin
$pin = Pinterest::pins()->get('pin-id');

// Create a pin
$pin = Pinterest::pins()->create([
    'board_id' => 'board-id',
    'title' => 'Amazing Sunset',
    'description' => 'Beautiful sunset at the beach',
    'link' => 'https://example.com/sunset',
    'media_source' => [
        'source_type' => 'image_url',
        'url' => 'https://example.com/sunset.jpg',
    ],
]);

// Update a pin
Pinterest::pins()->update('pin-id', [
    'title' => 'Updated Title',
]);

// Delete a pin
Pinterest::pins()->delete('pin-id');

// Save a pin to a different board
Pinterest::pins()->save('pin-id', [
    'board_id' => 'other-board-id',
]);
```

### User Account

[](#user-account)

```
// Get authenticated user info
$user = Pinterest::user()->getAccount();
echo $user->get('username');

// Get user analytics
$analytics = Pinterest::user()->getAnalytics([
    'start_date' => '2024-01-01',
    'end_date' => '2024-01-31',
    'metric_types' => 'IMPRESSION,PIN_CLICK',
]);

// Top pins analytics
$topPins = Pinterest::user()->getTopPinsAnalytics([
    'start_date' => '2024-01-01',
    'end_date' => '2024-01-31',
    'sort_by' => 'IMPRESSION',
    'num_of_pins' => 10,
]);
```

### Pagination

[](#pagination)

Pinterest uses cursor-based pagination with bookmark tokens. The SDK handles this transparently:

```
$response = Pinterest::boards()->list(['page_size' => 25]);

// Iterate through all pages
while (true) {
    foreach ($response->items() as $board) {
        echo $board['name'] . "\n";
    }

    if (!$response->hasMorePages()) {
        break;
    }

    $response = $response->getNextPage();
}
```

### OAuth Flow

[](#oauth-flow)

The SDK provides a complete OAuth2 authorization code flow:

```
// 1. Generate authorization URL and redirect user
$state = bin2hex(random_bytes(16));
session(['pinterest_oauth_state' => $state]);

$url = Pinterest::oauth()->getAuthorizationUrl($state);
return redirect($url);

// 2. Handle the callback - exchange code for token
$code = request('code');
$token = Pinterest::oauth()->exchangeCodeForToken($code);

// Store tokens securely
$token->getAccessToken();   // Access token string
$token->getRefreshToken();  // Refresh token string
$token->getExpiresIn();     // Lifetime in seconds

// 3. Use the new token
Pinterest::setAccessToken($token->getAccessToken());

// 4. Refresh an expired token
$newToken = Pinterest::oauth()->refreshToken($token->getRefreshToken());
```

### Ads API

[](#ads-api)

All ads endpoints require an ad account ID:

```
// List ad accounts
$accounts = Pinterest::adAccounts()->list();

// Campaigns
$campaigns = Pinterest::campaigns()->list('ad-account-id');
Pinterest::campaigns()->create('ad-account-id', [
    ['name' => 'Spring Sale', 'objective_type' => 'AWARENESS', 'status' => 'ACTIVE'],
]);
Pinterest::campaigns()->get('ad-account-id', 'campaign-id');

// Ad Groups
$adGroups = Pinterest::adGroups()->list('ad-account-id');
Pinterest::adGroups()->create('ad-account-id', $data);

// Ads
$ads = Pinterest::ads()->list('ad-account-id');
Pinterest::ads()->create('ad-account-id', $data);

// Audiences
$audiences = Pinterest::audiences()->list('ad-account-id');
Pinterest::audiences()->create('ad-account-id', [
    'name' => 'My Audience',
    'rule' => ['visitor_source_id' => 'tag-id'],
    'audience_type' => 'VISITOR',
]);

// Conversion events
Pinterest::conversions()->sendEvents('ad-account-id', [
    'data' => [
        [
            'event_name' => 'checkout',
            'action_source' => 'web',
            'event_time' => time(),
            'user_data' => ['em' => [hash('sha256', 'user@example.com')]],
        ],
    ],
]);

// Conversion tags
Pinterest::conversions()->listTags('ad-account-id');
Pinterest::conversions()->createTag('ad-account-id', ['name' => 'My Tag']);

// Keywords
Pinterest::keywords()->list('ad-account-id', ['ad_group_id' => 'group-id']);
Pinterest::keywords()->create('ad-account-id', $keywordsData);

// Customer Lists
Pinterest::customerLists()->list('ad-account-id');
Pinterest::customerLists()->create('ad-account-id', $listData);
```

### Media Upload

[](#media-upload)

```
// Register a media upload
$media = Pinterest::media()->register(['media_type' => 'video']);

// Check upload status
$status = Pinterest::media()->getStatus($media->get('media_id'));
```

### Error Handling

[](#error-handling)

The SDK throws typed exceptions for different error scenarios:

```
use Pinterest\Exceptions\PinterestApiException;
use Pinterest\Exceptions\PinterestAuthException;
use Pinterest\Exceptions\PinterestRateLimitException;
use Pinterest\Exceptions\PinterestValidationException;

try {
    $boards = Pinterest::boards()->list();
} catch (PinterestAuthException $e) {
    // 401/403 - Invalid or expired credentials
    // Refresh token and retry
} catch (PinterestRateLimitException $e) {
    // 429 - Rate limited
    $retryAfter = $e->getRetryAfter();   // Seconds to wait
    $remaining = $e->getRateLimitRemaining();
} catch (PinterestValidationException $e) {
    // 400/422 - Invalid request data
    $errors = $e->getValidationErrors();
} catch (PinterestApiException $e) {
    // Any other API error
    $status = $e->getCode();
    $body = $e->getErrorBody();
    $response = $e->getResponse();
}
```

### Working with Responses

[](#working-with-responses)

All API calls return an `ApiResponse` (or `PaginatedResponse` for list endpoints):

```
$response = Pinterest::boards()->get('board-id');

// Access data
$response->json();              // Full decoded JSON body
$response->get('name');         // Dot-notation access
$response->get('owner.id');     // Nested dot-notation
$response->status();            // HTTP status code
$response->successful();        // Boolean: 2xx status
$response->toArray();           // Convert to array
$response->toJson();            // Convert to JSON string
$response['name'];              // Array access

// Headers
$response->headers();           // All headers
$response->header('X-Custom');  // Specific header
```

### Dynamic Token Switching

[](#dynamic-token-switching)

```
// Change token at runtime
Pinterest::setAccessToken('different-token');

// Access the underlying client
$client = Pinterest::getClient();
$client->setAccessToken('another-token');
```

Available Services
------------------

[](#available-services)

MethodServiceDescription`boards()``BoardsService`Boards + sections CRUD, list pins`pins()``PinsService`Pins CRUD, save pins`user()``UserService`Account info, analytics`media()``MediaService`Media upload registration`adAccounts()``AdAccountsService`Ad accounts list/get/analytics`campaigns()``CampaignsService`Campaigns CRUD, analytics`adGroups()``AdGroupsService`Ad groups CRUD, analytics`ads()``AdsService`Ads CRUD, analytics`audiences()``AudiencesService`Audiences CRUD`conversions()``ConversionsService`Conversion events + tags`customerLists()``CustomerListsService`Customer lists CRUD`keywords()``KeywordsService`Keywords CRUD, metrics`oauth()``OAuthService`Authorization + token managementTesting
-------

[](#testing)

```
composer test
```

Static Analysis
---------------

[](#static-analysis)

```
composer analyse
```

Code Formatting
---------------

[](#code-formatting)

```
composer format
```

Architecture
------------

[](#architecture)

The package follows a layered architecture:

- **Facade** (`Pinterest\Facades\Pinterest`) - Static access point
- **Manager** (`Pinterest\Pinterest`) - Lazy-loads service instances
- **Services** (`Pinterest\Services\*`) - Domain-specific API wrappers
- **Client** (`Pinterest\Client\PinterestClient`) - HTTP abstraction with auth, retries, error mapping
- **Auth** (`Pinterest\Auth\OAuthService`) - OAuth2 flow management
- **Support** (`Pinterest\Support\*`) - Response wrappers, pagination
- **Exceptions** (`Pinterest\Exceptions\*`) - Typed exception hierarchy

License
-------

[](#license)

The MIT License (MIT). See [LICENSE.md](LICENSE.md) for more information.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance81

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

141d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3dac595c783c61dc5d2a7e90f9b8c9d2a89b99581de06681b07584670bc7864f?d=identicon)[amarneche](/maintainers/amarneche)

---

Top Contributors

[![amarneche](https://avatars.githubusercontent.com/u/47366103?v=4)](https://github.com/amarneche "amarneche (4 commits)")

---

Tags

apilaravelsdkpinterestsocial media

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/pinterest-laravel-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/pinterest-laravel-sdk/health.svg)](https://phpackages.com/packages/pinterest-laravel-sdk)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.9k3](/packages/defstudio-telegraph)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.0k](/packages/simplestats-io-laravel-client)[api-platform/laravel

API Platform support for Laravel

58171.8k14](/packages/api-platform-laravel)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

44855.7k](/packages/harris21-laravel-fuse)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1563.2k4](/packages/masterix21-laravel-licensing)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
