---
description: 'Learn how to manage draft orders using the admin REST APIs. This guide includes how to manage draft orders including listing and creating them, manage their line items, and register their payment.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Manage Draft Orders
In this document, you’ll learn how to manage draft orders using the admin REST APIs.
## Overview
Using the draft orders admin REST APIs, you can manage draft orders and perform other related functionalities.
### Scenario
You want to add or use the following admin functionalities:
- Manage draft orders, including listing, creating, updating, and deleting draft orders.
- Managing line items in draft orders, including adding, updating, and deleting items from a draft order.
- Authorize and capture a draft order’s payment.
---
## Prerequisites
### Medusa Components
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.mdx) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.mdx#usage).
### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial.
You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
---
## List Draft Orders
You can list draft orders by sending a request to the [List Draft Orders endpoint]( /api/admin#tag/Draft-Orders/operation/GetDraftOrders):
```ts
medusa.admin.draftOrders.list()
.then(({ draft_orders, limit, offset, count }) => {
console.log(draft_orders.length)
})
```
```tsx
import { useAdminDraftOrders } from "medusa-react"
const DraftOrders = () => {
const { draft_orders, isLoading } = useAdminDraftOrders()
return (
)
}
export default DraftOrders
```
```ts
fetch(`/admin/draft-orders`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ draft_orders, limit, offset, count }) => {
console.log(draft_orders.length)
})
```
```bash
curl -L -X GET '/admin/draft-orders' \
-H 'Authorization: Bearer '
```
This endpoint does not require any path or query parameters. You can pass search or pagination query parameters as explained in the [API reference]( /api/admin#tag/Draft-Orders/operation/GetDraftOrders).
The request returns an array of draft order objects along with [pagination parameters]( /api/admin#section/Pagination).
---
## Create a Draft Order
You can create a draft order by sending a request to the [Create Draft Order endpoint]( /api/admin#tag/Draft-Orders/operation/PostDraftOrders):
```ts
medusa.admin.draftOrders.create({
email,
region_id,
items: [
{
// defined product
quantity: 1,
variant_id,
},
{
// custom product
quantity: 1,
unit_price: 1000,
title: "Custom Product",
},
],
shipping_methods: [
{
option_id,
// for custom shipping price
price,
},
],
})
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```tsx
import { useAdminCreateDraftOrder } from "medusa-react"
const CreateDraftOrder = () => {
const createDraftOrder = useAdminCreateDraftOrder()
// ...
const handleCreate = () => {
createDraftOrder.mutate({
email,
region_id,
items: [
{
// defined product
quantity: 1,
variant_id,
},
{
// custom product
quantity: 1,
unit_price: 1000,
title: "Custom Product",
},
],
shipping_methods: [
{
option_id,
// for custom shipping price
price,
},
],
})
}
// ...
}
export default CreateDraftOrder
```
```ts
fetch(`/admin/draft-orders`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
region_id,
items: [
{
// defined product
quantity: 1,
variant_id,
},
{
// custom product
quantity: 1,
unit_price: 1000,
title: "Custom Product",
},
],
shipping_methods: [
{
option_id,
// for custom shipping price
price,
},
],
}),
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```bash
curl -L -X POST '/admin/draft-orders' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
--data-raw '{
"email": "",
"region_id": "",
"items": [
{
"quantity": 1,
"variant_id": ""
},
{
"quantity": 1,
"unit_price": 1000,
"title": "Custom Product"
}
],
"shipping_methods": [
{
"option_id": "",
"price": 1000
}
]
}'
```
This endpoint requires the following request body parameters:
- `email`: a string indicating the email of the customer to associate this draft order with.
- `region_id`: a string indicating the ID of the region this draft order belongs to.
- `shipping_methods`: an array of objects, each object being a shipping method to use for the draft order. The object is required to have the `option_id` property which is the ID of the shipping option to use. You can optionally specify a `price` property to set a custom amount for the price.
You can also pass other optional parameters. For example, the `items` array can be passed to add line items to the draft order. There are two types of items that you can add:
1. Defined product variants. This is done by passing the `variant_id` property, with its value being the ID of the product variant to add.
2. Custom products that aren’t defined in your store. This is done by passing the `unit_price` property with its value being the price of the custom product, and the `title` property with its value being the title of the custom product.
You must also pass for each item its quantity.
To learn about other optional request body parameters, such as passing shipping or billing addresses, check out the [API reference]( /api/admin#tag/Draft-Orders/operation/PostDraftOrders).
The request returns the created draft order as an object.
---
## Retrieve Draft Order
You can retrieve a draft order by sending a request to the [Get Draft Order endpoint]( /api/admin#tag/Draft-Orders/operation/GetDraftOrdersDraftOrder):
```ts
medusa.admin.draftOrders.retrieve(draftOrderId)
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```tsx
import { useAdminDraftOrder } from "medusa-react"
const DraftOrder = () => {
const {
draft_order,
isLoading,
} = useAdminDraftOrder(draftOrderId)
return (
)
}
export default DraftOrder
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```bash
curl -L -X GET '/admin/draft-orders/' \
-H 'Authorization: Bearer '
```
This endpoint requires the draft order’s ID as a path parameter.
The request returns the draft order as an object.
---
## Update Draft Order
You can update a draft order by sending a request to the [Update Draft Order endpoint]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrder):
```ts
medusa.admin.draftOrders.update(draftOrderId, {
email: "user@example.com",
})
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```tsx
import { useAdminUpdateDraftOrder } from "medusa-react"
const UpdateDraftOrder = () => {
const updateDraftOrder = useAdminUpdateDraftOrder(
draftOrderId
)
// ...
const handleUpdate = () => {
updateDraftOrder.mutate({
email: "user@example.com",
})
}
// ...
}
export default UpdateDraftOrder
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "user@example.com",
}),
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.id)
})
```
```bash
curl -L -X POST '/admin/draft-orders/' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
--data-raw '{
"email": "user@example.com"
}'
```
This endpoint requires the draft order’s ID as a path parameter.
In the request body, you can pass any of the draft order’s fields to update. In the example above, you update the `email` field. Check out the [API reference]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrder) to learn about other accepted request body parameters.
The request returns the updated draft order as an object.
---
## Manage Line Items
### Add Line Items
You can add line items to a draft order by sending a request to the [Create Line Items endpoint]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrderLineItems):
```ts
medusa.admin.draftOrders.addLineItem(draftOrderId, {
quantity: 1,
})
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```tsx
import { useAdminDraftOrderAddLineItem } from "medusa-react"
const AddLineItem = () => {
const addLineItem = useAdminDraftOrderAddLineItem(
draftOrderId
)
// ...
const handleAdd = () => {
addLineItem.mutate({
quantity: 1,
})
}
// ...
}
export default AddLineItem
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}/line-items`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
quantity: 1,
}),
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```bash
curl -L -X POST '/admin/draft-orders//line-items' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
--data-raw '{
"quantity": 1
}'
```
This endpoint requires the ID of the draft order as a path parameter.
In the request body, it’s required to pass the `quantity` parameter, which is a number indicating the quantity of the item in the draft order. You can also pass other optional parameters based on the type of line item you’re adding.
There are two types of items that you can add:
1. Defined product variants. This is done by passing the `variant_id` parameter, with its value being the ID of the product variant to add.
2. Custom products that aren’t defined in your store. This is done by passing the `unit_price` parameter with its value being the price of the custom product, and the `title` property with its value being the title of the custom product.
Check the [API reference]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrderLineItems) for a full list of request body parameters.
The request returns the updated draft order as an object. You can access the draft order’s items by accessing the `carts` property in the draft item, then the `items` property. The `items` property is an array of line item objects.
### Update Line Item
You can update a line item by sending a request to the [Update Line Item endpoint]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrderLineItemsItem):
```ts
medusa.admin.draftOrders.updateLineItem(draftOrderId, itemId, {
quantity: 1,
})
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```tsx
import { useAdminDraftOrderUpdateLineItem } from "medusa-react"
const UpdateLineItem = () => {
const updateLineItem = useAdminDraftOrderUpdateLineItem(
draftOrderId
)
// ...
const handleUpdate = () => {
updateLineItem.mutate({
item_id,
quantity: 1,
})
}
// ...
}
export default UpdateLineItem
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
quantity: 1,
}),
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```bash
curl -L -X POST '/admin/draft-orders//line-items/' \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
--data-raw '{
"quantity": 1
}'
```
This endpoint requires the draft order and line item’s IDs as path parameters.
In the request body, you can pass any of the line item’s fields as parameters to update them. In the example above, you pass the `quantity` parameter to update the quantity of the item. Check out the [API reference]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrderLineItemsItem) for a full list of request body parameters.
The request returns the updated draft order as an object. You can access the draft order’s items by accessing the `carts` property in the draft item, then the `items` property. The `items` property is an array of line item objects.
### Delete Line Item
You can delete a line item by sending a request to the [Delete Line Item endpoint]( /api/admin#tag/Draft-Orders/operation/DeleteDraftOrdersDraftOrderLineItemsItem):
```ts
medusa.admin.draftOrders.removeLineItem(draftOrderId, itemId)
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```tsx
import { useAdminDraftOrderRemoveLineItem } from "medusa-react"
const DeleteLineItem = () => {
const deleteLineItem = useAdminDraftOrderRemoveLineItem(
draftOrderId
)
// ...
const handleDelete = () => {
deleteLineItem.mutate(itemId)
}
// ...
}
export default DeleteLineItem
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, {
credentials: "include",
method: "DELETE",
})
.then((response) => response.json())
.then(({ draft_order }) => {
console.log(draft_order.cart.items)
})
```
```bash
curl -L -X DELETE '/admin/draft-orders//line-items/' \
-H 'Authorization: Bearer '
```
This endpoint requires the draft order and line item’s IDs as path parameters.
The request returns the updated draft order as an object. You can access the draft order’s items by accessing the `carts` property in the draft item, then the `items` property. The `items` property is an array of line item objects.
---
## Register Draft Order Payment
Registering the draft order’s payment leads to authorizing and capturing the payment using the `system` payment method. This would complete the draft order and create an order from it.
You can register the draft order payment by sending a request to the [Register Draft Order Payment endpoint]( /api/admin#tag/Draft-Orders/operation/PostDraftOrdersDraftOrderRegisterPayment):
```ts
medusa.admin.draftOrders.markPaid(draftOrderId)
.then(({ order }) => {
console.log(order.id)
})
```
```tsx
import { useAdminDraftOrderRegisterPayment } from "medusa-react"
const RegisterPayment = () => {
const registerPayment = useAdminDraftOrderRegisterPayment(
draftOrderId
)
// ...
const handlePayment = () => {
registerPayment.mutate()
}
// ...
}
export default RegisterPayment
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}/pay`, {
credentials: "include",
method: "POST",
})
.then((response) => response.json())
.then(({ order }) => {
console.log(order.id)
})
```
```bash
curl -L -X POST '/admin/draft-orders//pay' \
-H 'Authorization: Bearer '
```
This endpoint requires the draft order’s ID as a path parameter.
The request returns the order created from the draft order as an object.
---
## Delete a Draft Order
You can delete a draft order by sending a request to the [Delete Draft Order endpoint]( /api/admin#tag/Draft-Orders/operation/DeleteDraftOrdersDraftOrder):
```ts
medusa.admin.draftOrders.delete(draftOrderId)
.then(({ id, object, deleted }) => {
console.log(id)
})
```
```tsx
import { useAdminDeleteDraftOrder } from "medusa-react"
const DeleteDraftOrder = () => {
const deleteDraftOrder = useAdminDeleteDraftOrder(
draftOrderId
)
// ...
const handleDelete = () => {
deleteDraftOrder.mutate()
}
// ...
}
export default DeleteDraftOrder
```
```ts
fetch(`/admin/draft-orders/${draftOrderId}`, {
credentials: "include",
method: "DELETE",
})
.then((response) => response.json())
.then(({ id, object, deleted }) => {
console.log(id)
})
```
```bash
curl -L -X DELETE '/admin/draft-orders/' \
-H 'Authorization: Bearer '
```
This endpoint requires the draft order’s ID as a path parameter.
The request returns the following fields:
- `id`: The ID of the deleted draft order.
- `object`: The type of object that was deleted. In this case, the value will be `draft-order`.
- `deleted`: A boolean value indicating whether the draft order was deleted.
---
## See Also
- [How to manage orders](./manage-orders.mdx)
- [Orders architecture overview](../orders.md)