RACP & Agents Docs ยท OAuth 2.0 & API v1
API v1 ยท Stable
OAuth 2.0 ยท RFC 6749 API v1 ยท Stable

Connekt OAuth API

Let your users sign in with their Connekt account and access their social data โ€” securely, with their explicit consent. Built on standard OAuth 2.0 + PKCE. One integration handles students, commercial apps, and enterprise microservices.

๐Ÿ”

Standard OAuth 2.0

RFC 6749, RFC 7636 (PKCE), RFC 7009 (revocation), RFC 7662 (introspection). Use any OAuth library.

๐Ÿค–

RACP Webhooks

Same HMAC-SHA256 signing as the Agent platform. If you use RACP, you already know how to verify OAuth events.

โšก

Versioned & Stable

All endpoints under /api/v1/ follow a no-breaking-changes contract. Ship to production with confidence.

Base URLs

Authorization Server https://connekt.social
API v1 https://connekt.social/api/v1
OpenID Discovery https://connekt.social/.well-known/openid-configuration
Developer Studio https://dev.connekt.social

Scopes

Request only the scopes your app actually needs. Users explicitly approve each scope on the consent screen.

Scope Permission Data Returned
profile.read ๐Ÿ‘ค View basic profile username, avatar_url, bio, name, created_at
profile.extended ๐Ÿ’Ž View Connekt status user_status, pioneer_status, is_pioneer, email_verified
connections.read ๐Ÿ”— View connections followers_count, following_count, connection lists
posts.read ๐Ÿ“ฐ View posts post content, media, likes, comments
posts.write โœ๏ธ Create posts Create posts on behalf of user
channels.read ๐Ÿ“ก View channel memberships subscribed channels, ownership status
presence ๐ŸŸข View online status is_online, last_seen (approximate)
notifications.write ๐Ÿ”” Send notifications Push Connekt in-app notifications

Authorization Code Flow

The standard "Sign in with Connekt" flow. Use this for web apps, mobile apps, and any app with a backend.

1

Redirect user to authorization endpoint

Build the URL and send the user there.

2

User approves on Connekt consent screen

Connekt shows your app name, logo, and the exact scopes you requested.

3

Receive authorization code via redirect

Connekt redirects back to your redirect_uri with ?code=...&state=...

4

Exchange code for tokens

POST to /oauth/token. Confidential apps include client_secret. Public apps (SPA/mobile) omit it and use PKCE only.

5

Use access token on API v1 endpoints

Bearer token in Authorization header.

Step 1 โ€” Authorization URL

GET https://connekt.social/oauth/authorize
  ?response_type=code
  &client_id=ck_your_client_id
  &redirect_uri=https://yourapp.com/callback
  &scope=profile.read%20connections.read
  &state=random_csrf_token
  &code_challenge=BASE64URL(SHA256(verifier))  # PKCE โ€” strongly recommended
  &code_challenge_method=S256

Step 4 โ€” Token Exchange (confidential client)

POST https://connekt.social/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=ck_your_client_id
&client_secret=your_client_secret   # Server-side only
&code=AUTH_CODE_HERE
&redirect_uri=https://yourapp.com/callback
&code_verifier=YOUR_PKCE_VERIFIER

Step 4 โ€” Token Exchange (public client โ€” no secret)

POST https://connekt.social/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=ck_your_client_id
&code=AUTH_CODE_HERE
&redirect_uri=https://yourapp.com/callback
&code_verifier=YOUR_PKCE_VERIFIER

Token Response

{
  "access_token": "ckt_AbCdEf...",
  "token_type": "Bearer",
  "expires_in": 86400,
  "refresh_token": "ckr_XyZwVu...",
  "scope": "profile.read connections.read"
}

PKCE โ€” RFC 7636

Use PKCE for all public clients (SPAs, mobile apps, Electron). The JS widget handles this automatically.

// Generate PKCE pair (browser or Node.js)
const verifier = crypto.randomUUID().replace(/-/g, '') + crypto.randomUUID().replace(/-/g, '');

const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const digest = await crypto.subtle.digest('SHA-256', data);
const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');

// challenge โ†’ code_challenge param
// verifier  โ†’ code_verifier in token exchange

Public Client Flow โ€” No client_secret

For apps that cannot keep a secret (SPAs, mobile, desktop). Register the app as a Public Client in Studio, then exchange the code with only the client_id and PKCE verifier.

POST https://connekt.social/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=ck_your_client_id
&code=AUTH_CODE_HERE
&redirect_uri=https://yourapp.com/callback
&code_verifier=YOUR_PKCE_VERIFIER

Note: No client_secret is sent. The PKCE verifier proves the caller is the same app that started the flow.

Client Credentials

Server-to-server access with no user involved. For agents, backend systems, and data pipelines. Your app must be registered with this grant type enabled.

POST https://connekt.social/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=ck_your_client_id
&client_secret=your_client_secret
&scope=profile.read

Token Refresh

Access tokens expire after 24 hours. Use the refresh token to get a new pair. Refresh tokens rotate on each use (old one is invalidated). A RACP token.refreshed webhook is fired to your registered endpoint.

POST https://connekt.social/oauth/token/refresh
Content-Type: application/x-www-form-urlencoded

refresh_token=ckr_XyZwVu...
&client_id=ck_your_client_id
&client_secret=your_client_secret

Token Revocation โ€” RFC 7009

Revoke tokens when a user disconnects your app. Always returns 200 even if the token is not found (per RFC). Fires a RACP token.revoked webhook.

POST https://connekt.social/oauth/token/revoke
Content-Type: application/x-www-form-urlencoded

token=ckt_AbCdEf...
&client_id=ck_your_client_id
&client_secret=your_client_secret

Token Introspection โ€” RFC 7662 NEW

For resource servers and microservices that need to verify a token without calling /oauth/userinfo. Validates the token and returns its metadata. Only exposes data about tokens issued to your app.

POST https://connekt.social/oauth/token/introspect
Content-Type: application/x-www-form-urlencoded

token=ckt_AbCdEf...
&client_id=ck_your_client_id
&client_secret=your_client_secret

Active Token Response

{
  "active": true,
  "sub": "user-public-uuid",
  "username": "kudakwashe",
  "scope": "profile.read connections.read",
  "client_id": "ck_your_client_id",
  "token_type": "Bearer",
  "exp": 1748000000,
  "iat": 1747913600,
  "grant_type": "authorization_code"
}

Invalid/Expired Token

{ "active": false }

API v1 Reference

All endpoints require Authorization: Bearer <access_token>. Rate limit headers are present on every response.

GET /api/v1/me profile.read

Current authenticated user profile.

Example Response

{"status":"success","user":{"id":"uuid","username":"kudakwashe","name":"Kudakwashe M.","avatar_url":"https://...","bio":"...","is_online":true,"scopes_granted":["profile.read"]}}
GET /api/v1/me/connections connections.read

User's followers or following. Params: type=followers|following, page, per_page (max 50).

Example Response

{"status":"success","type":"following","connections":[{"id":"uuid","username":"jane","avatar_url":"...","is_online":false}],"has_more":false,"page":1}
GET /api/v1/me/posts posts.read

User's posts, newest first. Params: page, per_page (max 50).

Example Response

{"status":"success","posts":[{"id":"uuid","content":"...","media_url":"https://...","created_at":"2026-01-01T00:00:00","likes_count":42,"comments_count":7,"visibility":"public"}],"has_more":true,"total":88}
GET /api/v1/me/channels channels.read

Channels the user is subscribed to.

Example Response

{"status":"success","channels":[{"id":"uuid","name":"Tech Talk ZW","subscriber_count":1200,"is_owner":false}],"total":3}
GET /api/v1/users/:id profile.read

Look up any user by public_id or username.

Example Response

{"status":"success","user":{"id":"uuid","username":"tinodashe","name":"Tinodashe ...","avatar_url":"...","bio":"..."}}
POST /api/v1/posts posts.write

Create a post on behalf of the user. Body: { content, visibility }.

Example Response

{"status":"success","post":{"id":"uuid","content":"Hello from my app!","visibility":"public","created_at":"2026-01-01T00:00:00"}}

Sign in with Connekt Widget

The fastest way to add Connekt authentication. Drop in a script tag, add a div. Works in any HTML page. PKCE is handled automatically.

1. Include the script

<script src="https://connekt.social/static/js/connekt-oauth.js"></script>

2. Add the button div

<div data-connekt-client-id="ck_your_client_id"
     data-connekt-scopes="profile.read connections.read"
     data-connekt-redirect-uri="https://yourapp.com/callback"
     data-connekt-theme="dark">
</div>

3. Listen for the auth code

document.addEventListener('ckt:success', async (e) => {
    const { code, state, verifier } = e.detail;

    // Send to YOUR server โ€” never exchange the code client-side
    const res = await fetch('/auth/connekt/callback', {
        method: 'POST',
        body: JSON.stringify({ code, state, verifier }), // Include PKCE verifier!
        headers: { 'Content-Type': 'application/json' }
    });
    const { user } = await res.json();
    console.log('Signed in as:', user.username);
});

document.addEventListener('ckt:error', (e) => {
    console.error('Auth failed:', e.detail.error);
});

โš ๏ธ Security: Never expose client_secret client-side

For confidential apps, the client_secret must stay on your server. The widget gives you a code โ€” send that to your backend, which does the token exchange with the secret. Public apps (SPA/mobile) omit the secret entirely and use PKCE only.

Widget Attributes

AttributeRequiredDescription
data-connekt-client-id Yes Your app's client_id from Studio
data-connekt-redirect-uri Yes Must match a registered redirect URI
data-connekt-scopes Yes Space-separated scope list
data-connekt-theme No "dark" (default) or "light"
data-connekt-mode No "popup" (default) or "redirect"
data-connekt-state No Custom state value (auto-generated if omitted)

Webhooks โ€” RACP Protocol

Receive real-time events when things happen to your users. OAuth webhooks use the same RACP protocol as Connekt Agents โ€” same HMAC-SHA256 signing, same X-Connekt-Signature header, same User-Agent. If you already verify RACP agent events, your verification code works here unchanged.

Available Events

token.issued

A user authorizes your app (new token granted)

token.revoked

A user revokes your app's access

token.refreshed

A token is refreshed (old token invalidated, new one issued)

user.post.created

A connected user creates a post (requires posts.read scope)

Webhook Payload Shape

{
  "event": "token.issued",
  "timestamp": 1748000000,
  "platform": "connekt",
  "api_version": "1.0",
  "data": {
    "user": { "id": "user-uuid", "username": "kudakwashe" },
    "token_prefix": "ckt_AbCdEf",
    "scopes": ["profile.read", "connections.read"],
    "expires_in": 86400
  }
}

Verify the Signature (Python)

import hmac, hashlib

def verify_connekt_webhook(payload_bytes, signature_header, webhook_secret):
    """Same code as RACP agent verification."""
    expected = hmac.new(
        webhook_secret.encode('utf-8'),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

# Flask example
@app.route('/webhook/connekt', methods=['POST'])
def connekt_webhook():
    sig = request.headers.get('X-Connekt-Signature', '')
    if not verify_connekt_webhook(request.data, sig, WEBHOOK_SECRET):
        return 'Unauthorized', 401

    event = request.json
    if event['event'] == 'token.issued':
        user = event['data']['user']
        print(f"New user connected: {user['username']}")

    return '', 200

Delivery Guarantees

  • At-least-once delivery with 3 retries (1s โ†’ 3s โ†’ 9s backoff)
  • 10-second request timeout per attempt
  • Delivery is non-blocking โ€” never slows down the primary OAuth flow
  • Your endpoint should return 200/201/202/204 to acknowledge
  • All delivery attempts visible in Studio event log

Rate Limits

Enforced via Redis sliding window. The Retry-After header tells you exactly how long to wait.

PlanCalls / DayCalls / Minute
Free50030
Developer5,000120
Pro50,000600

Rate Limit Response Headers

X-RateLimit-Limit-Day: 5000
X-RateLimit-Remaining-Day: 4872
X-RateLimit-Limit-Minute: 120
X-RateLimit-Remaining-Minute: 117
X-RateLimit-Plan: developer
X-Connekt-API-Version: 1.0

429 Too Many Requests

{
  "error": "rate_limit_exceeded",
  "error_description": "You have exceeded your API rate limit. Check the Retry-After header.",
  "docs": "https://connekt.social/developers/docs/oauth#rate-limits"
}

Error Reference

All errors follow the OAuth 2.0 error format. Non-200 responses always have error and error_description fields.

HTTPerrorCause
400 invalid_request Missing or malformed parameter
400 invalid_grant Authorization code invalid, expired, or already used
400 unsupported_grant_type grant_type not supported by this app
401 invalid_client client_id/secret mismatch or app is inactive
401 invalid_token Bearer token missing, invalid, expired, or revoked
403 insufficient_scope Token does not have required scope
404 not_found Resource not found
429 rate_limit_exceeded Daily or per-minute limit reached

OpenID Discovery

Standard OIDC discovery document โ€” lets OAuth libraries auto-configure from a single URL.

GET https://connekt.social/.well-known/openid-configuration
{
  "issuer": "https://connekt.social",
  "authorization_endpoint": "https://connekt.social/oauth/authorize",
  "token_endpoint": "https://connekt.social/oauth/token",
  "userinfo_endpoint": "https://connekt.social/oauth/userinfo",
  "revocation_endpoint": "https://connekt.social/oauth/token/revoke",
  "introspection_endpoint": "https://connekt.social/oauth/token/introspect",
  "scopes_supported": ["profile.read", "profile.extended", "..."],
  "grant_types_supported": ["authorization_code", "client_credentials", "refresh_token"],
  "code_challenge_methods_supported": ["S256", "plain"]
}

Sample Apps & Integrations

The fastest way to get started is by following a reference implementation. Clone a repository and be up and running in minutes.

Ready to integrate?

Register your app in Connekt Studio and get your client credentials in under a minute.