curl -X POST https://api.metrifox.com/api/v1/orders \
-H "x-api-key: $METRIFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency_code": "USD",
"customer_key": "customer-123",
"line_items": [
{
"item_type": "plan",
"item_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"price_option_id": "85ba44aa-eb4f-47be-a84f-3b290488f1ca",
"quantity": 1
}
]
}'import requests
url = "https://{defaultHost}/api/v1/orders"
payload = {
"currency_code": "USD",
"customer_key": "customer-123",
"line_items": [
{
"item_type": "plan",
"item_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"price_option_id": "85ba44aa-eb4f-47be-a84f-3b290488f1ca",
"quantity": 1
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
currency_code: 'USD',
customer_key: 'customer-123',
line_items: [
{
item_type: 'plan',
item_id: '603efd2d-1100-4bf1-a577-5a96f4847891',
price_option_id: '85ba44aa-eb4f-47be-a84f-3b290488f1ca',
quantity: 1
}
]
})
};
fetch('https://{defaultHost}/api/v1/orders', 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://{defaultHost}/api/v1/orders",
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([
'currency_code' => 'USD',
'customer_key' => 'customer-123',
'line_items' => [
[
'item_type' => 'plan',
'item_id' => '603efd2d-1100-4bf1-a577-5a96f4847891',
'price_option_id' => '85ba44aa-eb4f-47be-a84f-3b290488f1ca',
'quantity' => 1
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://{defaultHost}/api/v1/orders"
payload := strings.NewReader("{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://{defaultHost}/api/v1/orders")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{defaultHost}/api/v1/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"statusCode": 201,
"message": "Order Created Successfully",
"meta": {},
"data": {
"id": "a8c9fc2f-6841-48ae-8496-ceca19be5a3d",
"customer_id": "764c80e3-ed59-44a5-ba07-7ee5ba547774",
"order_number": "ORD-1042",
"status": "pending",
"currency_code": "USD",
"subtotal_in_standard_unit": 49,
"subtotal_before_discount_in_standard_unit": 49,
"discount_amount_in_standard_unit": 0,
"tax_amount_in_standard_unit": 0,
"total_in_standard_unit": 49,
"order_line_items": [
{
"id": "947ac9c3-b7b6-4e52-a57d-220f835761cb",
"quantity": 1,
"unit_price": 49,
"total_price": 49,
"subtotal_before_discount": 49,
"discount_amount": 0,
"amount_before_tax": 49,
"tax_rate": 0,
"tax_amount": 0,
"tax_inclusive": false,
"name": "Pro",
"source_type": "plan",
"source_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"invoice_id": null
}
],
"applied_discounts": [],
"order_charges": [],
"invoices": [],
"setup_intent": null,
"is_manual": true,
"is_sandbox": false,
"customer": {},
"payment_method": null,
"billing_interval": "monthly",
"billing_interval_value": 1,
"subscription_id": null,
"subscription_config": null,
"policy": null,
"should_collect_payment": true,
"should_collect_card": false,
"manual_discount_selections": [],
"created_at": "2026-10-07T09:30:00Z",
"updated_at": "2026-10-07T09:30:00Z"
},
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}Create Order
Create an order for an existing customer
curl -X POST https://api.metrifox.com/api/v1/orders \
-H "x-api-key: $METRIFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency_code": "USD",
"customer_key": "customer-123",
"line_items": [
{
"item_type": "plan",
"item_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"price_option_id": "85ba44aa-eb4f-47be-a84f-3b290488f1ca",
"quantity": 1
}
]
}'import requests
url = "https://{defaultHost}/api/v1/orders"
payload = {
"currency_code": "USD",
"customer_key": "customer-123",
"line_items": [
{
"item_type": "plan",
"item_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"price_option_id": "85ba44aa-eb4f-47be-a84f-3b290488f1ca",
"quantity": 1
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
currency_code: 'USD',
customer_key: 'customer-123',
line_items: [
{
item_type: 'plan',
item_id: '603efd2d-1100-4bf1-a577-5a96f4847891',
price_option_id: '85ba44aa-eb4f-47be-a84f-3b290488f1ca',
quantity: 1
}
]
})
};
fetch('https://{defaultHost}/api/v1/orders', 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://{defaultHost}/api/v1/orders",
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([
'currency_code' => 'USD',
'customer_key' => 'customer-123',
'line_items' => [
[
'item_type' => 'plan',
'item_id' => '603efd2d-1100-4bf1-a577-5a96f4847891',
'price_option_id' => '85ba44aa-eb4f-47be-a84f-3b290488f1ca',
'quantity' => 1
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://{defaultHost}/api/v1/orders"
payload := strings.NewReader("{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://{defaultHost}/api/v1/orders")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{defaultHost}/api/v1/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"currency_code\": \"USD\",\n \"customer_key\": \"customer-123\",\n \"line_items\": [\n {\n \"item_type\": \"plan\",\n \"item_id\": \"603efd2d-1100-4bf1-a577-5a96f4847891\",\n \"price_option_id\": \"85ba44aa-eb4f-47be-a84f-3b290488f1ca\",\n \"quantity\": 1\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"statusCode": 201,
"message": "Order Created Successfully",
"meta": {},
"data": {
"id": "a8c9fc2f-6841-48ae-8496-ceca19be5a3d",
"customer_id": "764c80e3-ed59-44a5-ba07-7ee5ba547774",
"order_number": "ORD-1042",
"status": "pending",
"currency_code": "USD",
"subtotal_in_standard_unit": 49,
"subtotal_before_discount_in_standard_unit": 49,
"discount_amount_in_standard_unit": 0,
"tax_amount_in_standard_unit": 0,
"total_in_standard_unit": 49,
"order_line_items": [
{
"id": "947ac9c3-b7b6-4e52-a57d-220f835761cb",
"quantity": 1,
"unit_price": 49,
"total_price": 49,
"subtotal_before_discount": 49,
"discount_amount": 0,
"amount_before_tax": 49,
"tax_rate": 0,
"tax_amount": 0,
"tax_inclusive": false,
"name": "Pro",
"source_type": "plan",
"source_id": "603efd2d-1100-4bf1-a577-5a96f4847891",
"invoice_id": null
}
],
"applied_discounts": [],
"order_charges": [],
"invoices": [],
"setup_intent": null,
"is_manual": true,
"is_sandbox": false,
"customer": {},
"payment_method": null,
"billing_interval": "monthly",
"billing_interval_value": 1,
"subscription_id": null,
"subscription_config": null,
"policy": null,
"should_collect_payment": true,
"should_collect_card": false,
"manual_discount_selections": [],
"created_at": "2026-10-07T09:30:00Z",
"updated_at": "2026-10-07T09:30:00Z"
},
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}{
"message": "<string>",
"errors": {}
}customer_id or customer_key. Do not send both. Every line item must reference a resource owned by your tenant.
write or admin scope. Pass the raw key in the x-api-key header.plan line item, and its quantity must be 1. For an invoice line item, omit price_option_id; Metrifox creates a carryover item and sets the quantity to 1.Find the correct price option
For every priced line item, send the ID of the price option whoseprice.currency matches the order’s currency_code. An item can have price options in several currencies, so do not use a price option based only on the item ID.
Retrieve the product and its full offering details with a read, write, or admin API key:
curl "https://api.metrifox.com/api/v1/product_catalogues/products/{product_id}" \
-H "x-api-key: $METRIFOX_API_KEY"
country_code as a query parameter when you want the response filtered to the product’s pricing for a particular country.
Use the following fields in the response:
item_type | item_id | Where to find price_option_id |
|---|---|---|
plan, addon, or single_purchase | The selected published_version.version_id | The matching entry in published_version.price_options |
entitlement | The selected entry’s ID in published_version.entitlements | The matching entry in published_version.entitlement_price_options |
credit | The selected entry’s ID in published_version.credit_attachments | The matching entry in published_version.credit_attachment_price_options |
charge | published_version.charge_attachments[].charge.id | The matching default charge.price_option or an entry in charge.localized_prices[].price_options |
invoice | The existing invoice ID | Omit price_option_id; Metrifox derives it from the invoice carryover |
price.currency equals the order’s currency_code, then send that entry’s id as price_option_id. The price option must belong to the resource identified by item_id.Authorizations
Body
Identify the customer by providing exactly one of customer_id or
customer_key. Do not send both fields.
Three-letter ISO 4217 currency code used to price the order.
3"USD"
1Show child attributes
Show child attributes
Metrifox customer ID. Provide this or customer_key, but not both.
Your immutable customer identifier. Provide this or customer_id, but not both.
"customer-123"
Whether the order is manually initiated.
When true, do not generate an invoice for the order.
Existing subscription associated with this order.
Custom date and time at which subscription provisioning should begin.
Billing cadence. Provide billing_interval_value with this field.
daily, weekly, monthly, quarterly, biannually, yearly, once Number of billing intervals. Provide billing_interval with this field.
x >= 1Initial order status. Draft orders are saved without invoicing or provisioning.
pending, draft Subscription being changed or migrated by this order.
Type of subscription change represented by the order.
quantity_upgrade, quantity_downgrade, upgrade, downgrade, addon_add, addon_remove, plan_migration Plan-change policy used when transitioning an existing subscription.
Discounts explicitly selected for this order.
Show child attributes
Show child attributes

