Verify social media account ownership in one integration
Let users connect their TikTok, Instagram, X (Twitter), LinkedIn, YouTube, Facebook, Pinterest or Threads account through PostSyncer, and receive back a cryptographically signed proof that they really own it. No per-platform OAuth to build, register or maintain.
# 1. Your server creates a session (api_key stays server-side) curl -X POST https://postsyncer.com/api/oauth/delegate/sessions \ -H "Authorization: Bearer $POSTSYNCER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "platform": "tiktok", "callback_url": "https://yourapp.com/cb", "state": "a1b2c3" }' # → opaque, single-use URL for the browser { "authorize_url": "https://app.postsyncer.com/oauth/delegate?request=psd_…", "expires_in": 900 }
Verify ownership on every platform PostSyncer supports
Stop building OAuth for every platform
Proving that a user owns a social account usually means registering a developer app with every network, getting through each app review, and maintaining token refreshes, scopes and breaking changes forever - per platform.
PostSyncer already does all of that. With OAuth delegation you reuse it: send the user through PostSyncer once and receive the platform's permanent user id plus a signature you verify with a shared secret. Learn more about our social media API and MCP tools.
- ✓ One integration covers every supported platform
- ✓ Tamper-proof HMAC-SHA256 ownership proof
- ✓ No social accounts or tokens stored on your side
- ✓ Built-in CSRF (state) and a 5-minute proof expiry
- ✓ Returns the platform's permanent, spoof-proof user id
How OAuth delegation works
Four steps from your app to a verified, signed proof of ownership.
Create a session
Your server calls /oauth/delegate/sessions
with your API key in the header. You get back an opaque, single-use authorize URL.
Authorize
Redirect the user to that URL. PostSyncer runs the platform's normal OAuth consent flow - your API key never touches the browser.
Receive proof
We redirect back to your callback with platform_id,
handle, expires
and a signed sig.
Verify
Check the state, confirm it hasn't expired, and verify the signature with your signing
secret. Then trust platform_id as proof.
Quickstart
Create a session on your server, send the user to authorize, then verify the signed callback. Pick your language:
// 1) Create a delegation session (server-side) const r = await fetch("https://postsyncer.com/api/oauth/delegate/sessions", { method: "POST", headers: { Authorization: `Bearer ${process.env.POSTSYNCER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ platform: "tiktok", callback_url: "https://yourapp.com/postsyncer/callback", state, // random, persisted, single-use }), }); const { authorize_url } = await r.json(); res.redirect(authorize_url); // 2) send the user to authorize // 3) verify the signed callback PostSyncer redirects back to import crypto from "crypto"; function verify(q, secret, expectedState) { if (q.state !== expectedState) return false; // CSRF if (Number(q.expires) < Date.now() / 1000) return false; // fresh const base = `platform=${q.platform}&platform_id=${q.platform_id}` + `&handle=${q.handle}&state=${q.state}&expires=${q.expires}`; const expected = crypto.createHmac("sha256", secret).update(base).digest("hex"); return crypto.timingSafeEqual(Buffer.from(q.sig), Buffer.from(expected)); }
Prefer to test first? Point callback_url at the built-in local
tester and PostSyncer will report each verification check for you. See the
full API reference.
Verifiable by design
Every successful proof is signed with HMAC-SHA256 over a fixed base string using the signing secret tied to your API key. Recompute it on your server and compare in constant time:
base = "platform={platform}&platform_id={platform_id}"
+ "&handle={handle}&state={state}&expires={expires}"
sig = HMAC_SHA256(base, your_signing_secret)
Generate your signing secret in Settings → API Keys in the PostSyncer app - click the shield "Generate signing key" button on the key's row. It is shown once; regenerating invalidates the previous secret.
Build it yourself vs. PostSyncer delegation
| Build OAuth yourself | PostSyncer delegation | |
|---|---|---|
| Platforms to integrate | One per network, separately | A single API for all of them |
| App reviews & approvals | Per platform, ongoing | Already handled by PostSyncer |
| Token storage & refresh | You build and secure it | Not your problem |
| Ownership proof | You design it | Signed HMAC-SHA256 out of the box |
| Time to first verification | Weeks | 5 Minutes |
Who uses OAuth delegation
Any product that needs to know a user truly owns a social handle.
Creator marketplaces
Confirm a creator really controls the handle before paying out, listing, or ranking them.
Brand & influencer platforms
Verify account ownership during onboarding without ever storing platform credentials.
Reward & loyalty apps
Tie rewards to a verified, permanent platform id that can't be spoofed or transferred.
Social login & KYC flows
Add "verify your social" as a trust signal alongside your existing identity checks.
Giveaway & UGC tools
Make sure entries come from real, owned accounts before counting them.
Agencies & SaaS
Onboard client accounts with verifiable proof, then manage them with the PostSyncer API.
Frequently Asked Questions
Everything developers ask about verifying social account ownership
OAuth delegation lets a third-party app connect a user's social media account through PostSyncer and receive back a cryptographically signed proof of ownership. Instead of registering and maintaining an OAuth integration with every platform (TikTok, Instagram, X/Twitter, LinkedIn, YouTube, and more), you reuse PostSyncer's existing integrations and verify the result with an HMAC-SHA256 signature.
You redirect the user into the PostSyncer delegation flow for that platform. After they authorize, PostSyncer returns the platform's permanent user id (such as a TikTok open_id or X user_id), the handle, an expiry timestamp, and an HMAC-SHA256 signature. You recompute the signature with your signing secret; if it matches and has not expired, you can trust the platform id as verified ownership proof.
No. Your API key is a full-access secret, so delegation starts with a server-to-server call from your backend (the key travels in the Authorization header). PostSyncer returns an opaque, single-use authorize URL, and only that token ever touches the user's browser.
Any platform PostSyncer supports that uses standard OAuth: TikTok, Instagram, X (Twitter), LinkedIn, YouTube, Facebook, Pinterest, and Threads. Credential-based platforms (Bluesky, Telegram) and instance-based Mastodon are not part of the delegation flow.
No. The platform id and handle are read directly from the platform's OAuth response and passed through to your callback. Nothing about the connection is persisted on your behalf beyond the API key's signing secret.
PostSyncer signs the string platform={platform}&platform_id={platform_id}&handle={handle}&state={state}&expires={expires} with HMAC-SHA256 using your signing secret. Your server recomputes the same HMAC and compares it in constant time, checks that the state matches what you issued (single use), and confirms expires is in the future.
Each signed callback includes an expires timestamp set five minutes in the future. Treat any proof received after that as expired and reject it.
In the PostSyncer app, open Settings → API Keys and click the “Generate signing key” (shield) button on the API key you want to use. The secret is shown once; regenerating it invalidates the previous one.
Ready To Grow Without The Guess Work?
Loved by 75,000+ creators