Skip to main content
POST
/
orders
/
{id}
/
convert
Convert a quote to a sales order
curl --request POST \
  --url https://api.arcuserp.com/v1/orders/{id}/convert \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "user_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
'
import requests

url = "https://api.arcuserp.com/v1/orders/{id}/convert"

payload = { "user_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({user_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'})
};

fetch('https://api.arcuserp.com/v1/orders/{id}/convert', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.arcuserp.com/v1/orders/{id}/convert",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'user_id' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.arcuserp.com/v1/orders/{id}/convert"

payload := strings.NewReader("{\n \"user_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.arcuserp.com/v1/orders/{id}/convert")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"user_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.arcuserp.com/v1/orders/{id}/convert")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"\n}"

response = http.request(request)
puts response.read_body
{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "object": "order",
  "entity_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "order_number": "<string>",
  "account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "location_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "po_number": "<string>",
  "order_date": "2023-11-07T05:31:56Z",
  "due_date": "2023-11-07T05:31:56Z",
  "subtotal": 123,
  "discount_total": 123,
  "shipping_total": 123,
  "tax_total": 123,
  "fee_total": 123,
  "order_total": 123,
  "list_price_total": 123,
  "pricing_savings": 123,
  "amount_paid": 123,
  "balance_due": 123,
  "tax_exempt": true,
  "notes": "<string>",
  "internal_notes": "<string>",
  "invoice_number": "<string>",
  "is_on_hold": true,
  "hold_type": "<string>",
  "ship_complete": true,
  "source_platform": "<string>",
  "external_order_id": "<string>",
  "external_order_number": "<string>",
  "metadata": {},
  "created_at": "2023-11-07T05:31:56Z",
  "updated_at": "2023-11-07T05:31:56Z"
}
{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}
{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}
{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}
{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}
{
"error": "not_found",
"code": "not_found",
"type": "not_found",
"hint": "The requested order does not exist or does not belong to this entity.",
"param": "expand[0]",
"required": "accounts:read",
"request_id": "req_abc123"
}

Authorizations

Authorization
string
header
required

API key issued per entity via Settings > Developers > API Keys. Each key carries scopes (e.g. orders:read, products:write). Bearer token format: Authorization: Bearer ark_live_ent_Test keys use ark_test_ent_. Both are issued per entity
via Settings > Developers > API Keys.

Headers

Idempotency-Key
string

Client-generated unique key for idempotent POST/PATCH/DELETE operations. Alias for the Idempotency parameter. Max 255 chars. On retry with the same key, the original response is returned without re-executing the operation. Keys expire after 24 hours.

Maximum string length: 255

Path Parameters

id
string<uuid>
required

UUID of the quote to convert.

Body

application/json
user_id
string<uuid>

UUID of the user performing the conversion. Defaults to the API key owner if omitted.

Response

New sales order (draft) created from the quote.

An Arcus ERP order document. One table holds quotes, sales_orders, invoices, returns, and purchase_orders -- always filter by document_type. entity_id is always from the API key (Layer 1 isolation).

id
string<uuid>
object
enum<string>
Available options:
order
entity_id
string<uuid>
read-only
order_number
string
read-only
document_type
enum<string>
Available options:
quote,
sales_order,
invoice,
return,
purchase_order
order_status
enum<string>
Available options:
draft,
confirmed,
partially_fulfilled,
fulfilled,
cancelled,
voided,
awaiting_ach_clearance,
on_hold
payment_status
enum<string>
Available options:
unpaid,
partially_paid,
paid,
overpaid,
refunded,
partially_refunded,
voided
fulfillment_status
enum<string>
Available options:
unfulfilled,
partially_fulfilled,
fulfilled
account_id
string<uuid> | null
location_id
string<uuid> | null
po_number
string | null
order_date
string<date-time> | null
due_date
string<date-time> | null
subtotal
number
discount_total
number
shipping_total
number
tax_total
number
fee_total
number
order_total
number
list_price_total
number
read-only

Derived (display-only): SUM(list_price * qty) over non-kit lines. The gross baseline of the gross-to-net bridge (List price minus pricing_savings equals subtotal). Never part of order_total.

pricing_savings
number
read-only

Derived (display-only): SUM(pricing_rule_adjustment * qty) over non-kit lines (positive magnitude). Per-unit pricing-rule savings already baked into subtotal via sell_rate (ASC 606 transaction price); shown as an informational List-to-Subtotal bridge, never subtracted from order_total.

amount_paid
number
read-only

SSOT: utils/ar-helpers.mjs::updateARBalance. Do not write directly.

balance_due
number
read-only
tax_exempt
boolean
delivery_option
enum<string>
Available options:
ship,
pick_up,
local_delivery
notes
string | null
internal_notes
string | null
invoice_number
string | null
read-only
invoice_type
enum<string> | null
Available options:
order,
manual,
proforma,
correction
is_on_hold
boolean
read-only
hold_type
string | null
read-only
ship_complete
boolean
source_platform
string | null
external_order_id
string | null
external_order_number
string | null
metadata
object | null
created_at
string<date-time>
read-only
updated_at
string<date-time>
read-only