MemorySyncMemorySync
Integrations

OAuth Apps

OAuth Apps allow third-party applications to access MemorySync on behalf of your users. Register a client, implement the authorization code flow with PKCE, and exchange codes for tokens — all through standard OAuth 2.0 endpoints.

What is an OAuth app

An OAuth app is a registered client that can request permission to act on behalf of a MemorySync user. When a user authorizes your app, MemorySync issues an access token scoped to the permissions (scopes) the user approved.

  • Apps are managed under /org/oauth/* in the dashboard.
  • Each app gets a client_id and (for confidential clients) a client_secret.
  • Redirect URIs must be pre-registered. The backend validates every redirect before issuing a code.

Client types

TypeDescription
ConfidentialServer-side apps that can securely store a client_secret. Can use both authorization code and client credentials grants.
PublicBrowser-based or mobile apps that cannot keep a secret. Must use PKCE (S256 only). Cannot use client credentials grant.

Authorization code flow with PKCE

  1. 1Generate a code_verifier (43–128 chars) and derive code_challenge = BASE64URL(SHA256(code_verifier)).
  2. 2Redirect the user to GET /oauth/authorize with response_type=code, client_id, redirect_uri, state, scope, code_challenge, and code_challenge_method=S256.
  3. 3MemorySync validates the client, redirect URI, and PKCE parameters. The pending request is cached server-side with a 600-second TTL.
  4. 4The user sees the consent screen. On approval, MemorySync redirects back to your redirect_uri with code and state.
  5. 5Exchange the code at POST /oauth/token with grant_type=authorization_code, code, redirect_uri, client_id, and code_verifier.

Client credentials grant

For server-to-server access without a user context, confidential clients can use the client credentials grant:

HTTP
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=memories:read memories:write

The response includes an access_token scoped to the organization that owns the OAuth app. Public clients cannot use this grant.

Token lifecycle

Token typeBehavior
Access tokenShort-lived. Include in requests as Authorization: Bearer <token>.
Refresh tokenLonger-lived. Use POST /oauth/token with grant_type=refresh_token to obtain a new access token. The old refresh token is rotated — store the new one.
Authorization codeSingle-use and short-lived. Must be exchanged within seconds of issuance.

Scopes reference

Scopes control what an OAuth token can access. Request only the scopes your application needs:

ScopeAccess granted
memories:readQuery and retrieve memories.
memories:writeAdd, update, and delete memories.
integrations:readView integration connections and sync status.
integrations:writeCreate, update, and manage integration connections.

Security best practices

  • Always use PKCE — Public clients must use PKCE. Confidential clients should also use it for defense-in-depth. Only S256 is accepted.
  • Validate state — Always include a random state parameter and verify it matches when the user returns. This prevents CSRF attacks.
  • Register exact redirect URIs — The backend rejects any redirect_uri not exactly matching a pre-registered URI. No wildcards allowed.
  • Store refresh tokens securely — Refresh tokens are rotated on every use. If you lose a refresh token, the user must re-authorize.
  • Use minimum scopes — Request only the scopes your app actually needs. The consent screen shows each scope to the user.
  • Unknown clients are rejected safely — If the client_id is invalid, the backend returns an error directly without redirecting, preventing open-redirect attacks.