From 8cf19d7334a8d69140549b9172eba52a51fde076 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 4 May 2026 20:06:05 +0700 Subject: [PATCH 1/3] docs(openapi): add subscription portal creation endpoint - Added a new endpoint `/api/subscriptions/portal` for creating a subscription management session, allowing customers to manage their subscriptions. - Included detailed request and response schemas for `CreateSubscriptionPortalRequest` and `CreateSubscriptionPortalResponse`. - Updated documentation to include the new endpoint in the subscriptions section of the API reference. --- api-reference/openapi/accounts.json | 96 +++++++++++++++++++ api-reference/subscriptions/portal-create.mdx | 4 + docs.json | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 api-reference/subscriptions/portal-create.mdx diff --git a/api-reference/openapi/accounts.json b/api-reference/openapi/accounts.json index 67652285..16719a81 100644 --- a/api-reference/openapi/accounts.json +++ b/api-reference/openapi/accounts.json @@ -410,6 +410,62 @@ } } }, + "/api/subscriptions/portal": { + "post": { + "description": "Create a subscription management session for the authenticated account. Returns a hosted URL where the customer can update payment method, view invoices, or cancel. The client should redirect the user to that URL.", + "security": [ + { + "apiKeyAuth": [] + }, + { + "bearerAuth": [] + } + ], + "requestBody": { + "description": "Portal session parameters", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSubscriptionPortalRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Portal session created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSubscriptionPortalResponse" + } + } + } + }, + "400": { + "description": "Bad request - missing or invalid parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionSessionErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized - invalid or missing authentication", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionSessionErrorResponse" + } + } + } + } + } + } + }, "/api/workspaces": { "post": { "description": "Create a new workspace account. Workspaces can optionally be linked to an organization.", @@ -2848,6 +2904,46 @@ "example": "successUrl is required" } } + }, + "CreateSubscriptionPortalRequest": { + "type": "object", + "required": [ + "returnUrl" + ], + "properties": { + "returnUrl": { + "type": "string", + "format": "uri", + "description": "The URL to redirect to when the customer leaves the portal.", + "example": "https://chat.recoupable.com/settings/billing" + }, + "accountId": { + "type": "string", + "format": "uuid", + "description": "UUID of the account to open the portal for. Only applicable when the authenticated account has admin access to multiple accounts. If not provided, opens the portal for the API key's own account.", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + } + }, + "CreateSubscriptionPortalResponse": { + "type": "object", + "required": [ + "id", + "url" + ], + "properties": { + "id": { + "type": "string", + "description": "The portal session ID.", + "example": "portal_sess_a1b2c3d4" + }, + "url": { + "type": "string", + "format": "uri", + "description": "The hosted portal URL. Redirect to this URL so the customer can manage their subscription.", + "example": "https://billing.example.com/manage/portal_sess_a1b2c3d4" + } + } } } } diff --git a/api-reference/subscriptions/portal-create.mdx b/api-reference/subscriptions/portal-create.mdx new file mode 100644 index 00000000..2a2fa4e1 --- /dev/null +++ b/api-reference/subscriptions/portal-create.mdx @@ -0,0 +1,4 @@ +--- +title: 'Create Subscription Portal' +openapi: '/api-reference/openapi/accounts.json POST /api/subscriptions/portal' +--- diff --git a/docs.json b/docs.json index 0ea31374..2330ae98 100644 --- a/docs.json +++ b/docs.json @@ -319,7 +319,8 @@ { "group": "Subscriptions", "pages": [ - "api-reference/subscriptions/sessions-create" + "api-reference/subscriptions/sessions-create", + "api-reference/subscriptions/portal-create" ] }, { From 68faa55aac98fd5b1eeb220e9eafe87d960aa230 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 4 May 2026 20:14:29 +0700 Subject: [PATCH 2/3] fix(openapi): update SubscriptionSessionErrorResponse references to SubscriptionPortalErrorResponse - Changed references in the OpenAPI documentation from `SubscriptionSessionErrorResponse` to `SubscriptionPortalErrorResponse` for clarity. - Added the `SubscriptionPortalErrorResponse` schema to define the error structure for subscription portal operations. --- api-reference/openapi/accounts.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/api-reference/openapi/accounts.json b/api-reference/openapi/accounts.json index 16719a81..311b750c 100644 --- a/api-reference/openapi/accounts.json +++ b/api-reference/openapi/accounts.json @@ -448,7 +448,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscriptionSessionErrorResponse" + "$ref": "#/components/schemas/SubscriptionPortalErrorResponse" } } } @@ -458,7 +458,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscriptionSessionErrorResponse" + "$ref": "#/components/schemas/SubscriptionPortalErrorResponse" } } } @@ -2905,6 +2905,19 @@ } } }, + "SubscriptionPortalErrorResponse": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string", + "description": "Human-readable error message.", + "example": "returnUrl is required" + } + } + }, "CreateSubscriptionPortalRequest": { "type": "object", "required": [ From 1051b36978e9cbfa26f8b20da0f0460e1740364c Mon Sep 17 00:00:00 2001 From: john Date: Mon, 4 May 2026 22:46:23 +0700 Subject: [PATCH 3/3] docs(openapi): update billing portal session request schema - Added a description for the request body used to create a billing portal session, clarifying that the account is determined from authentication rather than the payload. - Removed the `accountId` property from the request schema, simplifying the structure for users without admin access to multiple accounts. --- api-reference/openapi/accounts.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/api-reference/openapi/accounts.json b/api-reference/openapi/accounts.json index 311b750c..23d53cdf 100644 --- a/api-reference/openapi/accounts.json +++ b/api-reference/openapi/accounts.json @@ -2923,18 +2923,13 @@ "required": [ "returnUrl" ], + "description": "Request body for creating a billing portal session. The account is determined from authentication (API key or session), not from this payload.", "properties": { "returnUrl": { "type": "string", "format": "uri", "description": "The URL to redirect to when the customer leaves the portal.", "example": "https://chat.recoupable.com/settings/billing" - }, - "accountId": { - "type": "string", - "format": "uuid", - "description": "UUID of the account to open the portal for. Only applicable when the authenticated account has admin access to multiple accounts. If not provided, opens the portal for the API key's own account.", - "example": "123e4567-e89b-12d3-a456-426614174000" } } },