Skip to content

Quickstart

This quickstart gets one billing config into test and checks one entitlement from application code.

You do not need to understand every Stripe object first. The first pass is:

  1. Write billing.config.ts.
  2. Push it to test.
  3. Put a test API key in your app.
  4. Check an entitlement for a customer ID.
Terminal window
npm install @guapocado/sdk
npm install --save-dev @guapocado/cli

The SDK is what your app imports. The CLI is what reads and pushes billing.config.ts.

Terminal window
npx guap init

You can also create the file manually:

import { defineBilling } from "@guapocado/sdk";
export default defineBilling({
entitlements: {
"advanced-analytics": { type: "feature" },
"api-calls": { type: "meter", reset: "monthly" },
seats: { type: "limit" },
},
products: [
{
key: "free",
name: "Free",
entitlements: {
"advanced-analytics": false,
"api-calls": { included: 1000 },
seats: { included: 1 },
},
},
{
key: "pro",
name: "Pro",
pricing: {
mode: "recurring",
type: "flat",
amount: 4900,
currency: "usd",
frequency: "month",
},
entitlements: {
"advanced-analytics": true,
"api-calls": { included: 100000 },
seats: { included: 10 },
},
},
],
});

This says:

  • advanced-analytics is a yes/no feature.
  • api-calls is monthly usage Guapocado can consume.
  • seats is a numeric allowance your app enforces against its own users table.
  • free is an unpriced product.
  • pro is a monthly subscription product.
Terminal window
npx guap login

One login authorizes both modes. Test is where you test config, keys, checkout, and webhooks without touching live billing.

End-user apps call the same hosted API origin in both modes:

https://api.guapocado.dev

The key decides whether the request is test or live.

Preview what will change:

Terminal window
npx guap plan --test

Push when the plan looks right:

Terminal window
npx guap push --test

This syncs the config into Guapocado. If your test environment has Stripe connected, Guapocado can also sync Stripe products and prices from the product definitions.

Use a server key for backend code:

Terminal window
GUAPOCADO_API_KEY=sk_guap_test_...

Server keys can create customers, start checkout, consume usage, change subscriptions, and read entitlements.

Client keys start with ck_guap_ and are only for browser-safe reads. Do not put a server key in React client code.

import { createGuapocadoClient } from "@guapocado/sdk";
const guap = createGuapocadoClient({
apiKey: process.env.GUAPOCADO_API_KEY!,
customerId: "org_123",
});
const allowed = await guap.has("advanced-analytics");
if (!allowed) {
throw new Response("Upgrade required", { status: 403 });
}

customerId is your app’s stable billing identity. It can be a user ID, organization ID, team ID, workspace ID, account ID, or project ID.

await guap.usage.consume("api-calls", 1);

This records usage against the current customer. If the customer has no balance and overage is not enabled, the call fails instead of silently letting the app perform billable work.

const session = await guap.checkout.create({
productKey: "pro",
successUrl: "https://app.example.com/billing/success",
cancelUrl: "https://app.example.com/billing",
});
return Response.redirect(session.url);

The same API works for recurring subscription products and one-time products.

Read Billing Primitives before wiring more code. Most integration mistakes come from modeling everything as the wrong primitive.

Then choose a framework guide: