UseThatApp Documentation
Sell your web app from your own website — UseThatApp is the merchant of record. Put live prices and Buy buttons on your site; UseThatApp runs the hosted checkout, processes payment, calculates and remits tax, and handles refunds and chargebacks. The buyer lands back in your app with their purchase live — the license is created during checkout, no webhooks — and you get payouts via Stripe. Your app verifies each purchase with a license key — or lets UseThatApp run sign-in — through one SDK: usethatapp on PyPI and npm.
Reading this as an AI agent?
Every page on this site is fully pre-rendered static HTML — no JavaScript needed. For the fastest path, fetch docs.usethatapp.com/llms.txt (an index of all pages with summaries and integration rules) or docs.usethatapp.com/llms-full.txt (the entire site as one Markdown file — no crawling required). Page URLs are extensionless routes; the same list is in sitemap.xml.
One Merchant of Record, Two Ways to Verify
Merchant of record
The service everything else hangs off. Hosted buy links and a live pricing API; we take the payment, remit the tax, absorb refunds and chargebacks, and pay you via Stripe.
License keys
Verify purchases while keeping your own auth. Every purchase mints a key your server validates in one call — included in the per-sale fee, no login of ours involved.
Hosted sign-in
Or let us run login: buyers return from checkout already signed in, and the same session answers what they bought. An optional add-on, free for an introductory period.
The Loop
Everything in these docs serves one journey — a visitor on your website becoming a paying user of your app:
- Live prices on your site. Your pricing page renders from the Pricing API (
get_prices/getPrices, or plain fetch — it's public and CORS-enabled). Never hardcode a price. - Buy button → hosted checkout. Each price carries a ready-made
buy_url(or build one withpurchase_url/purchaseUrl). UseThatApp runs checkout as the merchant of record. - Back into your app. The license is created synchronously during checkout, so what they bought is live the moment they land — no webhooks, no polling.
- Verify, whichever way suits your app. Keeping your own accounts? The return carries a
uta_orderref you exchange for a license key, thenvalidate_license_key/validateLicenseKeyis your gate. Rather we ran login? Sign in with UseThatApp returns them signed in andget_entitlementanswers from that session. Either way, branch on the stableproduct_public_id. - Manage and upgrade. Deep-link "Manage subscription" with
manage_url/manageUrl; upsell with another purchase link.
Your app's marketplace listing on usethatapp.com is a complementary discovery channel — in external listing mode its card links straight out to your own site. Purchases are currently available to US buyers, with buy links enabled per app during the beta.
Quick Example
Live prices on your page, then gate what the buyer bought — shown here in Hosted sign-in mode (keys mode swaps the gate for validate_license_key, see License Keys). The usethatapp SDK (PyPI / npm) is a confidential, server-side client — it holds your client secret and never runs in the browser:
Python
from usethatapp import get_entitlement, get_prices, purchase_url
# Your pricing page — live prices, never hardcoded:
prices = get_prices() # AppPrices(..., prices=(Price(...), ...))
for p in prices.prices:
show_plan(p.product_name, p.amount, p.currency, p.buy_url)
# Your gate, Hosted sign-in mode (keys mode: validate_license_key):
ent = get_entitlement(session["uta_access_token"])
if ent.entitled and ent.product_public_id == "prod_<your-pro-id>":
... # serve paid content
else:
offer_upgrade(purchase_url("<prc-price-id>"))JavaScript
import { getEntitlement, getPrices, purchaseUrl } from "usethatapp";
// Your pricing page — live prices, never hardcoded:
const { prices } = await getPrices();
prices.forEach((p) =>
showPlan(p.product_name, p.amount, p.currency, p.buy_url));
// Your gate, Hosted sign-in mode (keys mode: validateLicenseKey):
const ent = await getEntitlement(req.session.utaAccessToken);
if (ent.entitled && ent.product_public_id === "prod_<your-pro-id>") {
// serve paid content
} else {
offerUpgrade(purchaseUrl("<prc-price-id>"));
}Hosted sign-in itself is two small routes (/login and /callback) — the Quick Start walks that whole loop end to end; keys mode skips both.
Supported Frameworks
Choose your language to see the full list of framework guides, or jump straight to the Quick Start.
