---
title: "Create Customer Contract Developer"
method: POST
path: "/billing/developer/contracts/{customer_id}"
tags: ["Billing", "billing"]
---

# Create Customer Contract Developer

`POST /billing/developer/contracts/{customer_id}`

## Request

- Base URL: `https://api.openintake.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.openintake.ai/billing/developer/contracts/{customer_id}`
- Auth: none declared

Create a new billing contract for a customer (developer only).

## Path parameters

- `customer_id` string, uuid, required

## Request body

- CreateBillingContractRequest: Request to create or update billing contract (admin only).
  - `start_date` string, date-time, nullable: Omit only when billing_start_pending is set
  - `number_of_months` integer, nullable: Contract length in months; omit for a month-to-month contract
  - `billing_start_pending` boolean: Hold billing until the customer starts taking real calls; requires no start_date
  - `items` CreateBillingContractItemRequest[], required: Contract line items
    - `item_type` 'base_rate' | 'outbound_call_over_quota' | 'monthly_minimum' | 'per_call_rate', required: Billing contract item types.
    - `price` union, required: Price in dollars
      - number
      - string
    - `quota` integer, nullable: Quota (e.g., number of included calls)
    - `min_call_duration_seconds` integer, nullable: Per-call rate only: calls shorter than this many seconds are not billed
    - `count_voicemails` boolean, nullable: Per-call rate only: whether outbound calls that hit voicemail are billed

## Response `201`

Successful Response

- BillingContractResponse: Response with billing contract details.
  - `billing_contract_id` string, uuid, required
  - `customer_id` string, uuid, required
  - `start_date` string, date-time, nullable: NULL while billing_start_pending — billing has not started
  - `number_of_months` integer, nullable: NULL means month-to-month: no fixed term
  - `billing_start_pending` boolean: Billing is on hold until the customer starts taking real calls; nothing is billed
  - `items` BillingContractItemResponse[], required
    - `billing_contract_item_id` string, uuid, required
    - `billing_contract_id` string, uuid, required
    - `item_type` 'base_rate' | 'outbound_call_over_quota' | 'monthly_minimum' | 'per_call_rate', required: Billing contract item types.
    - `price` string, required
    - `quota` integer, nullable
    - `min_call_duration_seconds` integer, nullable
    - `count_voicemails` boolean, nullable
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `end_date` string, date-time, nullable: Computed: start_date + number_of_months; NULL when month-to-month or pending
  - `is_active` boolean, required

## Other responses

- `422`: Validation Error

## Changes

- **2026-10-07** `d443593f5f45`: 6 breaking, 6 info
  - the response property `end_date` became optional for the status `201`
  - the response property `number_of_months` became optional for the status `201`
  - the response property `start_date` became optional for the status `201`
  - response property `end_date` list-of-types was widened by adding types `null` to media type `application/json` of response `201`
  - …8 more

[Operation history](https://skmtc.dev/openintake/apis/openintake-api/changes/billing/developer/contracts/:customer_id/post.md)

---

[API](https://skmtc.dev/openintake/apis/openintake-api.md) - [All operations](https://skmtc.dev/openintake/apis/openintake-api/llms.txt) - [OpenAPI document](https://skmtc.dev/openintake/apis/openintake-api/revisions/de90a8dcbc07?raw)
