The Pinterest API (version 5) lets your code create boards, publish Pins, upload video and read analytics for the Pinterest accounts that authorize your app. Getting there takes longer than most developers expect. Pinterest reviews every app, the first access tier hides what you publish, and tokens expire on a schedule you have to keep up with.
This guide walks through the whole path as it stands in October 2026: getting access, getting a token, publishing your first Pin, and the limits you will run into. Every number below comes from Pinterest’s developer documentation, linked at the end.
What the Pinterest API can do
The v5 API lives at https://api.pinterest.com/v5. For organic content (anything that is not an ad) these are the parts most apps use:
- Boards and board sections, which you can list, create, update and delete.
- Pins in image, video and carousel formats, which you can create, read and delete.
- Media uploads, for the video you attach to a Pin.
- Analytics for an account or a single Pin, such as impressions, saves and outbound clicks.
There is also a large ads side (campaigns, audiences, conversions, catalogs) with its own scopes and limits. This guide sticks to publishing.
Two things it does not do are worth knowing before you start. Create Pin has no field for a publish time, so scheduling is up to you. And editing a Pin after it is live (PATCH /v5/pins/{pin_id}) is a beta feature that Pinterest says is not available to all apps.
Is the Pinterest API free?
Pinterest does not charge for API access. The cost is time: the app review, the demo video for the upgrade, and the code that keeps tokens fresh and stays under the rate limits. We put rough numbers on that in build vs buy.
Step 1: get access
Register your app
- Log in to a Pinterest business account, or create one. This account administers the app.
- Verify the account’s email address.
- Open My apps, accept the Developer Terms of Service and click Connect app.
- Fill in the request form. The app name needs at least three Latin letters or digits and cannot contain the word “Pinterest”.
Pinterest reviews the request and emails you the result. Pinterest names two common reasons for a denial at this stage: a privacy policy link that does not load, is not public or sits on a domain unrelated to your app, and an app description that is too vague. Describe what your app does with Pinterest data in plain detail.
Once approved, your app ID and app secret are on the My apps page. Pinterest has no single API key that works on its own. The ID and secret identify your app, and every call also needs an access token that a Pinterest user grants you (step 2).
Trial access
An approved app starts on Trial access. You can call almost every endpoint, with two catches:
- Pins and boards you create are visible only to you. Pinterest treats them as sandbox entities, so Trial is for building and testing, not for publishing to an audience.
- Limits are counted per day, per app: 1,000 requests a day in total, and 300 a day for writes like creating Pins.
Standard access
To publish Pins other people can see, upgrade to Standard. From My apps, click Upgrade on the app card (it only shows up for eligible apps), check your app details and privacy policy link, and upload a video demo.
Every common reason Pinterest gives for a Standard denial is about this video. It has to show a real user going through Pinterest’s OAuth flow and your app doing something live with the API. Wireframes and general product demos get denied, and so does any app that collects Pinterest passwords or session cookies instead of using OAuth. If you are the only person who will ever use the app, Pinterest still wants the video, but a screen recording of calls in a terminal or Postman is accepted.
Pinterest reviews upgrade requests regularly and emails the decision. To appeal a denial, open a ticket in the Pinterest Help Center.
A new restriction for apps registered from 14 September 2026
Pinterest’s access tier page now carries a note: apps registered on or after 14 September 2026 may get 403 PINNER_DATA_ACCESS_DENIED when they request a board or Pin belonging to a non-business user without Pinterest’s authorization. If you are building something that serves personal accounts, read that changelog entry before you build.
Step 2: get an access token
Every call carries a bearer token tied to one Pinterest user. Most apps use the authorization code flow:
- Send the user to
https://www.pinterest.com/oauth/with yourclient_id, aredirect_urithat exactly matches one registered on your app,response_type=code, thescopelist and astatevalue. - The user approves your app and Pinterest redirects back with a
code. Check thatstatematches what you sent. - Exchange the code for tokens, authenticating with your app ID and secret:
curl -X POST https://api.pinterest.com/v5/oauth/token \
--user "$PINTEREST_APP_ID:$PINTEREST_APP_SECRET" \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode "code=$CODE" \
--data-urlencode 'redirect_uri=https://yourapp.example/pinterest/callback'
For publishing you need boards:read and pins:write at least. Add pins:read to read Pins back and boards:write to create boards. Secret boards need their own _secret scopes.
How long tokens last
| Token | Lifetime | What to do |
|---|---|---|
| Access token | 30 days | Refresh it before it expires. |
| Refresh token (continuous) | 60 days, renewed on each refresh | Refresh at least once every 60 days, or the user has to authorize again. |
Apps created on or after 25 September 2025 get continuous refresh tokens automatically. Pinterest no longer supports the old 365-day refresh tokens. The catch with a 60-day window is that an account nobody posts from for two months quietly stops working. We wrote up how that happens in why Pinterest integrations die quietly after two months, and how to manage many connected accounts in Pinterest OAuth for developers.
Two shortcuts help while you build. Once your app has Trial access you can generate a test token from the developer site that lasts 24 hours, so you can call the API before your OAuth flow exists. And Pinterest runs a sandbox at api-sandbox.pinterest.com for test calls that do not affect the live Pinterest site.
Step 3: publish your first Pin
First find the board. GET /v5/boards lists the boards of the user behind the token:
curl https://api.pinterest.com/v5/boards \
--header "Authorization: Bearer $PINTEREST_TOKEN"
Then create the Pin with an image URL Pinterest can download:
curl -X POST https://api.pinterest.com/v5/pins \
--header "Authorization: Bearer $PINTEREST_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"board_id": "BOARD_ID",
"title": "Small balcony, big plans",
"description": "Five ideas for a balcony garden that fits in two square metres.",
"link": "https://yourblog.example/balcony-garden",
"alt_text": "A narrow balcony with herbs in wooden boxes",
"media_source": {
"source_type": "image_url",
"url": "https://yourblog.example/images/balcony.jpg"
}
}'
A 201 response returns the new Pin with its id. Other values of source_type cover the other formats: image_base64 for an image you send inline, multiple_image_urls for a carousel of two to five images, and video_id for video.
Video takes a few more calls. Register the upload with POST /v5/media and {"media_type": "video"}, send the file to the upload_url it returns along with every field in upload_parameters, then poll GET /v5/media/{media_id} until the status reads succeeded. Only then create the Pin with "source_type": "video_id", the media_id and a cover image. Our media workflow post covers what goes wrong at volume.
Two more fields are worth knowing about. Pinterest says Create Pin is for new content made by the user, and points apps that save other people’s content to its Save button instead. The current spec (version 5.28.0) also lists ai_disclosures on Create Pin, where the creator can declare that a Pin was made or changed with AI.
Step 4: stay under the rate limits
Pinterest applies a universal limit and a limit per category. The categories that matter for publishing:
| Category | Covers | Trial (per day, per app) | Standard (per minute, per user, per app) |
|---|---|---|---|
| All requests | Every call | 1,000 | 100 per second |
org_write |
Creating, editing or deleting boards and Pins | 300 | 100 |
org_read |
Reading accounts, boards and Pins | 1,000 | 1,000 |
org_analytics |
Account analytics and top Pins | 1,000 | 60 |
Each response carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset headers, and a call over the limit gets a 429. Pinterest notes the limits can change without notice, and you can ask its support team for an adjustment. For backoff and queueing patterns, see Pinterest API rate limits. For the other errors you will meet, see Pinterest API errors explained.
What you still have to build
A working Create Pin call is the start. A production integration usually also needs:
- A scheduler, since the API publishes immediately. You need a queue, a worker and a plan for Pins that fail at 3 AM. See how to schedule Pinterest Pins programmatically.
- A token refresh job that runs before the 60-day window closes, and a way to tell the user when an account needs reconnecting.
- Retries that never publish the same Pin twice.
- A way to fix mistakes before they go live, because you may not be able to edit a Pin afterwards. See editing Pinterest Pins through the API.
When to skip the app review
If Pinterest publishing is a feature in your product rather than the product, a hosted layer can save the review and the upkeep. PinBridge is one: you connect Pinterest accounts through our approved app, then publish and schedule through one REST API with webhooks, retries and token refresh handled for you. See how the PinBridge API works, or compare it with other options in Pinterest publishing APIs compared.
Not a developer? You do not need the API at all. You can publish from Claude, from ChatGPT or with the PinBridge scheduler.
Sources
All checked on 24 October 2026 on Pinterest’s developer site:
- Connect app
- Understanding our access tiers
- Set up authentication and authorization
- Rate limits
- Create Pin and the OpenAPI description (version 5.28.0)
