Billing Checkout
Mint a checkout for a tier and answer the URL the buyer opens.
A POST, not a GET: the route CREATES a checkout at the payment provider. A GET is prefetchable, so a link scanner would mint a real checkout each time a user points at the link. Every route that mints outbound is a POST (POST /me/billing/plan, POST /apps/{id}/exports).
Console-only, per-current-user: Bearer-authed like the /exports routes — the web server forwards the session token in the Authorization: Bearer header and current_token verifies it. The route then demands billing:write, which the console session mint alone grants, so an agent credential answers 403. The caller's id goes to the provider as the buyer hint, so the provider's webhook can bind the new subscription back to this account.
The route refuses a caller who already holds a granting subscription (409). A provider accepts a second subscription and charges the card twice, and the plan projection takes the highest granting tier, so the extra subscription stays invisible. xhostd owns subscription state, so the guard belongs here and not in the console.
The 409 is the one enforcement point on the PUBLIC surface, and it is no longer the only mint point. python -m xhostd.cli.admin mint-checkout (:mod:xhostd.cli.admin) mints the same checkout and skips exactly this guard, so an operator can hand a live subscriber a second checkout without a gap in their plan. That verb needs a shell on the edge box, so nothing a caller sends reaches it.
The route hands the provider no landing URL. The client took settings.platform_domain at construction (xhostd/__main__.py::_build_billing_client) and builds the apex checkout page from :mod:xhostd.billing itself, so a target from the console cannot become an open-redirect input.
Request
- Base URL: https://api.xhostd.com (the document declares no server; this is the origin it was published from)
- URL: https://api.xhostd.com/me/billing/checkout
- Auth: none declared
Headers
Request body
Response
Successful Response
Changes
No recorded changes to this operation across all 1 revision of this API.