Documentation
Give your AI editor everything it needs to build with Dream API.
Build with AI
Copy this prompt into Claude Code, Cursor, Windsurf, or any AI coding assistant. It contains the complete SDK reference - everything the AI needs to help you build.
What the AI Gets
I'm building with Dream API SDK. Here's the complete reference:
## Installation
npm install @dream-api/sdk
## Setup
import { DreamAPI } from '@dream-api/sdk';
const api = new DreamAPI({ publishableKey: 'pk_xxx' });
## CRITICAL: Sign-Up vs Sign-In
// Sign-Up MUST use getSignUpUrl() - sets user metadata (plan, publishableKey)
<a href={api.auth.getSignUpUrl({ redirect: '/choose-plan' })}>Sign Up</a>
// Sign-In for returning users
<a href={api.auth.getSignInUrl({ redirect: '/dashboard' })}>Sign In</a>
// Account settings (profile, password, security)
<a href={api.auth.getCustomerPortalUrl({ returnUrl: '/dashboard' })}>Account</a>
// Billing portal (payment methods, invoices, cancel)
<button onClick={async () => {
const { url } = await api.billing.openPortal({ returnUrl: '/dashboard' });
window.location.href = url;
}}>Manage Billing</button>
## CRITICAL: After Checkout - Use getRefreshUrl()
// Stripe webhook takes 1-3s to update user's plan. Use getRefreshUrl() to handle this:
const refreshUrl = api.auth.getRefreshUrl({ redirect: '/dashboard' });
const { url } = await api.billing.createCheckout({
tier: 'pro',
successUrl: refreshUrl, // Polls until plan updates, then redirects with fresh JWT
cancelUrl: window.location.origin + '/pricing',
});
## Membership (Content Gating)
// No usage.track() needed - just check plan
const hasPaidAccess = user?.plan !== 'free';
{hasPaidAccess ? <PremiumContent /> : <UpgradePrompt />}
// Single tier + trial days = pseudo free tier (configure in dashboard, no code)
// Unlimited API requests - no metering needed for memberships
## Minimal Complete Example
function App() {
const [isReady, setIsReady] = useState(false);
const [user, setUser] = useState(null);
useEffect(() => {
api.auth.init().then(() => {
setUser(api.auth.getUser());
setIsReady(true);
});
}, []);
if (!isReady) return <p>Loading...</p>;
if (!user) return (
<a href={api.auth.getSignUpUrl({ redirect: '/choose-plan' })}>Get Started</a>
);
return (
<div>
<p>Plan: {user.plan}</p>
<button onClick={() => api.usage.track()}>Use Feature</button>
<button onClick={() => api.auth.signOut()}>Sign Out</button>
</div>
);
}
## Upgrade Flow
const handleUpgrade = async () => {
// Use getRefreshUrl() - it polls until Stripe webhook updates the plan
const refreshUrl = api.auth.getRefreshUrl({ redirect: '/dashboard' });
const { url } = await api.billing.createCheckout({
tier: 'pro',
successUrl: refreshUrl,
cancelUrl: window.location.origin + '/pricing',
});
window.location.href = url;
};
## SaaS Methods
api.auth.init() // Call once on load, client-side only
api.auth.getSignUpUrl({ redirect: '/choose-plan' }) // URL for NEW users
api.auth.getSignInUrl({ redirect: '/dashboard' }) // URL for RETURNING users
api.auth.getRefreshUrl({ redirect: '/dashboard' }) // After checkout - polls for plan update
api.auth.getCustomerPortalUrl({ returnUrl: '/' }) // Account settings
api.auth.isSignedIn() // boolean
api.auth.getUser() // { id, email, plan } or null
api.auth.signOut() // Signs out user
api.usage.track() // { success, usage: { usageCount, limit, remaining } }
api.usage.check() // Read usage without incrementing
api.billing.createCheckout({ tier, successUrl, cancelUrl }) // { url }
api.billing.openPortal({ returnUrl }) // { url } for billing management
api.products.listTiers() // { tiers } for pricing page
## Store Methods
api.products.list() // { products } with price, imageUrl, soldOut
api.products.cartCheckout({ items, successUrl, cancelUrl }) // { url }, items = [{ priceId, quantity }]
## Environment Variables
VITE_DREAM_PUBLISHABLE_KEY=pk_xxx (Vite/React)
NEXT_PUBLIC_DREAM_PUBLISHABLE_KEY=pk_xxx (Next.js)
## Key Rules
- Publishable key is safe for frontend (like Stripe)
- auth.init() is CLIENT-SIDE ONLY - call in useEffect
- For Next.js: use 'use client' directive on auth components
- features is an ARRAY - use .map() not .split()
- price is in CENTS - divide by 100: ${(price / 100).toFixed(2)}
- Dashboard controls tiers, prices, trial days - change there, app updates automatically
## Starter Templates (Recommended)
git clone https://github.com/Fruitloop24/dream-saas-basic # SaaS with usage
git clone https://github.com/Fruitloop24/dream-membership-basic # Content gating
git clone https://github.com/Fruitloop24/dream-store-basic # E-commerce
# Also available: dream-saas-next, dream-membership-next, dream-store-next
Help me build my app using this SDK.How to Use
- 1Copy the prompt above
- 2Paste into your AI editor (Claude Code, Cursor, Windsurf)
- 3Ask it to build - "Add a pricing page" or "Set up auth"
Start Faster with Templates
Templates come with AI commands in .claude/commands/ folder. Open in any AI editor and run /setup.
