← library
Review-gated OAuth
Social / visual discovery (Pins, boards, ads)·agent-generated · deepseek-v4.1-flash·checked 2026-10-28
difficulty
3/5

OAuth 2 authorization-code is real (authorize at https://www.pinterest.com/oauth/, token at POST /v5/oauth/token), but you get no app secret until Pinterest manually approves your Trial request, and shipping to other users needs a second, video-gated Standard review. No OIDC discovery exists, so endpoints are hand-configured.

First working connection
~2–4 hours of work + 1–10 days Trial review
Production / approved
Same again + ~1–4 weeks for the Standard review and video demo
Composio managed OAuth
Available: ship today
Composio lists a managed OAuth app for this toolkit — you can ship on it while your own app is set up or reviewed.
who does itagent 5you 4provider 0
evidencetested 5sourced 31inferred 6
◆ agent run13 pages read26/30 quotes verified verbatim74s$0.023deepseek-v4.1-flash

01Pick your path

Trial access + OAuth authorization code
when You need a working user-consent flow for development or a single internal user.
→ Full OAuth flow with your own app ID/secret and real scopes; 1000 req/day; Pins and boards visible only to the creator.
Standard access (production)
when You will act on behalf of other people's Pinterest accounts in a shipped product.
→ Higher per-user rate limits and Pins/boards that are actually public; unlocked only after a recorded OAuth demo is approved.
Client credentials grant
when You own the ad account or catalog being managed and do not need per-user authorization.
→ An app-level token with no user consent screen — good for ad/catalog operations on your own business assets, useless for personalizing to an end user.
Product-limited token (24h)
when You want to smoke-test endpoints before writing the redirect/callback code.
→ Immediate API calls without building the OAuth flow, but the token dies after 24 hours and requires an already-approved Trial app.

02Time & effort

Hands-on work
1.9 h – 6.8 h
Waiting on others
8 days – 5 weeks
You're actually working
<1% of elapsed time
Phases
6
start↑ first working connection, then production pathproduction
  1. DEVBusiness account, email verify, Developer ToS10–30 minutessourced[S1]You must be logged into the business account that will administer the app.
  2. DEVDraft and submit Connect app (Trial) request15–45 minutessourced[S1]Agent can draft the app name, description and scope justification; you paste and submit.
  3. DEVPinterest reviews Trial requestwait 1–10 dayssourced[S1][S6]Sources confirm manual review plus email notification and advise allowing 'a few days'; the day range itself is inferred.
  4. DEVBuild and test the OAuth flow1–4 hourssourced[S2][S4]Authorize redirect, callback, token exchange, refresh persistence. No discovery metadata, so endpoints are hardcoded.
  5. PRODRecord OAuth demo video, submit Standard upgrade30–90 minutessourced[S6]Must show the live OAuth flow and real Pinterest integration; terminal/Postman recordings are accepted.
  6. PRODPinterest reviews Standard requestwait 1–4 weeksinferred[S6][S7]Sources say reviews happen 'regularly' with email notification but give no SLA; deny/resubmit cycles are visible in the community thread.
agent can do it you waiting on providerbar widths ∝ √time, so short tasks stay visible

03Steps

0/9 done

Get a working connection

  1. Accept that this is a manual-endpoint OAuth 2 serveragentinferred

    There is no OAuth/OIDC discovery on api.pinterest.com, and www.pinterest.com returns an HTML shell (200) for any well-known path. Plan for hardcoded endpoints: authorize https://www.pinterest.com/oauth/, token https://api.pinterest.com/v5/oauth/token. Don't wire a discovery-dependent client.

    ↗ www.pinterest.com/oauth/
  2. Create the admin business account and accept the ToSyousourced ❝[S1]

    Log in or create a business account, verify its email, open My apps, and accept the Developer Terms of Service. Nothing else is clickable until the ToS is accepted.

    “Go to My apps and click through to accept our Developer Terms of Service” — [S1] verified verbatim
    ↗ developers.pinterest.com/docs/getting-started/connect-app/
  3. Draft and submit the Connect app (Trial) requestagentsourced ❝[S6][S1]

    Select Connect app, fill the request form with app info, and submit for Trial access. Vague descriptions and broken privacy-policy links are the two stated denial reasons. Agent drafts the text; you paste and submit.

    “Access requests that don't have enough information about the app or are vague or incomplete may be denied.” — [S6] verified verbatim
    ↗ developers.pinterest.com/docs/getting-started/connect-app/
    ◆ prepared by agent · Trial-request description + scope justification draft
    App name: PinPilot (>=3 Latin alphanumerics, no "Pinterest")
    
    What the app does: PinPilot is an assistant that drafts and schedules Pins and reports weekly organic performance for the brand's own Pinterest business account. A user explicitly authorizes their account via Pinterest OAuth; we never collect Pinterest usernames, passwords or session cookies.
    
    Scopes requested and why:
    - boards:read — list the user's boards so they can pick a destination board before publishing.
    - pins:read — read back Pins we created and fetch their metrics for the weekly report.
    - ads:read — (only if ads reporting is in scope) read campaign and ad performance for the user's ad account.
    
    Privacy policy: https://<your-company-domain>/privacy — public, loads fully, hosted on the same domain as the product.
    Data handling: access and refresh tokens stored encrypted server-side; no Pinterest credentials stored.
  4. Register the exact redirect URIyousourced ❝[S1][S5]

    My apps → Manage (your app) → Configure tab → Redirect URIs → enter the URI → Add. Use an exact string including scheme and trailing slash; the value sent at authorize time must match character-for-character and must not bounce again from your callback.

    “They must be an exact match to avoid any exceptions. The specified redirect URI must not cause the responding server to send a secondary redirect to yet another URI.” — [S1] verified verbatim
    ↗ developers.pinterest.com/docs/getting-started/connect-app/
  5. Wire the authorize redirect and the token exchangeagentsourced ❝[S4][S2]

    Redirect to https://www.pinterest.com/oauth/ with client_id, redirect_uri, response_type=code, scope and a state nonce; verify state on return; then POST to https://api.pinterest.com/v5/oauth/token with HTTP Basic client_id:client_secret, grant_type=authorization_code, code and the same redirect_uri. Sandbox host is https://api-sandbox.pinterest.com/v5/oauth/token.

    “https://www.pinterest.com/oauth/?client_id=1234567&redirect_uri=https://example.com/&response_type=code&scope=ads:read,ads:write,boards:read,pins:read&state=hello” — [S4] verified verbatim
    ↗ api.pinterest.com/v5/oauth/token
    ◆ prepared by agent · Authorize URL + token exchange
    GET https://www.pinterest.com/oauth/?client_id=<APP_ID>&redirect_uri=<EXACT_REGISTERED_URI>&response_type=code&scope=boards:read,pins:read&state=<csrf_nonce>
    
    # callback -> verify state, then:
    curl -X POST https://api.pinterest.com/v5/oauth/token \
      -H 'Authorization: Basic <base64(client_id:client_secret)>' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'grant_type=authorization_code' \
      --data-urlencode 'code=<CODE>' \
      --data-urlencode 'redirect_uri=<EXACT_REGISTERED_URI>' \
      --data-urlencode 'continuous_refresh=true'   # only if the app predates 2025-09-25
    
    # sandbox variant: https://api-sandbox.pinterest.com/v5/oauth/token
  6. Persist and refresh with the continuous refresh tokenagentinferred[S2][S5]

    Store access_token + refresh_token server-side, track expires_in / refresh_token_expires_in, and refresh on a timer. Legacy 365-day refresh tokens are gone; continuous refresh tokens have a 60-day window and refresh indefinitely. Use the Token Debugger when a token misbehaves (expired, insufficient scopes, logged-out user session).

    ↗ developers.pinterest.com/docs/api/v5/oauth-token/
  7. Smoke-test with a product-limited token or sandboxagentsourced ❝[S1][S3]

    Product-limited tokens expire after 24 hours and let you hit endpoints without the full flow; the sandbox host avoids touching production data. Watch the Trial ceiling of 1000 requests/day per app, and read x-ratelimit-* headers with curl -v.

    “Test tokens expire after 24 hours and allow you to explore certain endpoints faster.” — [S1] verified verbatim
    ↗ github.com/pinterest/api-quickstart

Make it production-ready

  1. Record the OAuth demo and request Standard accessyousourced ❝[S6]

    My apps → Upgrade on the app card (only visible when eligible) → confirm use case and privacy-policy link → upload the video showing the full OAuth flow and live Pinterest integration → submit. A terminal or Postman recording is explicitly acceptable, even if you are the only user.

    “We accept screen recordings of calls on your terminal or through tools such as Postman.” — [S6] verified verbatim
    ↗ developers.pinterest.com/docs/getting-started/access-tiers/
    ◆ prepared by agent · Standard-access demo video checklist
    OAuth demo checklist (Standard access)
    [ ] Start logged out of Pinterest.
    [ ] Click 'Connect Pinterest' in the app — show the real authorize URL with YOUR client_id.
    [ ] Show the Pinterest login, then the consent screen with the requested scopes visible.
    [ ] Complete consent; show the redirect landing on your callback with ?code=...
    [ ] Show the token exchange request (server logs or terminal, secrets masked).
    [ ] Make one live API call with the token (e.g. list boards) and show the response in YOUR app's UI.
    [ ] Narrate the scope justification in one sentence per scope.
    [ ] Confirm on camera that no passwords or session cookies are collected or stored.
    [ ] Keep it under ~3 minutes, single unedited take, real data.
  2. If denied, appeal through the Help Center ticket pathyousourced ❝[S6][S7]

    Allow a few days before following up. If rejected, re-check that the video shows the OAuth flow AND a live integration, then open an API Technical Support ticket from the Help Center ('Still need more help?').

    “If you want to appeal a denial, submit a ticket in our Help Center.” — [S6] verified verbatim
    ↗ developers.pinterest.com/docs/getting-started/access-tiers/

04Requirements, scopes & nuances

You'll need

  • ▸A Pinterest business account that administers the app — personal accounts and Business Access-provisioned accounts are not the admin path. sourced ❝[S1]
  • ▸A verified email address on that account, plus acceptance of the Developer Terms of Service before you can register anything. sourced ❝[S1]
  • ▸App name with at least 3 Latin letters/numbers, not containing the word "Pinterest". sourced ❝[S1]
  • ▸At least one registered redirect URI, matched exactly at authorize time and not itself issuing a redirect. sourced ❝[S1]
  • ▸A publicly accessible privacy policy hosted on a domain clearly associated with your company/app — a missing or inaccurate one is a stated Trial denial reason. sourced ❝[S6]
  • ▸For Standard access: a screen recording that shows the app sending users through the OAuth flow and not storing sensitive information. sourced ❝[S6]

Gotchas

  • !Trial access is not production: 1000 requests/day per app, and Pins/boards you create are visible only to their creator as sandbox entities. Real distribution needs Standard access. sourced ❝[S6][S3]
  • !Refresh tokens changed: the legacy 365-day refresh token is no longer supported. Apps created before Sept 25, 2025 must send continuous_refresh=true to get the 60-day token that refreshes indefinitely; newer apps get it automatically. sourced ❝[S4][S2]
  • !redirect_uri must be an exact string match against a registered URI and must not trigger a secondary redirect from your callback server. sourced ❝[S1]
  • !Doc inconsistency: the auth guide's Client Credentials example still says grant_type=authorization_code, while the endpoint reference enum lists client_credentials. Trust the enum. inferred[S4][S2]
  • !Denials are frequent and the rejection mail is generic ("demo did not show Pinterest integration" / "demo did not show full OAuth flow"), so treat the video as the deliverable that decides your launch. sourced ❝[S7][S6]
  • !Tokens can stop working for reasons other than expiry — logged-out user session or a password change invalidates the session; then you must re-run the Authorization Code grant. sourced ❝[S5]
Scope / permissionTierNoteEvidence
boards:readbasicRead boards. Ask for this before any write scope; combine with commas or spaces (boards:read,pins:read).sourced ❝[S4]
pins:readbasicRead Pins. The narrowest organic read scope shown in the docs.inferred[S4]
ads:readsensitiveRead ad accounts, campaigns, ad groups, ads — ad data is business-sensitive; request only if your agent reports on ads.sourced ❝[S3][S4]
ads:writesensitiveCreate/edit/delete ad entities. Highest-risk scope in the documented set — an agent with this can spend money.sourced ❝[S3][S4]
Pins/boards of non-business users (post-Sept-14-2026 apps)gatedApps registered on/after Sept 14, 2026 can get 403 PINNER_DATA_ACCESS_DENIED reading boards or Pins without Pinterest's authorization for non-business users.sourced ❝[S6]

05If you get blocked

✕Standard (production) upgrade gets rejected — demo lacks the full OAuth flow or a live Pinterest integration.sourced ❝[S7][S6]

→ Keep the demo video short and boring: full OAuth redirect, consent screen, code landing, token exchange, one live API call. Re-submit; if still rejected, open an 'API Technical Support' ticket in the Help Center.

✕You cannot see the app secret while the app is pending review, so the token exchange cannot be tested.sourced ❝[S5]

→ Plan Trial review into your schedule before you need the secret; until then prototype the redirect + callback handling against the documented authorize URL and use the api-quickstart repo structure.

✕No OAuth/OIDC discovery metadata exists, so generic OAuth clients that auto-configure will fail.inferred[S4][S2]

→ Hardcode the two endpoints: authorize https://www.pinterest.com/oauth/ and token https://api.pinterest.com/v5/oauth/token (sandbox: https://api-sandbox.pinterest.com/v5/oauth/token).

✕Five-app limit per developer; deleting an app is not self-serve.sourced ❝[S5]

→ Delete an existing app (requires a Support ticket) or ask Support to raise the limit; don't burn slots on throwaway apps.

✕Apps registered on/after Sept 14, 2026 can receive HTTP 403 PINNER_DATA_ACCESS_DENIED when reading boards or Pins for non-business users without Pinterest's authorization.sourced ❝[S6]

→ Handle the PINNER_DATA_ACCESS_DENIED 403 in code, and verify your use case is a business-account / authorized-user flow rather than reading arbitrary users' boards and Pins.

06Evidence: what was tested, sourced, and still uncertain

$ probes: live GETs with a dummy client_id, no credentials
✓ Discovery document (/.well-known/openid-configuration) → 404
https://api.pinterest.com/.well-known/openid-configuration
not published
∴ The API host publishes no OIDC metadata. Do not use libraries that require discovery; hardcode the authorization and token URLs.
✓ Discovery document (/.well-known/oauth-authorization-server) → 404
https://api.pinterest.com/.well-known/oauth-authorization-server
not published
∴ Same for the OAuth server metadata path on api.pinterest.com — 404. Endpoint config is manual only.
✓ Discovery document (/.well-known/openid-configuration) → 200
https://www.pinterest.com/.well-known/openid-configuration
non-JSON (text/html; charset=utf-8)
✓ Discovery document (/.well-known/oauth-authorization-server) → 200
https://www.pinterest.com/.well-known/oauth-authorization-server
non-JSON (text/html; charset=utf-8)
∴ The 200 here is the www HTML app shell catching every path, not a metadata document. Any 'discovery works' claim based on a 200 is wrong.
✓ Authorize endpoint with a fake client_id → 302
https://www.pinterest.com/oauth/?client_id=probe_invalid_client&response_type=code&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
redirect → https://www.pinterest.com/login/?next=%2Foauth%2F%3Fclient_id%3Dprobe_invalid_client%26response_type%3Dcode%26redirect_uri%3Dhttps%253A%252F%252Fexample.com%252
∴ The authorize endpoint is live and bounces unauthenticated users to /login/?next=/oauth/... before it ever validates client_id. Test the consent screen with a real app ID after Trial approval; a fake client_id never reaches client validation.

Sources read

  1. [S1] Pinterest Developers | Connect app official
  2. [S2] Pinterest Developers official
  3. [S3] Pinterest Developers | Rate limits official
  4. [S4] Set up authentication and authorization official
  5. [S5] Pinterest Developers | Faqs official
  6. [S6] Pinterest Developers | Access tiers official
  7. [S7] My Standard API Request application rejected twice - Need clarification third-party
  8. [S8] Install the Pinterest for Salesforce Commerce Cloud app official
  9. [S9] Business Manager: access, roles and permissions | Pinterest Business help official
  10. [S10] Business Manager: partner access | Pinterest Business help official
  11. [S11] GitHub - pinterest/api-quickstart: Code that makes it easy to get started with the Pinterest API. third-party
  12. [S12] How to Get OAuth Access Token for Pinterest? third-party
  13. [S13] Pinterest Developers official
  14. [composio] Composio — Managed OAuth apps directory official
  15. [probe] Live HTTP probes run by the agent (dummy client_id, no credentials) probe

Still uncertain

  • ? Neither source states a review SLA for Trial or Standard access; the 1–10 day and 1–4 week ranges are inferred from 'allow a few days' guidance and community denial threads.
  • ? The provided sources never list the full scope catalog (the scopes URL returned rate-limit content), so only boards:read, pins:read, ads:read and ads:write are documented here — check the scopes reference for write/organic and catalog scopes.
  • ? Whether an agent-only client-credentials token can access every ad/catalog endpoint is not stated; the docs only show it as a grant type.
  • ? It is not stated whether Standard access requires a business account (Trial explicitly does), nor whether a personal-account-only use case can ever pass Standard review.
  • ? Token rotation semantics (whether refresh returns a new refresh token each time) are not described in these sources.
  • ? Probes could not confirm that client_id validation happens on the authorize endpoint, since a fake client_id is intercepted by the login redirect first.
  • ? Generated automatically; no app was registered and no review was submitted.