---
title: "Attach Org Billing"
method: POST
path: "/api/admin/orgs/{org_id}/billing/attach"
tags: ["admin"]
---

# Attach Org Billing

`POST /api/admin/orgs/{org_id}/billing/attach`

## Request

- Base URL: `https://app.ctlsurf.com` (the document declares no server; this is the origin it was published from)
- URL: `https://app.ctlsurf.com/api/admin/orgs/{org_id}/billing/attach`
- Auth: HTTP bearer

Attach seat billing to an existing organization.

Orgs are created by promote-business, which is deliberate: the billing
relationship is established afterwards rather than at signup. This is that
second step.

Two modes, because both are real:

- manual_only sets seats_purchased with no provider involved. Comped orgs,
  self-hosted deployments, and anyone invoiced outside Stripe live here, and
  they are a supported configuration rather than a broken one.
- Otherwise a Stripe customer and a quantity-N subscription are created. The
  subscription may come back `incomplete` when the customer has no payment
  method yet; that is expected, not a failure. The response carries the
  status so the operator knows to send the owner a payment link.

Never lowers seats below what is already assigned: doing so would put the
org over its own limit the instant billing was attached.

## Path parameters

- `org_id` string, required

## Request body

- AttachBillingRequest: Start an org's per-seat subscription, or set its seats manually.
  - `seats` integer, nullable
  - `manual_only` boolean
  - `comped` boolean

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/ctlsurf/apis/notebook-control-plane.md) · [All operations](https://skmtc.dev/ctlsurf/apis/notebook-control-plane/llms.txt) · [OpenAPI document](https://skmtc.dev/ctlsurf/apis/notebook-control-plane/revisions/ddfbbe20d5ce?raw)
