---
title: "Confirm the first workspace and purchase"
method: POST
path: "/billing/welcome"
tags: ["Billing"]
---

# Confirm the first workspace and purchase

`POST /billing/welcome`

## Request

- Base URL: `https://app.openpo.st/api/v1`
- URL: `https://app.openpo.st/api/v1/billing/welcome`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `openpost_session`

Creates the signed-in Owner's first Workspace and one checkout attempt bound to the confirmed purchase choice. Exact retries resume the same attempt.

## Request body

- ConfirmFirstWorkspacePurchaseInputBody
  - `$schema` string, uri: A URL to the JSON Schema for this object.
  - `billing_period` 'monthly' | 'annual', required: Canonical billing period
  - `plan_id` string, required: Canonical hosted plan ID
  - `purchase_choice_token` string, required: Integrity-protected purchase choice carried through signup
  - `return_path` string: Validated same-origin route to resume after checkout
  - `workspace_name` string, required: Name for the first Workspace

## Response `200`

OK

- ConfirmFirstWorkspacePurchaseOutputBody
  - `$schema` string, uri: A URL to the JSON Schema for this object.
  - `checkout` BillingURLResponse, required
    - `$schema` string, uri: A URL to the JSON Schema for this object.
    - `billing_period` string: Selected billing period
    - `client_token` string: Browser-safe Paddle.js client token
    - `customer_email` string: Authenticated customer's checkout email
    - `environment` string: Explicit Paddle.js environment: sandbox or production
    - `id` string: OpenPost checkout attempt or Paddle portal session ID
    - `plan_id` string: OpenPost plan ID
    - `price_ids` object: Paddle price IDs for localized previews in the selected billing period
    - `provider_price_id` string: Paddle price ID for the selected plan and period
    - `purpose` string: Requested Paddle portal destination
    - `return_url` string: OpenPost URL used after Paddle checkout completes
    - `trial_ends_at` string: Expected end of the 14-day trial
    - `url` string: OpenPost checkout URL or short-lived Paddle customer portal URL
    - `used_generic_fallback` boolean: Whether Paddle omitted the purpose-specific link and OpenPost returned the generic portal
    - `workspace_id` string: Workspace bound to this checkout attempt
  - `organization_id` string, required
  - `workspace_id` string, required
  - `workspace_name` string, required

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `409`: Conflict
- `422`: Unprocessable Entity
- `500`: Internal Server Error
- `503`: Service Unavailable

---

[API](https://skmtc.dev/openpo/apis/openpost-api.md) · [All operations](https://skmtc.dev/openpo/apis/openpost-api/llms.txt) · [OpenAPI document](https://skmtc.dev/openpo/apis/openpost-api/revisions/67d3964458a7?raw)
