Docs: OAuth

OAuth integration

Build integrations that securely authenticate users, request scoped permissions, and access account details on behalf of Myhappr creators.

Myhappr uses standard OAuth 2.0 protocols. We support the Authorization Code Flow for server-to-server applications. Register your application inside your Developer Settings to obtain credentials. PKCE support for Single Page Applications (React, Vue, mobile apps) is coming soon.

What You Can Build

Use caseWhat OAuth gives you
Creator dashboardsPull transaction and support history to build deeper financial analytics or stream overlays.
Alert bots (Discord/Slack)Read notifications to trigger real-time alerts in community servers when a creator receives a tip.
Identity verificationAuthenticate users securely using their Myhappr account and access their verified email.
CRM syncingSync a creator's supporters to external tools like Mailchimp or Notion to manage their audience.

Authorized Scopes

Request only the scopes your application needs. The user will be prompted to grant or deny these permissions on the consent screen.

ScopeDescription
profile:readRead basic profile info (username, display name, bio, avatar).
email:readRead the verified email address.
supporters:readRead list of financial supporters and recent tip history.
notifications:readRead the creator's stored notification history (tips, payouts, milestones) from our database.
1

Redirect user to Myhappr Consent Screen

Redirect the user's browser to our authorization endpoint to begin the flow. Always pass a cryptographically secure state parameter to protect against CSRF attacks.

GEThttps://myhappr.com/oauth/authorize

Query parameter

FieldTypeRequiredDescription
client_idstringtrueYour registered application client ID.
redirect_uristringtrueThe callback URL where users return after authorization. Must exactly match your registered redirect URIs.
response_typestringtrueMust be set to 'code'.
scopestringtrueSpace-separated list of scopes (e.g. 'profile:read email:read').
statestringtrueA unique, secure random string. Your server must verify this state in the callback to prevent Cross-Site Request Forgery (CSRF).

Example Request Link

https://myhappr.com/oauth/authorize?client_id=mhc_abc123&redirect_uri=https://yourapp.com/callback&response_type=code&scope=profile:read email:read&state=71a6e9f2bc4d8e
2

Receive Authorization Code

If the user approves authorization, Myhappr redirects their browser to your registered redirect_uri with the temporary authorization code and your exact state value.

Example Callback URL

https://yourapp.com/callback?code=mac_code_92f8d1c&state=71a6e9f2bc4d8e
Security Alert (CSRF Validation): Store your generated state parameter in a secure short-lived Redis key or encrypted HTTP-only session cookie (e.g. 10-minute TTL). Your callback handler MUST verify that the state query parameter matches the stored value before exchanging the code for an access token, then immediately delete it to prevent replay attacks.
3

Exchange Code for Access Token

Make a server-to-server POST request to exchange the temporary authorization code for a long-lived access token. You must pass your Client ID and Client Secret in the Authorization header using Basic Authentication.

POSThttps://api.myhappr.com/api/v1/oauth/token

Request body

FieldTypeRequiredDescription
grant_typestringtrueMust be 'authorization_code'.
codestringtrueThe authorization code received in the callback query.
redirect_uristringtrueMust be exactly the same redirect URI sent in Step 1.

Example Token Request

curl -X POST "https://api.myhappr.com/api/v1/oauth/token" \
  -H "Authorization: Basic bWhjX2FiYzEyMzptaHNfeW91cl9jbGllbnRfc2VjcmV0X2hlcmU=" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "mac_code_92f8d1c",
    "redirect_uri": "https://yourapp.com/callback"
  }'

Example Successful Response

{
  "access_token": "mha_jwt_token_payload_here",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "profile:read email:read",
  "refresh_token": "mhrt_refresh_token_payload_here"
}

expires_in is in seconds — 3600 seconds = 60 minutes (1 hour). Use the refresh_token (valid for 30 days) to obtain a new access token before it expires.

4

Access User Information

Call the user info endpoint passing the retrieved access_token inside the Authorization header to access authorized resources.

GEThttps://api.myhappr.com/api/v1/oauth/userinfo

Header

FieldTypeRequiredDescription
AuthorizationstringtrueBearer <access_token>

Example UserInfo Call

curl "https://api.myhappr.com/api/v1/oauth/userinfo" \
  -H "Authorization: Bearer mha_jwt_token_payload_here"

Example UserInfo Response

{
  "id": "usr_cuid10293",
  "username": "samuel",
  "display_name": "Samuel Tuoyo",
  "email": "samuel@happr.com",
  "avatar": "https://ui-avatars.com/api/?name=Samuel+Tuoyo",
  "bio": "Building the future of African creators.",
  "is_pro_user": true
}

Transactions API

Retrieve a paginated list of successful transactions for the authenticated creator. Requires the supporters:read scope.

GEThttps://api.myhappr.com/api/v1/oauth/transactions

Query parameter

FieldTypeRequiredDescription
limitintegerfalseNumber of transactions to return (max 100, default 50)
cursorstringfalseCursor for pagination (the ID of the last transaction received from the previous page)

Example Transactions Call

curl "https://api.myhappr.com/api/v1/oauth/transactions?limit=10" \
  -H "Authorization: Bearer mha_jwt_token_payload_here"

Example Response

{
  "success": true,
  "data": [
    {
      "id": "tx_cuid10293",
      "amount": 1000,
      "currency": "NGN",
      "supporter_name": "John Doe",
      "message": "Keep up the great work!",
      "created_at": "2026-08-12T10:00:00.000Z"
    }
  ],
  "meta": {
    "next_cursor": "tx_cuid10292",
    "has_more": true
  }
}

Notifications API

Retrieve a paginated list of stored notifications for the authenticated creator. Myhappr writes a notification record into our database whenever a tip is received, a payout completes, or a milestone is hit. Requires the notifications:read scope.

GEThttps://api.myhappr.com/api/v1/oauth/notifications

Query parameter

FieldTypeRequiredDescription
limitintegerfalseNumber of notifications to return (max 100, default 50)
cursorstringfalseCursor for pagination - pass the id of the last notification from the previous response

Example Request

curl "https://api.myhappr.com/api/v1/oauth/notifications?limit=10" \
  -H "Authorization: Bearer mha_jwt_token_payload_here"

Example Response

{
  "success": true,
  "data": [
    {
      "id": "cmssrhxeh0002vcuf6e6b7g7r",
      "type": "security_alert",
      "title": "New Login Detected",
      "message": "A new login was detected from IP: ::1 using Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36.",
      "read": false,
      "meta": null,
      "created_at": "2026-08-14T09:45:54.521Z"
    }
  ],
  "meta": {
    "next_cursor": null,
    "has_more": false
  }
}

OAuth 2.0 Security Checklist

Protect your application and user credentials by applying these industry-standard security guidelines:

Prevent CSRF (State Param)

Always generate a cryptographically random state parameter for each login session. Verify it matches on return before exchanging tokens.

Avoid Credentials Leakage

Never commit your Client Secret to git repositories or expose it on frontend single-page apps. Keep it safely secured on your backend server.

Exact Redirect Matching

Ensure your registered redirect callback matches exactly. We enforce strict character matching to prevent redirect hijack vectors.

PKCE (Future Support)

We plan to introduce PKCE (Proof Key for Code Exchange) in the future to protect public clients like mobile apps and single-page apps (SPAs). For now, you must never store your Client ID or Client Secret on the frontend. Our current flow is strictly for server-side environments.