Profiles

Connect OAuth Platforms

Connect LinkedIn and other OAuth platforms

Supported OAuth Platforms

  • LinkedIn - Currently available
  • Twitter/X - Coming soon
  • Facebook - Coming soon
  • Instagram - Coming soon

How OAuth Works

  1. User clicks "Connect LinkedIn" in your app
  2. They're redirected to postcore's OAuth endpoint
  3. postcore redirects them to LinkedIn for authorization
  4. User authorizes and returns to your app
  5. Connection is complete

LinkedIn Connection

Endpoint

GET /profiles/connect?apiKey=YOUR_KEY&platform=linkedin&profileKey=PROFILE_KEY&returnUrl=YOUR_CALLBACK

Query Parameters

ParameterRequiredDescription
apiKeyYesYour postcore API key
platformYesMust be "linkedin"
profileKeyNoExisting profile (auto-created if omitted)
returnUrlYesWhere to redirect after connection

Implementation

Step 1: Build the connection URL

function getLinkedInConnectionURL(profileKey) {
  const params = new URLSearchParams({
    apiKey: process.env.POSTCORE_API_KEY,
    platform: 'linkedin',
    profileKey: profileKey, // Or omit to auto-create
    returnUrl: 'https://yourapp.com/oauth/callback'
  });
  
  return `https://api.postcore.dev/profiles/connect?${params}`;
}
from urllib.parse import urlencode

def get_linkedin_connection_url(profile_key):
    params = {
        'apiKey': os.getenv('POSTCORE_API_KEY'),
        'platform': 'linkedin',
        'profileKey': profile_key,
        'returnUrl': 'https://yourapp.com/oauth/callback'
    }
    
    return f"https://api.postcore.dev/profiles/connect?{urlencode(params)}"

Step 2: Redirect the user

// React example
function ConnectLinkedInButton({ profileKey }) {
  const handleConnect = () => {
    const url = getLinkedInConnectionURL(profileKey);
    window.location.href = url;
  };

  return <button onClick={handleConnect}>Connect LinkedIn</button>;
}

Step 3: Handle the callback

After authorization, the user returns to your returnUrl with the profileKey:

https://yourapp.com/oauth/callback?profileKey=prof_abc123

Extract and save it:

// In your callback page
const urlParams = new URLSearchParams(window.location.search);
const profileKey = urlParams.get('profileKey');

if (profileKey) {
  console.log('LinkedIn connected!', profileKey);
  // Store profileKey if it was auto-created
  // Redirect to dashboard
  window.location.href = '/dashboard';
}
// app/oauth/callback/page.tsx
export default async function OAuthCallback({
  searchParams
}: {
  searchParams: Promise<{ profileKey?: string }>
}) {
  const { profileKey } = await searchParams;
  
  if (!profileKey) {
    return <div>Error: No profile key received</div>;
  }
  
  // Save to database if needed
  return (
    <div>
      <h1>LinkedIn Connected!</h1>
      <a href="/dashboard">Go to Dashboard</a>
    </div>
  );
}
app.get('/oauth/callback', (req, res) => {
  const { profileKey } = req.query;
  
  if (!profileKey) {
    return res.status(400).send('No profile key received');
  }
  
  console.log('LinkedIn connected:', profileKey);
  res.redirect('/dashboard?linkedin_connected=true');
});

Token Expiry

LinkedIn tokens expire after 60 days. Monitor expiry status:

const { profiles } = await fetch("https://api.postcore.dev/profiles", {
  headers: { "x-api-key": apiKey },
}).then((r) => r.json());

profiles.forEach((profile) => {
  profile.connectedPlatforms.forEach((platform) => {
    if (platform.platform === "linkedin" && platform.needsReconnect) {
      // Send notification to user
      notifyUser("LinkedIn needs reconnection");
    }

    if (platform.daysUntilExpiry && platform.daysUntilExpiry < 7) {
      // Warn user token expires soon
      notifyUser(`LinkedIn expires in ${platform.daysUntilExpiry} days`);
    }
  });
});

To reconnect, simply send the user through the OAuth flow again with the same profileKey.

Without a Profile Key

If you omit profileKey, postcore creates one automatically:

const url = `https://api.postcore.dev/profiles/connect?apiKey=${apiKey}&platform=linkedin&returnUrl=${returnUrl}`;
// No profileKey parameter - one will be created

// After OAuth, you'll get the new profileKey in your returnUrl

Save the returned profileKey with your user's account.

Error Responses

Invalid API Key

{
  "error": "INVALID_API_KEY",
  "message": "Invalid API key"
}

Status: 401 Unauthorized

Profile Not Found

{
  "error": "PROFILE_NOT_FOUND",
  "message": "Profile not found"
}

Status: 404 Not Found

Solution: The profileKey doesn't exist. Omit it to auto-create a new profile.