---
title: "open a purchase order"
method: POST
path: "/api/v1/organizations/{organization_id}/purchase-orders"
tags: ["purchase_orders"]
---

# open a purchase order

`POST /api/v1/organizations/{organization_id}/purchase-orders`

## Request

- Base URL: `https://api.app.tightly.io`
- URL: `https://api.app.tightly.io/api/v1/organizations/{organization_id}/purchase-orders`
- Auth: HTTP bearer

Opens one purchase order and returns it. The body names the destination `location_id` (required) and, optionally, `order_type`, `supplier_id`, `source_location_id`, `recommended_quantity`, `order_date`, `expected_delivery_date` and `commitment_id`.

It takes no line items. An order opened here is empty, and `total_line_items` on the response is 0; bulk_create_purchase_orders is the door that creates orders together with their lines, one order per supplier and location, and update_purchase_order is the one that adds lines to an order that already exists.

`commitment_id` records which Commitment the order is placed against, and an id this organisation does not have is refused 400. Send it only when it came from a Commitments read.

A transfer (`order_type=TRANSFER`, `source_location_id` required) opened here is empty like every other order this door opens, so it draws no quantity and no source shelf is read. The shortfall refusal belongs to bulk_create_purchase_orders, the door that sends line items, and is documented there. A purchase order is never checked against a shelf on either door, because a buy asks a supplier for units nobody holds yet.

Scope: `purchase_orders:write`, which includes `purchase_orders:read`.

## Path parameters

- `organization_id` string, required

## Headers

- `Tightly-Version` string
- `Idempotency-Key` string

## Request body

- CreatePurchaseOrderRequest
  - `cancel_date` string, date: The last day of the ship window, inclusive. After it the buyer may walk away from whatever the vendor has not shipped. Must not be before `ship_window_start`.
  - `commitment_id` string, nullable
  - `expected_delivery_date` string, date
  - `location_id` string, required
  - `order_date` string, date
  - `order_type` unknown
  - `recommended_quantity` integer, nullable
  - `ship_window_start` string, date: The first day the vendor may ship this order. Optional, and normally absent: most orders are placed against an expected delivery date and no window.
  - `source_location_id` string, nullable
  - `supplier_id` string, nullable

## Response `201`

The purchase order as created

- object
  - `data` object
  - `message` object: severity, service and desc.

## Other responses

- `400`: Bad Request - Invalid request parameters or validation errors. Also returned when a stamp names a Commitment this organization does not have. Nothing is created.
- `401`: No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
- `403`: The key may not reach this operation. `scope_missing` when the key does not hold Purchase orders; `organization_mismatch` when the path names an organisation that is not the key's; `ip_not_allowed` when the caller's address is outside the key's allowlist.
- `429`: The key has spent its allowance for this minute. 600 reads and 120 writes a minute, counted per key, refused calls included. `Retry-After` says how long to wait.
- `500`: Internal Server Error - Database connection or processing errors
- `503`: The database is briefly out of reach, which is what a failover or a full connection pool looks like from outside. Wait the seconds `Retry-After` names and send the request again. A read is safe to repeat. A write is not, because the connection was lost in the middle of it, so read the object back before sending it a second time. Branch on the status rather than on `code`, which is `POSTGRES_UNAVAILABLE` from one of the two seams that raise this and `SERVICE_UNAVAILABLE` from the other.

---

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