Wispr AI Cost Centers API
The Cost Centers API from Wispr AI — 4 operation(s) for cost centers.
The Cost Centers API from Wispr AI — 4 operation(s) for cost centers.
openapi: 3.0.3
info:
title: Wispr Backend Analytics Cost Centers API
description: Wispr Backend API
version: 0.5.2
tags:
- name: Cost Centers
paths:
/api/v1/enterprise/{enterprise_id}/cost-centers:
post:
tags:
- Cost Centers
summary: Create Cost Center
description: 'Create a new cost center for an enterprise (break-away intent step).
The cost center is named after the caller''s current team. The team
is not moved into the new CC until the Stripe checkout webhook fires.
The caller must be an enterprise admin.'
operationId: create_cost_center
security:
- ApiKeyHeaderPatched: []
parameters:
- name: enterprise_id
in: path
required: true
schema:
type: string
format: uuid
title: Enterprise Id
responses:
'201':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CostCenterDetailResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
get:
tags:
- Cost Centers
summary: List Cost Centers
description: 'List all cost centers for an enterprise.
The caller must be an enterprise admin. Each entry includes a computed
``team_count`` fetched via a single GROUP BY query.'
operationId: list_cost_centers
security:
- ApiKeyHeaderPatched: []
parameters:
- name: enterprise_id
in: path
required: true
schema:
type: string
format: uuid
title: Enterprise Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CostCenterListResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/v1/cost-centers/{cost_center_id}:
get:
tags:
- Cost Centers
summary: Get Cost Center
description: 'Get a single cost center by id.
The caller must be an admin of the enterprise that owns this cost center.'
operationId: get_cost_center
security:
- ApiKeyHeaderPatched: []
parameters:
- name: cost_center_id
in: path
required: true
schema:
type: string
format: uuid
title: Cost Center Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CostCenterDetailResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
patch:
tags:
- Cost Centers
summary: Update Cost Center
description: 'Rename a cost center.
Caller must be an enterprise admin or the cost center''s billing owner.'
operationId: update_cost_center
security:
- ApiKeyHeaderPatched: []
parameters:
- name: cost_center_id
in: path
required: true
schema:
type: string
format: uuid
title: Cost Center Id
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateCostCenterRequest'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CostCenterDetailResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
delete:
tags:
- Cost Centers
summary: Delete Cost Center
description: 'Delete a cost center.
Refuses if the cost center has an active Stripe subscription or teams
still referencing it. The caller must be an enterprise admin.'
operationId: delete_cost_center
security:
- ApiKeyHeaderPatched: []
parameters:
- name: cost_center_id
in: path
required: true
schema:
type: string
format: uuid
title: Cost Center Id
responses:
'204':
description: Successful Response
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/v1/cost-centers/{cost_center_id}/break-away-preview:
get:
tags:
- Cost Centers
summary: Get Break Away Preview
description: 'Return the pre-checkout summary for an in-flight break-away.
Called after ``create_cost_center`` and before ``create_cost_center_billing``
to surface team name, source cost center, member counts, and the per-seat
price math so the admin can confirm before being redirected to Stripe.
Caller must be an enterprise admin of the owning enterprise or the new CC''s
``billing_owner_user_id``.'
operationId: get_break_away_preview
security:
- ApiKeyHeaderPatched: []
parameters:
- name: cost_center_id
in: path
required: true
schema:
type: string
format: uuid
title: Cost Center Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/BreakAwayPreview'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/v1/cost-centers/{cost_center_id}/billing:
post:
tags:
- Cost Centers
summary: Create Cost Center Billing
description: 'Create a Stripe checkout session for a cost center in break-away intent state.
The new cost center inherits the parent enterprise''s negotiated price —
callers do not pick a plan. The team that will move is inferred from the
caller''s current active membership (no team_id in the request body).'
operationId: create_cost_center_billing
security:
- ApiKeyHeaderPatched: []
parameters:
- name: cost_center_id
in: path
required: true
schema:
type: string
format: uuid
title: Cost Center Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutUrlResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
CostCenterListResponse:
properties:
cost_centers:
items:
$ref: '#/components/schemas/CostCenterResponse'
type: array
title: Cost Centers
type: object
required:
- cost_centers
title: CostCenterListResponse
description: A list of cost centers for an enterprise.
CostCenterDetailResponse:
properties:
id:
type: string
format: uuid
title: Id
enterprise_id:
type: string
format: uuid
title: Enterprise Id
name:
type: string
title: Name
status:
type: string
title: Status
billing_owner_user_id:
anyOf:
- type: string
- type: 'null'
title: Billing Owner User Id
num_seats:
anyOf:
- type: integer
- type: 'null'
title: Num Seats
plan_ends_at:
anyOf:
- type: integer
- type: 'null'
title: Plan Ends At
cancel_at_period_end:
anyOf:
- type: boolean
- type: 'null'
title: Cancel At Period End
created_at:
type: string
format: date-time
title: Created At
team_count:
type: integer
title: Team Count
default: 0
stripe_customer_id:
anyOf:
- type: string
- type: 'null'
title: Stripe Customer Id
stripe_subscription_id:
anyOf:
- type: string
- type: 'null'
title: Stripe Subscription Id
seats_current_cycle:
anyOf:
- type: integer
- type: 'null'
title: Seats Current Cycle
past_due_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Past Due At
pilot_end:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Pilot End
cancel_at:
anyOf:
- type: integer
- type: 'null'
title: Cancel At
type: object
required:
- id
- enterprise_id
- name
- status
- billing_owner_user_id
- num_seats
- plan_ends_at
- cancel_at_period_end
- created_at
- stripe_customer_id
- stripe_subscription_id
- seats_current_cycle
- past_due_at
- pilot_end
- cancel_at
title: CostCenterDetailResponse
description: A cost center with additional Stripe and billing-cycle detail.
CheckoutUrlResponse:
properties:
url:
type: string
title: Url
type: object
required:
- url
title: CheckoutUrlResponse
description: A Stripe checkout URL for the client to redirect to.
UpdateCostCenterRequest:
properties:
name:
type: string
maxLength: 120
minLength: 1
title: Name
type: object
required:
- name
title: UpdateCostCenterRequest
description: Request to rename a cost center.
CostCenterResponse:
properties:
id:
type: string
format: uuid
title: Id
enterprise_id:
type: string
format: uuid
title: Enterprise Id
name:
type: string
title: Name
status:
type: string
title: Status
billing_owner_user_id:
anyOf:
- type: string
- type: 'null'
title: Billing Owner User Id
num_seats:
anyOf:
- type: integer
- type: 'null'
title: Num Seats
plan_ends_at:
anyOf:
- type: integer
- type: 'null'
title: Plan Ends At
cancel_at_period_end:
anyOf:
- type: boolean
- type: 'null'
title: Cancel At Period End
created_at:
type: string
format: date-time
title: Created At
team_count:
type: integer
title: Team Count
default: 0
type: object
required:
- id
- enterprise_id
- name
- status
- billing_owner_user_id
- num_seats
- plan_ends_at
- cancel_at_period_end
- created_at
title: CostCenterResponse
description: A cost center's core billing and membership fields.
BreakAwayPreview:
properties:
team_name:
type: string
title: Team Name
source_cost_center_name:
type: string
title: Source Cost Center Name
members_moving:
type: integer
title: Members Moving
per_seat_amount_cents:
anyOf:
- type: integer
- type: 'null'
title: Per Seat Amount Cents
currency:
type: string
title: Currency
billing_interval:
anyOf:
- type: string
enum:
- month
- year
- type: 'null'
title: Billing Interval
new_cc_annual_amount_cents:
anyOf:
- type: integer
- type: 'null'
title: New Cc Annual Amount Cents
pricing_unavailable_reason:
anyOf:
- type: string
enum:
- tiered_pricing_not_supported
- unexpected_stripe_shape
- type: 'null'
title: Pricing Unavailable Reason
type: object
required:
- team_name
- source_cost_center_name
- members_moving
- per_seat_amount_cents
- currency
- billing_interval
- new_cc_annual_amount_cents
title: BreakAwayPreview
description: 'Pre-checkout summary shown to admins initiating a break-away.
All amounts are integer cents in the source CC''s currency. ``billing_interval``
is the underlying Stripe price interval; the annual amount is always
pre-multiplied so the frontend never has to apply ``× 12`` itself.
Pricing fields are nullable so the preview can still surface team / member
counts even when Stripe''s price shape is incompatible with flat per-seat
math (e.g. ``billing_scheme=tiered`` on most negotiated enterprise contracts).
``pricing_unavailable_reason`` is populated whenever any pricing field is
null so the frontend can show a precise explanation instead of a generic
"try again" fallback.'
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
input:
title: Input
ctx:
type: object
title: Context
type: object
required:
- loc
- msg
- type
title: ValidationError
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
securitySchemes:
ApiKeyHeaderPatched:
type: apiKey
in: header
name: Authorization
APIKeyHeader:
type: apiKey
in: header
name: X-API-Key