Create order
Create a new order with HMAC signature verification and idempotency protection.
π HMAC Signing (REQUIRED)
All order creation requests MUST include HMAC-SHA256 signature for security:
- Generate Timestamp: Get current Unix timestamp in seconds
- Create Payload: Concatenate
timestamp + "." + JSON_body - Sign Payload:
HMAC-SHA256(hmac_secret, payload)β base64 encode - Include Headers:
X-Timestamp: Unix timestamp (must be within 5 minutes)X-Signature: Base64-encoded HMAC signature
Example (Node.js):
π Idempotency Protection
Include Idempotency-Key header to prevent duplicate orders on retry.
If the same key is used, the original order is returned (not counted against rate limit).
β οΈ Security Notes:
- HMAC secret is displayed in the Integrations page (Developer section)
- Never expose HMAC secret in client-side code
- Regenerate secret immediately if compromised
- Requests with invalid/missing signatures return 401 Unauthorized
- Timestamps older than 5 minutes are rejected to prevent replay attacks
π‘οΈ Server-side price validation (anti-tampering)
HMAC proves the body wasnβt altered in transit; it does not prove the amounts are honest. So the server independently recomputes the order from authoritative data and rejects any mismatch β you cannot set your own prices or discounts:
- Item prices are recomputed from the live catalog.
unit_price/total_pricethat donβt match the catalog price β400 price_mismatch. (The stored order always uses the catalog price, never the value you send.) subtotal,tax_amount,total_amountmust reconcile tosubtotal + tax + shipping β discountover those catalog prices β otherwise400 price_mismatch.tax_amountis calculated by the server when you omit it: for theshipping_addresswhen the store has automatic tax (the shipping charge is rated as its own line), otherwise at the storeβs own rate β on the line totals, plus the shipping charge when the store charges tax on shipping. At the storeβs own rate atax_amountyou send must match that figure to the cent β otherwise400 price_mismatch. When the storeβs prices include tax, the tax is taken from what the shopper pays (line totals β discount, plus shipping when taxed) andsubtotalis the line totals minus that tax.POST /v1/tax/previewreturns the same figure before checkout.discount_amountis validated against the discount the promotions / gift card you claim actually grant (computed server-side frompromotion_usages+gift_card_redemption). Adiscount_amountgreater than that legitimate maximum β400 discount_invalid. A discount with no real promotion/gift card behind it β max is0. (You may apply less than the maximum.)shipping_amountis checked on every order, $0 included, and may not be negative:- With a carrier option (
shipping_rate_id+shipping_rate_source, orshippo_rate_id), the option is fetched again from its source β the storeβs carrier account, or its custom shipping extension re-quoted forshipping_addressandshipping_parcel. An unknown, expired or foreign option, one in another currency, or a test-mode option on a live order β400 shipping_rate_invalid; an amount that differs from the option β400 price_mismatch. - Otherwise, when the store has delivery rates and the destination is known
(
shipping_latitude/shipping_longitude, or ashipping_addressthat can be located), the amount must equal the storeβs charge for that address, free-delivery thresholds measured against the line totals afterdiscount_amountβ otherwise400 price_mismatch. A destination the store does not deliver to β400 shipping_not_deliverable. - With a named delivery option (
shipping_option_idof the formopt:<id>), the amount must equal that optionβs fee for the address and basket β otherwise400 price_mismatch. An option the order does not qualify for β400 shipping_option_unavailable. - On a pickup order (
fulfillment_method: pickup), the amount must equal the locationβs pickup fee β otherwise400 price_mismatch. A location that is not one of the storeβs pickup locations, or an order below its minimum β400 pickup_unavailable. Tax is calculated at the pickup location. - A store with no delivery rates (it ships through its own arrangements) accepts the amount sent; so does an order whose destination cannot be located. Such an order is recorded as not checked.
- When shipping cannot be checked because the service is unreachable β
502 shipping_unavailable; the order is not created.
- With a carrier option (
In short: send the real catalog prices and the actual promotions/gift card the shopper is entitled to. Donβt compute or invent prices/discounts client-side β the server is the authority.
curl --request POST \
--url https://api.tybritelabs.com/v1/orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'X-Signature: <x-signature>' \
--header 'X-Timestamp: <x-timestamp>' \
--data '
{
"customer_email": "john.doe@example.com",
"customer_name": "John Doe",
"customer_phone": "+12125550142",
"billing_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"shipping_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"items": [
{
"product_id": "715b8c10-eb11-4289-8c0e-2966e78cf9a5",
"variant_id": "15ca5a86-4b1b-47c3-8762-a1aa43941565",
"product_name": "Apple MacBook Pro",
"product_sku": "APP-MBP-13",
"quantity": 1,
"unit_price": 1999,
"total_price": 1999
}
],
"payment_method": "card",
"payment_status": "paid",
"subtotal": 1999,
"shipping_amount": 5.99,
"discount_amount": 0,
"total_amount": 2004.99,
"fulfillment_method": "delivery",
"shipping_option_id": "place",
"shipping_metadata": {
"fee": 5.99,
"tier_name": "Local (within 10 km)",
"distance_meters": 8548,
"is_free": false,
"reason": "8.5 km away",
"applied_rule": "distance"
},
"notes": "Leave with front desk"
}
'import requests
url = "https://api.tybritelabs.com/v1/orders"
payload = {
"customer_email": "john.doe@example.com",
"customer_name": "John Doe",
"customer_phone": "+12125550142",
"billing_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"shipping_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"items": [
{
"product_id": "715b8c10-eb11-4289-8c0e-2966e78cf9a5",
"variant_id": "15ca5a86-4b1b-47c3-8762-a1aa43941565",
"product_name": "Apple MacBook Pro",
"product_sku": "APP-MBP-13",
"quantity": 1,
"unit_price": 1999,
"total_price": 1999
}
],
"payment_method": "card",
"payment_status": "paid",
"subtotal": 1999,
"shipping_amount": 5.99,
"discount_amount": 0,
"total_amount": 2004.99,
"fulfillment_method": "delivery",
"shipping_option_id": "place",
"shipping_metadata": {
"fee": 5.99,
"tier_name": "Local (within 10 km)",
"distance_meters": 8548,
"is_free": False,
"reason": "8.5 km away",
"applied_rule": "distance"
},
"notes": "Leave with front desk"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"X-Timestamp": "<x-timestamp>",
"X-Signature": "<x-signature>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'X-Timestamp': '<x-timestamp>',
'X-Signature': '<x-signature>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customer_email: 'john.doe@example.com',
customer_name: 'John Doe',
customer_phone: '+12125550142',
billing_address: {
street: '350 Fifth Avenue',
city: 'New York',
state: 'NY',
zip: '10118',
country: 'US'
},
shipping_address: {
street: '350 Fifth Avenue',
city: 'New York',
state: 'NY',
zip: '10118',
country: 'US'
},
items: [
{
product_id: '715b8c10-eb11-4289-8c0e-2966e78cf9a5',
variant_id: '15ca5a86-4b1b-47c3-8762-a1aa43941565',
product_name: 'Apple MacBook Pro',
product_sku: 'APP-MBP-13',
quantity: 1,
unit_price: 1999,
total_price: 1999
}
],
payment_method: 'card',
payment_status: 'paid',
subtotal: 1999,
shipping_amount: 5.99,
discount_amount: 0,
total_amount: 2004.99,
fulfillment_method: 'delivery',
shipping_option_id: 'place',
shipping_metadata: {
fee: 5.99,
tier_name: 'Local (within 10 km)',
distance_meters: 8548,
is_free: false,
reason: '8.5 km away',
applied_rule: 'distance'
},
notes: 'Leave with front desk'
})
};
fetch('https://api.tybritelabs.com/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://api.tybritelabs.com/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([
'customer_email' => 'john.doe@example.com',
'customer_name' => 'John Doe',
'customer_phone' => '+12125550142',
'billing_address' => [
'street' => '350 Fifth Avenue',
'city' => 'New York',
'state' => 'NY',
'zip' => '10118',
'country' => 'US'
],
'shipping_address' => [
'street' => '350 Fifth Avenue',
'city' => 'New York',
'state' => 'NY',
'zip' => '10118',
'country' => 'US'
],
'items' => [
[
'product_id' => '715b8c10-eb11-4289-8c0e-2966e78cf9a5',
'variant_id' => '15ca5a86-4b1b-47c3-8762-a1aa43941565',
'product_name' => 'Apple MacBook Pro',
'product_sku' => 'APP-MBP-13',
'quantity' => 1,
'unit_price' => 1999,
'total_price' => 1999
]
],
'payment_method' => 'card',
'payment_status' => 'paid',
'subtotal' => 1999,
'shipping_amount' => 5.99,
'discount_amount' => 0,
'total_amount' => 2004.99,
'fulfillment_method' => 'delivery',
'shipping_option_id' => 'place',
'shipping_metadata' => [
'fee' => 5.99,
'tier_name' => 'Local (within 10 km)',
'distance_meters' => 8548,
'is_free' => false,
'reason' => '8.5 km away',
'applied_rule' => 'distance'
],
'notes' => 'Leave with front desk'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"X-Signature: <x-signature>",
"X-Timestamp: <x-timestamp>"
],
]);
$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.tybritelabs.com/v1/orders"
payload := strings.NewReader("{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("X-Timestamp", "<x-timestamp>")
req.Header.Add("X-Signature", "<x-signature>")
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.tybritelabs.com/v1/orders")
.header("Idempotency-Key", "<idempotency-key>")
.header("X-Timestamp", "<x-timestamp>")
.header("X-Signature", "<x-signature>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["X-Timestamp"] = '<x-timestamp>'
request["X-Signature"] = '<x-signature>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7f3c1e88-2b4a-4c9e-9d21-5a6b7c8d9e01",
"order_number": "ORD-20260804-4f2a91",
"order_status": "processing",
"payment_status": "paid",
"total_amount": 324.5
}Authorizations
API Key Authentication
Use your API key in the Authorization header:
Authorization: Bearer tybrite_sk_live_YOUR_KEY
Key Types:
Secret Keys (Server-Side Only):
- Format:
tybrite_sk_live_*(production) ortybrite_sk_test_*(sandbox) - Full read/write access to all endpoints
- β οΈ NEVER expose in client-side code or public repositories
- Required for: every write a shopper does not make for themselves, authentication, payment verification, AI recommendations
Publishable Keys (Client-Safe):
- Format:
tybrite_pk_live_*(production) ortybrite_pk_test_*(sandbox) - Catalogue reads, plus the actions a shopper takes for themselves
- β Safe for client-side JavaScript, mobile apps, and public code
- Allowed for: browsing products, search, CMS content, pricing queries, cart and wishlist, reviews, storefront events, and the Agent API's quotes, cart drafts and checkout intents
Endpoint-Specific Requirements:
- Authentication endpoints (
/v1/auth/*): Secret key required - Payment verification (
POST /v1/payments/verify): Secret key required - AI Recommendations (
POST /v1/recommendations): Secret key required - Semantic Search (
POST /v1/search): Both key types allowed (read-only operation) - Shopper actions (cart, wishlist, reviews, storefront events, Agent API quotes, cart drafts and checkout intents): Both key types allowed
- All other write operations: Secret key required
- All read operations: Both key types allowed
Using a publishable key for restricted operations returns 403 Forbidden.
Headers
Unique key to prevent duplicate orders (e.g., order-{timestamp}-{random})
Unix timestamp in seconds (current time). Must be within 5 minutes of server time. Used to prevent replay attacks.
HMAC-SHA256 signature of the payload (timestamp + "." + request_body), base64-encoded. Sign using your HMAC secret from the Integrations page (Developer section).
Body
Customer email address. Required.
"john.doe@example.com"
Customer full name. Required.
"John Doe"
Billing address. Required.
Show child attributes
Show child attributes
Order line items (at least one, at most 100)
1 - 100 elementsProvide variant_id OR product_id (at least one). Prefer variant_id β it is the exact variant (SKU) the shopper chose, so pass the same variant_id you put in the cart straight through to the order. If you send only product_id, the order is placed against the product's default variant β convenient for single-variant products, but for a product with multiple variants it may not be the one the shopper selected. When both are sent, variant_id wins (and product_id is resolved from it).
- Option 1
- Option 2
Show child attributes
Show child attributes
Payment method identifier (required)
card, stripe, paypal, paystack, mpesa, cash "card"
Subtotal before tax and shipping. Required.
2000
Total order amount (required)
2520
Customer UUID (optional - guest checkout supported)
"c320094c-eb65-4879-804c-83d2e1dd7f99"
Customer phone number (optional)
"+14155550199"
Shipping address. Required for a delivery order. On a pickup order it is not needed: the collection location's address is stored as the order's shipping address, with type: pickup.
Show child attributes
Show child attributes
Payment status (defaults to pending)
pending, paid, failed, refunded "pending"
Order fulfillment status (defaults to pending)
pending, confirmed, processing, shipped, delivered, cancelled "pending"
Tax amount
320
Shipping cost
200
Discount amount
0
Additional order notes
"Please deliver between 9 AM - 5 PM"
Shipping tracking number (optional, usually set on PATCH)
"1Z999AA10123456784"
Estimated delivery date and time (optional)
"2026-02-15T14:00:00Z"
External payment reference (e.g., Stripe charge ID, M-Pesa receipt)
"ch_1NqFvE2eZvKYlo2C8Z3y4abc"
Values for the merchant's own custom fields on this order, as
{ field_name: value }. Use this to carry a reference the merchant asked for at
checkout β a buyer's purchase-order number, a cost centre, a delivery instruction.
Each value is validated against the merchant's definition: a name that is not defined,
a value outside a select field's options, or a number that will not parse is
rejected. A rejected field does not fail the order β the order is created and
the reason is returned in post_processing_warnings, because the payment has already
been taken by that point. Read GET /v1/products/{id}/custom-fields or the order
response's custom_fields to discover which fields a merchant has defined.
{
"buyer_po": "PO-2026-0819",
"priority": "Express"
}
Shipping calculation details from /v1/shipping/calculate for audit trail
Show child attributes
Show child attributes
Optional gift card to redeem towards this order
Show child attributes
Show child attributes
Promotion usages applied to this order (tracked when payment_status is paid)
Show child attributes
Show child attributes
Campaigns to apply to this order, by id. The discount each one grants is computed server-side against the campaign's own rules and its remaining budget, so a campaign that has spent its budget adds nothing. Once the order is paid, what each campaign granted is drawn from its budget.
["3f1c8a4e-9d2b-4c17-8f5a-2b6d1e7c9a04"]
Apply the customer's redeemable store credit to this order. When
true (and the order has a customer_id), store credit is spent
against the order total, capped at the total. The amount actually
applied is returned as store_credit_applied. Requires a customer.
true
Optional cap on how much store credit to apply. When omitted (and
apply_store_credit is true) up to the full order total is applied.
The applied amount never exceeds the available balance or the total.
25
Your own order reference. When omitted, Galactic Core generates one. Use this to keep order numbers aligned with a system you already run.
"ORD-10432"
ISO 4217 currency code the order is priced in. When omitted, the store's default storefront currency is used. Set it when you present prices in a currency the shopper selected, so the order is recorded in the same currency it was paid in.
"USD"
Stock reservation ids returned by POST /v1/checkout/reserve. Supplying them commits the stock already held for this shopper instead of decrementing it again, which is what keeps a high-demand drop from overselling between reservation and payment. On a pending order the ids are kept with the order: they are committed when the order is paid and released when it is cancelled or its payment fails. Only holds on the order's own items are committed. At most 100 ids.
["8f2c1a9b-4d7e-4f10-9a3b-2c5e7f1d0a44"]
Delivery latitude, used to resolve the delivery zone or distance tier that prices shipping. Send it with shipping_longitude when the shopper's coordinates are known; the server re-derives the shipping cost from them rather than trusting a client total.
40.7128
Delivery longitude. See shipping_latitude.
-74.006
The id of a carrier option from the store's connected carrier account. Equivalent to shipping_rate_id with shipping_rate_source: shippo. The option is fetched again and checked before it is charged, so a modified, stale or foreign option is rejected.
"rate_8f2c1a9b4d7e4f109a3b2c5e7f1d0a44"
The id of the carrier option the shopper chose, as returned in rates[] by POST /v1/shipping/calculate. Send with shipping_rate_source.
"rate_8f2c1a9b4d7e4f109a3b2c5e7f1d0a44"
Where the chosen option came from β its source in rates[]: the store's carrier account (shippo) or its custom shipping extension (custom).
shippo, custom "shippo"
The parcel the option was quoted for. Required with shipping_rate_source: custom, because the extension is asked for its options again to check the one chosen.
Show child attributes
Show child attributes
How the shopper receives the order: delivered to shipping_address, or collected at one of the store's locations.
delivery, pickup "delivery"
The location to collect from, on a pickup order β a location id from pickup_locations (GET /v1/shipping/zones) or from a pickup option's location (POST /v1/shipping/calculate). When omitted on a pickup order, the store's primary pickup location is used.
"3d5c7a10-8b2e-4f61-9c4d-1a2b3c4d5e6f"
The id of the option the shopper chose from options[] in POST /v1/shipping/calculate β place for standard delivery, opt:<id> for a named delivery option such as Express, or pickup:<location id> on a pickup order. shipping_amount must equal that option's fee for this order.
60"opt:9a1f3c2e-5b7d-4e8a-a2c4-6d8e0f1a3b5c"
The ship-from address the option was quoted with, when one was sent to POST /v1/shipping/calculate as address_from.
Where this order came from, recorded for the merchant's analytics. Accepts the fields below; the same fields are also read from the top level of the request body if you already send them there. Promotions that actually applied are recorded from the server-validated result, so promotion_ids never inflates what a shopper received.
Show child attributes
Show child attributes
Google ad click id, when the shopper arrived from a Google ad. On a paid order this lets the merchant's Google advertising get credit for the sale, and is kept on the order so the merchant's own reports can attribute revenue and profit to the ad that earned it rather than relying on the ad platform's account. Forward the true captured value; omit if not present.
"Cj0KCQiA...gclid"
Meta (Facebook & Instagram) ad click id, when the shopper arrived from a Meta ad. On a paid order this lets the merchant's Meta advertising get credit for the sale. The conversion is sent server-side (Conversions API) and de-duplicated against the storefront's Meta Pixel by the order id, so it counts even when the browser blocks the Pixel. It is kept on the order so the merchant's own reports can attribute revenue and profit to the ad that earned it. Forward the true captured value; omit if not present.
"IwAR1abc...fbclid"
Advertising privacy-consent state captured at checkout, used to decide whether a conversion may be reported to an ad platform for this shopper's region (required for EEA shoppers; UK/Swiss records are not dropped for a missing signal). Always forward the true captured values β never guess.
Show child attributes
Show child attributes
Response
The Idempotency-Key has already been used for this store, so the order it created is
returned instead of a new one being made. The body is the order resource, exactly as
GET /v1/orders/{id} would return it β note this differs from the 201 envelope, which
nests the order under an order property.
Retrying a create with the same key is always safe: concurrent retries resolve to the
same order, and only the first request receives 201.
"ORD-2026-001234"
pending, confirmed, processing, shipped, delivered, cancelled "pending"
pending, paid, failed, refunded "pending"
Method used for payment
stripe, paypal, paystack, mpesa, cash, bank_transfer "stripe"
1999.98
159.99
Per-jurisdiction tax detail when tax was calculated automatically for the shipping destination (one entry per taxing jurisdiction). Null when a flat store rate was used.
Show child attributes
Show child attributes
How the tax figure was produced β automatic (jurisdiction-accurate calculation for the destination), fallback (automatic calculation was unavailable, so the store's configured rate was used), or manual (the store's configured rate).
automatic, fallback, manual, null "automatic"
15
0
2174.97
Show child attributes
Show child attributes
Where the order goes. On a pickup order it is the collection location's address, with type: pickup, the location's name and location_id, and the address in line1 / line2 / city / state / postal_code / country.
Show child attributes
Show child attributes
Whether the order is delivered to the shopper or collected at one of the store's locations.
delivery, pickup "delivery"
The location the shopper collects from, on a pickup order. Null on a delivery order.
null
The store location the order is fulfilled from: the pickup location on a pickup order, or the location deliveries leave from when the store delivers from its nearest location. Null when the store does not route orders between locations.
"7b2e9c41-0d3f-4a58-b6e1-2f4a6c8e0b13"
The shipping option the order was placed with, as returned by POST /v1/shipping/calculate (place, opt:<id> or pickup:<location id>). Null when none was named.
"place"
Show child attributes
Show child attributes
Customer-visible updates the merchant added as the order moved β the work between payment and dispatch (preparation, checks, packing) that a shopper otherwise hears nothing about. Oldest first, so it reads as a timeline. Internal notes are never included.
Show child attributes
Show child attributes
The merchant's own fields on this order, with their values β a buyer's purchase-order number, a cost centre, whatever the merchant defined. Only fields the merchant published appear here; one holding an internal note or a cost stays in the admin. Empty when the merchant has defined none.
The merchant controls the names and how many exist, so render the array rather than reading fixed
keys: field_label is the heading to show, and field_type gives the shape of value.
Show child attributes
Show child attributes
Whether this order was created in the live or test environment. Sandbox orders are isolated from production data.
production, sandbox "production"
How the shipping charge was arrived at. shipping_source and shipping_rule are recorded by the server when the order is created; the other fields are the details the storefront sent with the order.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.tybritelabs.com/v1/orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'X-Signature: <x-signature>' \
--header 'X-Timestamp: <x-timestamp>' \
--data '
{
"customer_email": "john.doe@example.com",
"customer_name": "John Doe",
"customer_phone": "+12125550142",
"billing_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"shipping_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"items": [
{
"product_id": "715b8c10-eb11-4289-8c0e-2966e78cf9a5",
"variant_id": "15ca5a86-4b1b-47c3-8762-a1aa43941565",
"product_name": "Apple MacBook Pro",
"product_sku": "APP-MBP-13",
"quantity": 1,
"unit_price": 1999,
"total_price": 1999
}
],
"payment_method": "card",
"payment_status": "paid",
"subtotal": 1999,
"shipping_amount": 5.99,
"discount_amount": 0,
"total_amount": 2004.99,
"fulfillment_method": "delivery",
"shipping_option_id": "place",
"shipping_metadata": {
"fee": 5.99,
"tier_name": "Local (within 10 km)",
"distance_meters": 8548,
"is_free": false,
"reason": "8.5 km away",
"applied_rule": "distance"
},
"notes": "Leave with front desk"
}
'import requests
url = "https://api.tybritelabs.com/v1/orders"
payload = {
"customer_email": "john.doe@example.com",
"customer_name": "John Doe",
"customer_phone": "+12125550142",
"billing_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"shipping_address": {
"street": "350 Fifth Avenue",
"city": "New York",
"state": "NY",
"zip": "10118",
"country": "US"
},
"items": [
{
"product_id": "715b8c10-eb11-4289-8c0e-2966e78cf9a5",
"variant_id": "15ca5a86-4b1b-47c3-8762-a1aa43941565",
"product_name": "Apple MacBook Pro",
"product_sku": "APP-MBP-13",
"quantity": 1,
"unit_price": 1999,
"total_price": 1999
}
],
"payment_method": "card",
"payment_status": "paid",
"subtotal": 1999,
"shipping_amount": 5.99,
"discount_amount": 0,
"total_amount": 2004.99,
"fulfillment_method": "delivery",
"shipping_option_id": "place",
"shipping_metadata": {
"fee": 5.99,
"tier_name": "Local (within 10 km)",
"distance_meters": 8548,
"is_free": False,
"reason": "8.5 km away",
"applied_rule": "distance"
},
"notes": "Leave with front desk"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"X-Timestamp": "<x-timestamp>",
"X-Signature": "<x-signature>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'X-Timestamp': '<x-timestamp>',
'X-Signature': '<x-signature>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customer_email: 'john.doe@example.com',
customer_name: 'John Doe',
customer_phone: '+12125550142',
billing_address: {
street: '350 Fifth Avenue',
city: 'New York',
state: 'NY',
zip: '10118',
country: 'US'
},
shipping_address: {
street: '350 Fifth Avenue',
city: 'New York',
state: 'NY',
zip: '10118',
country: 'US'
},
items: [
{
product_id: '715b8c10-eb11-4289-8c0e-2966e78cf9a5',
variant_id: '15ca5a86-4b1b-47c3-8762-a1aa43941565',
product_name: 'Apple MacBook Pro',
product_sku: 'APP-MBP-13',
quantity: 1,
unit_price: 1999,
total_price: 1999
}
],
payment_method: 'card',
payment_status: 'paid',
subtotal: 1999,
shipping_amount: 5.99,
discount_amount: 0,
total_amount: 2004.99,
fulfillment_method: 'delivery',
shipping_option_id: 'place',
shipping_metadata: {
fee: 5.99,
tier_name: 'Local (within 10 km)',
distance_meters: 8548,
is_free: false,
reason: '8.5 km away',
applied_rule: 'distance'
},
notes: 'Leave with front desk'
})
};
fetch('https://api.tybritelabs.com/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://api.tybritelabs.com/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([
'customer_email' => 'john.doe@example.com',
'customer_name' => 'John Doe',
'customer_phone' => '+12125550142',
'billing_address' => [
'street' => '350 Fifth Avenue',
'city' => 'New York',
'state' => 'NY',
'zip' => '10118',
'country' => 'US'
],
'shipping_address' => [
'street' => '350 Fifth Avenue',
'city' => 'New York',
'state' => 'NY',
'zip' => '10118',
'country' => 'US'
],
'items' => [
[
'product_id' => '715b8c10-eb11-4289-8c0e-2966e78cf9a5',
'variant_id' => '15ca5a86-4b1b-47c3-8762-a1aa43941565',
'product_name' => 'Apple MacBook Pro',
'product_sku' => 'APP-MBP-13',
'quantity' => 1,
'unit_price' => 1999,
'total_price' => 1999
]
],
'payment_method' => 'card',
'payment_status' => 'paid',
'subtotal' => 1999,
'shipping_amount' => 5.99,
'discount_amount' => 0,
'total_amount' => 2004.99,
'fulfillment_method' => 'delivery',
'shipping_option_id' => 'place',
'shipping_metadata' => [
'fee' => 5.99,
'tier_name' => 'Local (within 10 km)',
'distance_meters' => 8548,
'is_free' => false,
'reason' => '8.5 km away',
'applied_rule' => 'distance'
],
'notes' => 'Leave with front desk'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"X-Signature: <x-signature>",
"X-Timestamp: <x-timestamp>"
],
]);
$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.tybritelabs.com/v1/orders"
payload := strings.NewReader("{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("X-Timestamp", "<x-timestamp>")
req.Header.Add("X-Signature", "<x-signature>")
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.tybritelabs.com/v1/orders")
.header("Idempotency-Key", "<idempotency-key>")
.header("X-Timestamp", "<x-timestamp>")
.header("X-Signature", "<x-signature>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["X-Timestamp"] = '<x-timestamp>'
request["X-Signature"] = '<x-signature>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customer_email\": \"john.doe@example.com\",\n \"customer_name\": \"John Doe\",\n \"customer_phone\": \"+12125550142\",\n \"billing_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"shipping_address\": {\n \"street\": \"350 Fifth Avenue\",\n \"city\": \"New York\",\n \"state\": \"NY\",\n \"zip\": \"10118\",\n \"country\": \"US\"\n },\n \"items\": [\n {\n \"product_id\": \"715b8c10-eb11-4289-8c0e-2966e78cf9a5\",\n \"variant_id\": \"15ca5a86-4b1b-47c3-8762-a1aa43941565\",\n \"product_name\": \"Apple MacBook Pro\",\n \"product_sku\": \"APP-MBP-13\",\n \"quantity\": 1,\n \"unit_price\": 1999,\n \"total_price\": 1999\n }\n ],\n \"payment_method\": \"card\",\n \"payment_status\": \"paid\",\n \"subtotal\": 1999,\n \"shipping_amount\": 5.99,\n \"discount_amount\": 0,\n \"total_amount\": 2004.99,\n \"fulfillment_method\": \"delivery\",\n \"shipping_option_id\": \"place\",\n \"shipping_metadata\": {\n \"fee\": 5.99,\n \"tier_name\": \"Local (within 10 km)\",\n \"distance_meters\": 8548,\n \"is_free\": false,\n \"reason\": \"8.5 km away\",\n \"applied_rule\": \"distance\"\n },\n \"notes\": \"Leave with front desk\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7f3c1e88-2b4a-4c9e-9d21-5a6b7c8d9e01",
"order_number": "ORD-20260804-4f2a91",
"order_status": "processing",
"payment_status": "paid",
"total_amount": 324.5
}
