# Create Billing Portal Session

Source: https://recoupable.dev/docs/api-reference/accounts/portal-create

Create a Stripe Customer Portal session for an account. Returns a hosted URL where the customer can update the card on file, view invoices, or cancel a Starter or Pro subscription; the client should redirect the user to that URL. `id` may be the authenticated account or an organization the caller belongs to. Enterprise (invoiced) plans are managed with your Recoup contact and the app does not offer this portal for them, but the endpoint works for any account with a Stripe customer.

## POST /api/accounts/{id}/portal

Full OpenAPI specification: https://recoupable.dev/docs/spec/accounts.json

## Authentication

This operation requires one of the security alternatives in the specification below. Security scheme definitions are included where present in the published specification.

[Authentication guide](https://recoupable.dev/docs/authentication)

## Operation and referenced schemas

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Recoup API - Accounts",
    "description": "API documentation for the Recoup platform - an AI agent platform for the music industry",
    "license": {
      "name": "MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.recoupable.dev"
    }
  ],
  "paths": {
    "/api/accounts/{id}/portal": {
      "post": {
        "description": "Create a Stripe Customer Portal session for an account. Returns a hosted URL where the customer can update the card on file, view invoices, or cancel a Starter or Pro subscription; the client should redirect the user to that URL. `id` may be the authenticated account or an organization the caller belongs to. Enterprise (invoiced) plans are managed with your Recoup contact and the app does not offer this portal for them, but the endpoint works for any account with a Stripe customer.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The unique identifier (UUID) of the account. Must be the authenticated account or another accessible via organization membership.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "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 - invalid parameters, or the account has no Stripe customer yet",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionPortalErrorResponse"
                },
                "example": {
                  "error": "No active subscription found"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or missing authentication",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionPortalErrorResponse"
                },
                "example": {
                  "error": "Unauthorized"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - the account is not the caller's and not an organization they belong to (an unknown id also returns 403, never 404)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionPortalErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CreateSubscriptionPortalRequest": {
        "type": "object",
        "required": [
          "returnUrl"
        ],
        "description": "Request body for creating a billing portal session. The account is taken from the `id` path parameter and must be accessible to the authenticated caller.",
        "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"
          }
        }
      },
      "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"
          }
        }
      },
      "SubscriptionPortalErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message.",
            "example": "returnUrl is required"
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your Recoup API key. [Learn more](/quickstart#api-keys)."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}
```
