---
title: "Creates a Contract"
method: POST
path: "/contracts"
tags: ["Contract"]
---

# Creates a Contract

`POST /contracts`

Required permission: Contracts - Edit

A complete contract — top-level attributes, covered items with their contracted
rates, the block-list and the non-billable products — is created in this one call.

Covered items are part of the contract payload:

* `product_price_overrides` — the covered products with their contracted rate
  (`price_retail_cents` or `discount_percentage`) and their block-list status
  (`blacklisted`, meaning the product is billed separately from the contract).
* `non_billable_product_ids` — products covered by the contract and therefore not
  billed on their own.
* `schedule_ids` — the recurring invoice schedules this contract governs. Link a
  schedule to a contract by sending `contract_id` to the Schedule endpoints.

## Request body

- object
  - `contract_amount` string
  - `customer_id` integer, required
  - `description` string
  - `start_date` string, date
  - `end_date` string, date
  - `name` string
  - `primary_contact` string
  - `status` string
  - `likelihood` integer
  - `apply_to_all` boolean
  - `sla_id` integer
  - `tag_list` string[]
  - `product_price_overrides` object[] — The products the contract covers, with their contracted rates and block-list status. Replaces the whole set: omit the key to leave the existing overrides untouched, or send an empty array to remove them all. An entry with an `id` updates that existing override, an entry without one creates a new override, and any existing override whose `id` is not listed is deleted. Set either `price_retail_cents` or `discount_percentage` (never both) unless `blacklisted` is true. Must be a JSON array of objects — anything else, including an array containing `null`, is rejected with 422 rather than treated as an empty set. Clearing the set requires a JSON body, since a form-encoded empty array cannot be transmitted.
    - `id` integer — Existing override to update; omit to create a new one
    - `product_id` integer
    - `price_retail_cents` integer — Contracted rate for the product, in cents
    - `discount_percentage` number — Percentage off the catalog price, greater than 0 and at most 100
    - `blacklisted` boolean — Block-list the product so it is billed separately from the contract
  - `non_billable_product_ids` integer[] — Products covered by the contract and therefore not billed separately. Replaces the whole set; omit the key to leave it untouched. Must be a JSON array of integers — anything else, including an array containing `null`, is rejected with 422 rather than treated as an empty set. Clearing the set requires a JSON body, since a form-encoded empty array cannot be transmitted.

## Response `200`

successful

## Other responses

- `422` — Invalid request

---

[API](https://skmtc.dev/syncromsp/apis/syncro.md) · [All operations](https://skmtc.dev/syncromsp/apis/syncro/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/syncromsp/syncro/revisions/dfc1c332d2c2/schema)
