UseThatApp Logo

    REST API

    The raw HTTP surface behind the whole UseThatApp offering — selling from your own website with UseThatApp as merchant of record (public app-profile and pricing endpoints feeding hosted buy links), licensing (the Bearer-authed entitlement endpoint and the client-credentialed license key endpoints), and authentication ("Sign in with UseThatApp" over OIDC). If you run Python or JavaScript, the usethatapp SDK wraps all of it; this page is for every other stack — and for calling the public endpoints straight from a browser.

    Conventions

    • Base URL: https://www.usethatapp.com
    • Format: JSON requests and responses.
    • Versioning: the REST API lives under /api/v1/. The OIDC endpoints (under /o/) and the canonical entitlement path (/licensing/entitlement/) are frozen, unversioned surfaces the SDKs pin.
    • Live schema: an OpenAPI 3 schema at /api/v1/schema/ and Swagger UI at /api/v1/docs/.

    Authentication models

    SurfaceAuth
    /api/v1/public/…None — anonymous, CORS-enabled (Access-Control-Allow-Origin: *), cacheable public reads.
    /api/v1/entitlement/OAuth 2.0 Bearer access token with the entitlements scope, obtained via the OIDC login flow. Requires the Hosted sign-in add-on (otherwise 403 service_not_enabled).
    /api/v1/licenses/…, /api/v1/orders/…HTTP Basic with your app's OAuth client id and secret — server-to-server, no end-user token. Included in the base per-sale fee.

    Public endpoints

    Two anonymous read endpoints power selling from your own website — app profile and live prices, addressed by your app's public OAuth client_id. Full field-by-field reference with example responses: Pricing API.

    public endpoints
    GET /api/v1/public/apps/{client_id}/          → app profile (name, tagline, listing_mode, url, marketplace_url)
    GET /api/v1/public/apps/{client_id}/prices/   → live prices, each with a ready-made buy_url

    Both only resolve for published apps with external sales enabled (404 otherwise) and send Cache-Control: public, max-age=60.

    Entitlement endpoint

    The live source of truth for a user's plan in your app. Two paths, identical behavior:

    • GET /licensing/entitlement/ — the canonical path, which the SDKs call.
    • GET /api/v1/entitlement/ — an alias mounted so the v1 API surface is complete. Behaves identically.

    Send the OAuth access token from the login flow as a Bearer token. The token must carry the entitlements scope (part of the default openid entitlements scopes).

    request
    curl -H "Authorization: Bearer <access-token>" \
      https://www.usethatapp.com/api/v1/entitlement/
    response — 200
    {
      "entitled": true,
      "version": "Pro",
      "product_id": "6f0e8f9a-2b1c-4d5e-8f7a-9b0c1d2e3f4a",
      "product_public_id": "prod_9XkKe2QGxN4Ttz1Rw7Ya",
      "status": "active",
      "is_free": false,
      "period_end": "2026-08-27"
    }
    FieldMeaning
    entitledTrue if the user may use the app (an active license, or a free tier).
    versionPlan display name (e.g. "Pro"). Mutable — for display only.
    product_public_idOpaque product identifier (prod_…). Gate features on this. Matches product_id in the Pricing API, and is kept permanently.
    product_idEqual-valued alias of product_public_id — both carry the same prod_… value. Gate on either.
    statusactive, trialing, one_time_active, free, preview, or none.
    is_freeWhether the entitlement is the app's free tier.
    period_endISO date the current period ends, or null.

    Errors

    StatusBodyMeaning
    401{"error": "invalid_token"}Missing, expired, or revoked token (a confirmed logout lands here). Refresh, or send the user back through login.
    403{"error": "insufficient_scope", "scope": "entitlements"}A valid token that lacks the entitlements scope.
    400{"error": "Client is not linked to an app"}The OAuth client isn't linked to an app — a configuration problem, not a user problem.

    The SDKs map 401 to UtaTokenError and 403 to UtaPermissionError — see Error Handling. For what the fields mean for feature gating, see Licensing.

    License key endpoints

    Server-to-server verification for apps that keep their own authentication. All three take HTTP Basic client credentials; none involves an end-user token. Field meanings, statuses, and the integration walkthrough are on License Keys.

    license key endpoints
    POST /api/v1/licenses/validate                      → {entitled, status, license_id,
                                                             product_id, product_public_id,
                                                             period_end, canceled_at}
         body: {"key": "key_…"}                          120/min per client
    
    GET  /api/v1/orders/<ref>                           → the same fields + license_key
                                                           202 {"status":"processing"} if the
                                                           license has not landed yet
                                                           120/min per client
    
    POST /api/v1/licenses/<license_id>/regenerate-key   → the same fields + license_key,
                                                           rotated_at. Old key dies at once.
                                                           30/min per client

    Errors: 401 invalid_client (bad credentials), 404 unknown_key / unknown_order / unknown_license (never issued, or belonging to another app — the endpoints are not cross-app oracles), and 409 license_canceled on rotation of a dead license. A key whose license was canceled or refunded is not "unknown": it validates with status: "canceled".

    OIDC / OAuth endpoints

    UseThatApp is a standard OpenID Provider. Rather than hardcoding endpoint paths, fetch the discovery document — it enumerates the authorization, token, userinfo, JWKS, and end-session endpoints, plus supported scopes and signing algorithms:

    discovery
    GET https://www.usethatapp.com/o/.well-known/openid-configuration
    • authorization_endpoint — start the authorization-code + PKCE flow.
    • token_endpoint — exchange the code for tokens (confidential client: send your client secret).
    • userinfo_endpoint — the pairwise pseudonymous sub claim (no PII — see Authentication).
    • jwks_uri — public keys for validating ID tokens.
    • end_session_endpoint — RP-initiated logout.

    If you're integrating by hand on a stack without an SDK, any certified OIDC client library pointed at this issuer (https://www.usethatapp.com/o) will do the protocol work.

    Rate limits

    SurfaceLimit
    Entitlement endpoint60 requests/minute per token
    Public API (/api/v1/public/…)120 requests/minute per IP

    Machine-readable schema

    The versioned API is described by a live OpenAPI 3 schema at https://www.usethatapp.com/api/v1/schema/ with interactive Swagger UI at https://www.usethatapp.com/api/v1/docs/. AI agents can also use llms.txt and the MCP server.

    AI agents: this site is fully pre-rendered — fetch /llms.txt for an indexed summary of every page, or /llms-full.txt for the whole documentation as one Markdown file.