Home Uncategorized

API Keys

Last updated on Apr 27, 2026

API keys & authentication

The LinkMe platform supports two auth surfaces:

  • Portal user authentication (email/password + social login)
  • API authentication (app/server keys for SDK and automation calls)

Use this page as the canonical reference for auth behavior, setup, and troubleshooting.

Portal user authentication

Portal sign-in supports:

  • Email/password
  • Google OAuth
  • GitHub OAuth

Account linking behavior

Account linking is currently based on normalized email (trim + lowercase).

  • If social login returns an email that already exists, LinkMe reuses that existing user.
  • If no user exists for that email, LinkMe creates a new account.
  • A single user can therefore use email/password and social login if the email matches.

Verification behavior

  • Email/password registration sends verification email (unless invite claim flow applies).
  • OAuth-created users are marked verified during callback.

OAuth configuration

Google OAuth

Required server env:

  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET

Callback URL:

  • https://<your-auth-domain>/api/auth/google/callback

GitHub OAuth

Required server env:

  • GH_OAUTH_CLIENT_ID
  • GH_OAUTH_CLIENT_SECRET

Runtime fallback is supported for legacy local envs:

  • GITHUB_CLIENT_ID
  • GITHUB_CLIENT_SECRET

Callback URL:

  • https://<your-auth-domain>/api/auth/github/callback

If you use GitHub Actions secrets, do not start names with GITHUB_ (reserved prefix).

API key authentication (Edge + tooling)

The Edge API trusts signed requests from LinkMe app credentials managed in Portal.

API access is available on paid plans. On Free, requests return paid_plan_required with an upgrade URL.

Key types

Key type Use case Capabilities
App API Key Used by SDK/runtime resolve and claim flows for a specific app. can_read by default; optional can_write for controlled automation.
Server/API Key Used by backend jobs and scripts for create/update workflows. Typically can_write; store server-side only.

Each key stores:

  • appId
  • appKey (secret)
  • capability flags (can_read, can_write)
  • optional label/expiry metadata

Sending credentials

SDK-style requests:

GET /api/deeplink?cid=abc123 HTTP/1.1
Host: li-nk.me
x-app-id: YOUR_APP_ID
x-api-key: YOUR_APP_KEY

Write/admin automation:

curl https://li-nk.me/api/links \
  -H 'Authorization: Bearer sk_live_...' \
  -H 'Content-Type: application/json' \
  -d '{"slug":"spring","ios_store_url":"https://apps.apple.com/..."}'

Rotation & security hygiene

  1. Name keys by environment and owner (for example prod-marketing-worker).
  2. Never ship write-scoped keys in mobile clients.
  3. Rotate keys by adding new, deploying, then revoking old.
  4. Audit key usage and remove idle credentials.

Common OAuth errors

The redirect_uri is not associated with this application

Your OAuth app callback URL does not exactly match what LinkMe sends.

Example for production root-domain auth:

  • auth page: https://li-nk.me/auth
  • callback: https://li-nk.me/api/auth/github/callback

Missing GH_OAUTH_CLIENT_ID/GH_OAUTH_CLIENT_SECRET

Deployment did not load GitHub OAuth secrets into the Portal env.

Verify secrets and deploy workflow env passthrough.

Related references