Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.social-api.ai/llms.txt

Use this file to discover all available pages before exploring further.

SocialAPI uses OAuth in two distinct contexts:
  1. Connecting platform accounts (Instagram, Facebook, etc.) to your SocialAPI account so you can manage them through the API.
  2. Authenticating MCP/API clients (Claude, ChatGPT, Cursor) via the built-in OAuth 2.1 authorization server so they can call the API on your behalf.

Connecting platform accounts

SocialAPI manages platform OAuth on your behalf. Your application kicks off the connection, sends the user to the platform’s consent screen, and receives a redirect back to a URL of your choice with the result. You never see or store platform access tokens — SocialAPI persists them encrypted and proxies all subsequent calls. This is a managed connection pattern, not an OAuth flow you implement against SocialAPI. For OAuth 2.1 (used by MCP and third-party API clients calling SocialAPI), see the section below.

Step 1: Initiate the connection

Call POST /v1/accounts/connect with the platform slug, your post-connection redirect_uri, and an optional state value for correlation:
curl -X POST https://api.social-api.ai/v1/accounts/connect \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "instagram",
    "redirect_uri": "https://app.example.com/oauth/callback",
    "state": "session_abc123"
  }'
Fields:
FieldLocationRequiredNotes
platformtop-levelyesPlatform slug (instagram, facebook, threads, tiktok, linkedin, twitter, youtube, google).
redirect_uritop-levelrecommendedYour post-connection callback. Must be pre-registered (see Whitelisting redirect URIs). If omitted, the user sees a built-in HTML success page instead of being redirected.
statetop-leveloptionalOpaque correlation value, max 512 chars, echoed back verbatim in the final redirect. Use it to tie the result to a session on your side.
brand_idtop-leveloptionalAttach the account to an existing brand. If omitted, a new brand is auto-created.
metadatatop-leveloptionalPlatform-specific connection data only (for example, TikTok BYOK uses this for apikey). For standard managed OAuth this is empty or omitted.
Response (HTTP 202):
{
  "auth_url": "https://www.instagram.com/oauth/authorize?client_id=...&state=...",
  "state": "4a8f2c1e9b3d7f06a5c2e8b4d1f3a7e2",
  "message": "Redirect the user to auth_url"
}
The state in the response is SocialAPI’s internal CSRF token used between our connect call and our platform callback. Your application does not need to read or store it; just send the user to auth_url.

Step 2: User authorizes on the platform

Redirect your user to the auth_url. They log in to the platform and grant permissions. The platform redirects back to SocialAPI’s callback (not yours). SocialAPI exchanges the code for an access token, persists it encrypted, and then 302-redirects the user to your redirect_uri.

Step 3: Receive the result at your redirect_uri

Success:
https://app.example.com/oauth/callback
  ?status=success
  &platform=instagram
  &state=session_abc123
  &account_id=acc_01HZ9X3Q4R5M6N7P8V2K0W1J
One connection produces exactly one account_id. Facebook accounts that manage multiple Pages still resolve to a single account in the connection result; Page details are exposed separately under /v1/accounts/{id}/pages and are not part of this flow. Error (the user denied consent, the platform returned an error, or the link expired):
https://app.example.com/oauth/callback
  ?status=error
  &error=access_denied
  &error_description=The+user+denied+the+request
  &platform=instagram
  &state=session_abc123
Always check status first. On success, persist the account_id against your user record and call /v1/accounts/{id} for full account details. On error, surface a retry path in your UI — the customer can restart from Step 1.

Fallback when redirect_uri is omitted

If your connect call did not include redirect_uri, SocialAPI renders a built-in HTML success or error page in place of the redirect. This is intended for ad-hoc connections (for example, the SocialAPI dashboard itself); production integrations should always supply redirect_uri.

Whitelisting redirect URIs

Every redirect_uri you use must be pre-registered. Register URIs from the SocialAPI dashboard under Settings → OAuth redirect URIs. The management API exists at /v1/oauth/redirect-uris but is dashboard-only (requires the dashboard JWT, not an API key). A connect call with a redirect_uri that is not on the whitelist returns 400 with an error.

Correlation state (customer-controlled)

The top-level state field on POST /v1/accounts/connect is your correlation token, not a security primitive enforced by SocialAPI. It is echoed back unchanged in the final redirect. Common uses:
  • Tie the redirect to the originating session (set state to a server-side session ID).
  • CSRF defense for your own application — generate a random value, store it in the user’s session, and verify it matches when the redirect lands.
SocialAPI does not validate state. If you do not pass one, the final redirect will include state= with an empty value.

Listing connected accounts

curl https://api.social-api.ai/v1/accounts \
  -H "Authorization: Bearer $SOCAPI_KEY"

Reconnecting an account

If you call POST /v1/accounts/connect for an account that is already connected, the flow runs again and the stored token is upserted. This is safe to call when tokens expire and is the supported path for token refresh on platforms that lack long-lived tokens.

OAuth 2.1 for MCP and API clients

SocialAPI includes a built-in OAuth 2.1 authorization server that enables MCP clients (Claude, ChatGPT, Cursor) and other third-party applications to authenticate users and call the API on their behalf. The implementation follows these RFCs:
  • RFC 8414 for authorization server metadata discovery
  • RFC 7591 for dynamic client registration
  • RFC 7636 for PKCE (required)
  • RFC 7009 for token revocation

Discovery

Clients can discover the authorization server configuration at:
GET /.well-known/oauth-authorization-server
Response:
{
  "issuer": "https://api.social-api.ai",
  "authorization_endpoint": "https://api.social-api.ai/oauth/authorize",
  "token_endpoint": "https://api.social-api.ai/oauth/token",
  "registration_endpoint": "https://api.social-api.ai/oauth/register",
  "revocation_endpoint": "https://api.social-api.ai/oauth/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_methods_supported": ["client_secret_post"],
  "code_challenge_methods_supported": ["S256"],
  "scopes_supported": ["social:all"]
}

Step 1: Register a client

Register your application using dynamic client registration:
curl -X POST https://api.social-api.ai/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My MCP Client",
    "redirect_uris": ["https://app.example.com/callback"]
  }'
Response (HTTP 201):
{
  "client_id": "a1b2c3d4e5f6...",
  "client_secret": "s3cr3t...",
  "client_name": "My MCP Client",
  "redirect_uris": ["https://app.example.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_post"
}
The client_secret is returned once. Store it securely. It cannot be retrieved again.

Step 2: Authorize the user

Redirect the user to the authorization endpoint with PKCE parameters:
GET /oauth/authorize
  ?client_id=a1b2c3d4e5f6...
  &redirect_uri=https://app.example.com/callback
  &response_type=code
  &scope=social:all
  &state=random_csrf_value
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
The API validates the client and redirect URI, then redirects the user to the SocialAPI dashboard consent screen. After the user approves, they are redirected back to your redirect_uri with ?code=...&state=....
PKCE is required. The only supported challenge method is S256. Requests without a code_challenge are rejected with 400.
Single scope. The only supported scope is social:all, which grants full access to the user’s account. This is the default if no scope is specified.

Step 3: Exchange the code for tokens

curl -X POST https://api.social-api.ai/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "client_id=a1b2c3d4e5f6..." \
  -d "client_secret=s3cr3t..." \
  -d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" \
  -d "redirect_uri=https://app.example.com/callback"
Response:
{
  "access_token": "eyJhbGciOiJFZERTQSIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rt_a1b2c3d4...",
  "scope": "social:all"
}
The access token is an EdDSA/Ed25519 signed JWT valid for 1 hour. Use it as a Bearer token for all /v1 endpoints.

Step 4: Refresh the access token

When the access token expires, use the refresh token to get a new pair:
curl -X POST https://api.social-api.ai/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=rt_a1b2c3d4..." \
  -d "client_id=a1b2c3d4e5f6..."
The response contains a new access token and a new refresh token. The old refresh token is invalidated (rotation is enforced). Refresh tokens expire after 30 days.

Revoking tokens

To revoke a refresh token (for example, on user logout):
curl -X POST https://api.social-api.ai/oauth/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=rt_a1b2c3d4..." \
  -d "client_id=a1b2c3d4e5f6..."
Per RFC 7009, this endpoint always returns 200, even if the token is already invalid.

Supporting endpoints

EndpointMethodPurpose
/.well-known/oauth-authorization-serverGETRFC 8414 metadata discovery
/oauth/registerPOSTRFC 7591 dynamic client registration
/oauth/authorizeGETAuthorization with PKCE
/oauth/tokenPOSTCode exchange and refresh token rotation
/oauth/revokePOSTRFC 7009 token revocation

MCP server card

MCP clients can discover SocialAPI as a tool provider via the server card:
GET /.well-known/mcp/server-card.json
The protected resource metadata (RFC 9470) is available at:
GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-protected-resource/mcp