Rewardly Docs
Guides

OAuth marketplace integration

Connect a merchant's Rewardli account to an approved marketplace application.

Rewardli supports OAuth 2.1 Authorization Code flow with PKCE for approved, server-side marketplace applications. A merchant signs in to Rewardli, chooses the account to connect, reviews the requested permissions, and approves access.

Access and refresh tokens must remain on your server. Rewardli never sends them through the browser redirect.

Register your application

Rewardli platform administrators register applications and provide:

  • a client_id
  • a client_secret, shown once
  • one or more exact HTTPS redirect URIs
  • the scopes your application may request

Store the client secret in a server-side secret manager. Never place it in browser JavaScript, a mobile application, source control, or logs.

Authorization-server metadata is available from:

https://api.rewardli.dev/.well-known/oauth-authorization-server

Start authorization

Generate a fresh PKCE verifier, S256 challenge, and state value for every installation:

import { createHash, randomBytes } from "node:crypto";

const verifier = randomBytes(48).toString("base64url");
const challenge = createHash("sha256").update(verifier).digest("base64url");
const state = randomBytes(24).toString("base64url");

// Store verifier + state in the user's installation session.

Redirect the browser to:

https://app.rewardli.dev/oauth/authorize
  ?response_type=code
  &client_id=roc_...
  &redirect_uri=https%3A%2F%2Fpartner.example.com%2Foauth%2Frewardli%2Fcallback
  &scope=account%3Aread%20catalog%3Aread%20rewards%3Awrite%20wallet%3Aread
  &state=...
  &code_challenge=...
  &code_challenge_method=S256

Rewardli requires an exact registered redirect_uri. After approval, the browser returns to your callback with a five-minute, single-use code:

https://partner.example.com/oauth/rewardli/callback?code=rac_...&state=...

Verify state with a constant-time comparison before exchanging the code. If the user declines, the callback receives error=access_denied and the original state.

Exchange the code

From your server, authenticate the client and exchange the code:

curl -X POST https://api.rewardli.dev/oauth/token \
  -u "$REWARDLI_CLIENT_ID:$REWARDLI_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "redirect_uri=https://partner.example.com/oauth/rewardli/callback" \
  --data-urlencode "code_verifier=$PKCE_VERIFIER"

The response contains an opaque one-hour access token and a rotating 30-day refresh token:

{
  "access_token": "rat_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rrt_...",
  "scope": "account:read catalog:read rewards:write wallet:read"
}

Use the access token with the existing /v1 API:

curl https://api.rewardli.dev/v1/catalog \
  -H "Authorization: Bearer $REWARDLI_ACCESS_TOKEN"

Refresh access

Refresh tokens rotate on every use. Replace the stored refresh token atomically with the new value; never reuse an old one:

curl -X POST https://api.rewardli.dev/oauth/token \
  -u "$REWARDLI_CLIENT_ID:$REWARDLI_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "refresh_token=$REWARDLI_REFRESH_TOKEN"

Reusing a consumed refresh token is treated as credential theft and revokes the entire token family. Prompt the merchant to reconnect.

Revoke tokens

When a merchant uninstalls your plugin, revoke its refresh token:

curl -X POST https://api.rewardli.dev/oauth/revoke \
  -u "$REWARDLI_CLIENT_ID:$REWARDLI_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "token=$REWARDLI_REFRESH_TOKEN"

Merchants can also revoke the complete connection under Settings → Connected apps.

Scopes

ScopeAccess
account:readMerchant profile and overview
catalog:readGift-card catalog
rewards:readReward records and delivery status
rewards:writeCreate, resend, cancel, and inspect rewards
wallet:readWallet balances and transactions
webhooks:readWebhook endpoints and deliveries
webhooks:writeCreate, update, test, and remove webhooks

Request only the scopes required by your plugin. OAuth tokens cannot fund wallets, change merchant branding/catalog rules, manage team members, or create other credentials.

On this page